Compare commits

...

5 Commits

6 changed files with 278 additions and 372 deletions

View File

@@ -6,7 +6,11 @@
sensitive_paths:
- scripts/history-rewrite/
- data/backups
- docs/plans/history_rewrite.md
- .github/workflows/
- docs/plans/
- .github/agents/
- .github/instructions/
- .github/prompts/
- .github/skills/
- .vscode/
- scripts/history-rewrite/preview_removals.sh
- scripts/history-rewrite/clean_history.sh

View File

@@ -7,8 +7,9 @@
"helpers:pinGitHubActionDigests"
],
"baseBranches": [
"development",
"feature/*"
"feature/beta-release",
"development"
],
"timezone": "America/New_York",
"dependencyDashboard": true,
@@ -18,6 +19,10 @@
"dependencies"
],
"ignorePaths": [
".docker/**"
],
"rebaseWhen": "auto",
"vulnerabilityAlerts": {

View File

@@ -136,6 +136,8 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=nightly-${{ github.sha }}
VCS_REF=${{ github.sha }}
BUILD_DATE=${{ github.event.repository.pushed_at }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: true

5
.gitignore vendored
View File

@@ -9,11 +9,6 @@
docs/reports/performance_diagnostics.md
docs/plans/chores.md
# -----------------------------------------------------------------------------
# VS Code
# -----------------------------------------------------------------------------
.vscode/**
# -----------------------------------------------------------------------------
# Python (pre-commit, tooling)
# -----------------------------------------------------------------------------

14
.vscode/mcp.json vendored Normal file
View File

@@ -0,0 +1,14 @@
{
"servers": {
"microsoft/playwright-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"@playwright/mcp@latest"
],
"gallery": "https://api.mcp.github.com",
"version": "0.0.1-seed"
}
},
"inputs": []
}

View File

@@ -1,438 +1,324 @@
# Renovate and Playwright Configuration Issues - Investigation Report
# Expose Build Version to Users - Implementation Plan
**Date:** January 30, 2026
**Investigator:** Planning Agent
**Status:** ⚠️ CRITICAL - Multiple configuration issues found
**Status:** 📋 READY FOR IMPLEMENTATION
**Goal:** Enable nightly build users to easily report their exact version for bug triage
---
## Executive Summary
Investigation reveals that **both Renovate and Playwright workflows have incorrect configurations** that deviate from the user's required behavior. The Renovate configuration is missing feature branch support and has incorrect automerge settings. The Playwright workflow is missing push event triggers.
This plan details how to expose build version information (including SHA, build date) to users via:
1. A backend `/health` endpoint (already exists, already exposes version)
2. A frontend UI footer display (already implemented in Layout.tsx)
**Finding:** The version exposure is **already fully implemented**. This document confirms the existing implementation and identifies minor enhancements.
---
## 1. Renovate Configuration Issues
## 1. Backend Analysis
### File Locations
- **Primary Config:** `.github/renovate.json` (154 lines)
- **Workflow:** `.github/workflows/renovate.yml` (31 lines)
### 1.1 Version Package
**File:** [backend/internal/version/version.go](../../backend/internal/version/version.go)
### 🔴 CRITICAL ISSUE #1: Missing Feature Branch Support
```go
package version
**Current State (BROKEN):**
```json
"baseBranches": [
"development"
]
```
- **Line:** `.github/renovate.json:9`
- **Problem:** Only targets `development` branch
- **Impact:** Feature branches (`feature/*`) receive NO Renovate updates
const Name = "Charon"
**Required State:**
```json
"baseBranches": [
"development",
"feature/*"
]
```
var (
Version = "0.3.0" // Overwritten via ldflags at build time
BuildTime = "unknown" // Overwritten via ldflags at build time
GitCommit = "unknown" // Overwritten via ldflags at build time
)
---
### 🔴 CRITICAL ISSUE #2: Automerge Enabled Globally
**Current State (BROKEN):**
```json
"automerge": true,
"automergeType": "pr",
"platformAutomerge": true,
```
- **Lines:** `.github/renovate.json:28-30`
- **Problem:** All non-major updates auto-merge immediately
- **Impact:** Updates merge before compatibility is proven
**Required State:**
- **Feature Branches:** Manual approval required (automerge: false)
- **Development Branch:** Let PRs sit until proven compatible
- **Major Updates:** Already correctly set to manual review (line 148)
---
### 🟡 ISSUE #3: Grouped Updates Configuration
**Current State (PARTIALLY CORRECT):**
```json
{
"description": "THE MEGAZORD: Group ALL non-major updates (NPM, Docker, Go, Actions) into one weekly PR",
"matchPackagePatterns": ["*"],
"matchUpdateTypes": [
"minor",
"patch",
"pin",
"digest"
],
"groupName": "weekly-non-major-updates",
"automerge": true
func Full() string {
if BuildTime != "unknown" && GitCommit != "unknown" {
return Version + " (commit: " + GitCommit + ", built: " + BuildTime + ")"
}
return Version
}
```
- **Lines:** `.github/renovate.json:116-127`
- **Status:** ✅ Grouping behavior is CORRECT
- **Problem:** ❌ Automerge should be conditional on branch
**Status:**Already has `Version`, `BuildTime`, and `GitCommit` variables that are injected at build time.
### 1.2 Health Handler
**File:** [backend/internal/api/handlers/health_handler.go](../../backend/internal/api/handlers/health_handler.go#L27-L36)
```go
func HealthHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"service": version.Name,
"version": version.Version,
"git_commit": version.GitCommit,
"build_time": version.BuildTime,
"internal_ip": getLocalIP(),
})
}
```
**Status:** ✅ Already exposes version, git_commit, and build_time in `/health` endpoint.
### 1.3 Build Time Injection (Dockerfile)
**File:** [Dockerfile](../../Dockerfile#L142-L156)
```dockerfile
ARG VERSION=dev
ARG VCS_REF=unknown
ARG BUILD_DATE=unknown
# ldflags injection:
-X github.com/Wikid82/charon/backend/internal/version.Version=${VERSION}
-X github.com/Wikid82/charon/backend/internal/version.GitCommit=${VCS_REF}
-X github.com/Wikid82/charon/backend/internal/version.BuildTime=${BUILD_DATE}
```
**Status:** ✅ Dockerfile accepts `VERSION`, `VCS_REF`, and `BUILD_DATE` build args and injects them via ldflags.
---
### 🟢 CORRECT Configuration
## 2. Build Pipeline Analysis
**These are working as intended:**
- ✅ Major updates are separate and require manual review (line 145-148)
- ✅ Weekly schedule (Monday 8am, line 23-25)
- ✅ Grouped minor/patch updates (line 116-127)
- ✅ Custom managers for Dockerfile, scripts (lines 32-113)
### 2.1 Nightly Build Workflow
**File:** [.github/workflows/nightly-build.yml](../../.github/workflows/nightly-build.yml#L137-L139)
---
## 2. Playwright Workflow Issues
### File Locations
- **Primary Workflow:** `.github/workflows/playwright.yml` (319 lines)
- **Alternative E2E:** `.github/workflows/e2e-tests.yml` (533 lines)
### 🔴 CRITICAL ISSUE #4: Missing Push Event Triggers
**Current State (BROKEN):**
```yaml
on:
workflow_run:
workflows: ["Docker Build, Publish & Test"]
types:
- completed
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to test (optional)'
required: false
type: string
```
- **Lines:** `.github/workflows/playwright.yml:4-15`
- **Problem:** Only runs after `docker-build.yml` completes, NOT on direct pushes
- **Impact:** User pushed code and Playwright tests did NOT run
**Root Cause Analysis:**
The workflow uses `workflow_run` trigger which:
1. Waits for "Docker Build, Publish & Test" to finish
2. Only triggers if that workflow was triggered by `pull_request` or `push`
3. BUT the condition on line 28-30 filters execution:
```yaml
if: >-
github.event_name == 'workflow_dispatch' ||
((github.event.workflow_run.event == 'pull_request' || github.event.workflow_run.event == 'push') &&
github.event.workflow_run.conclusion == 'success')
```
**Required State:**
```yaml
on:
push:
branches:
- main
- development
- 'feature/**'
paths:
- 'frontend/**'
- 'backend/**'
- 'tests/**'
- 'playwright.config.js'
- '.github/workflows/playwright.yml'
pull_request:
branches:
- main
- development
- 'feature/**'
workflow_run:
workflows: ["Docker Build, Publish & Test"]
types:
- completed
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to test (optional)'
required: false
type: string
build-args: |
VERSION=nightly-${{ github.sha }}
```
---
**Current State:**
-`VERSION` is passed as `nightly-${{ github.sha }}` (full 40-char SHA)
-`VCS_REF` is NOT passed (will default to "unknown")
-`BUILD_DATE` is NOT passed (will default to "unknown")
### 🟡 ISSUE #5: Alternative E2E Workflow Exists
**Discovery:**
- File: `.github/workflows/e2e-tests.yml`
- **Lines 31-50:** Has CORRECT push/PR triggers:
```yaml
on:
pull_request:
branches:
- main
- development
- 'feature/**'
paths:
- 'frontend/**'
- 'backend/**'
- 'tests/**'
- 'playwright.config.js'
- '.github/workflows/e2e-tests.yml'
push:
branches:
- main
- development
- 'feature/**'
```
**Question:** Are there TWO Playwright workflows?
- `playwright.yml` - Runs after Docker build (BROKEN triggers)
- `e2e-tests.yml` - Runs on push/PR (CORRECT triggers)
**Impact:** Confusion about which workflow should be the primary E2E test runner
---
## 3. Required Changes Summary
### Renovate Configuration Changes
**File:** `.github/renovate.json`
#### Change #1: Add Feature Branch Support
```diff
"baseBranches": [
- "development"
+ "development",
+ "feature/*"
],
```
- **Line:** 9
- **Priority:** 🔴 CRITICAL
#### Change #2: Conditional Automerge by Branch
```diff
- "automerge": true,
- "automergeType": "pr",
- "platformAutomerge": true,
```
Replace with:
**Expected Response from `/health` for nightly builds:**
```json
"packageRules": [
{
"description": "Feature branches: Require manual approval",
"matchBaseBranches": ["feature/*"],
"automerge": false
},
{
"description": "Development branch: Automerge after compatibility proven",
"matchBaseBranches": ["development"],
"automerge": true,
"automergeType": "pr",
"platformAutomerge": true,
"minimumReleaseAge": "3 days"
}
]
{
"status": "ok",
"service": "Charon",
"version": "nightly-abc123def456...", // Full SHA (not ideal)
"git_commit": "unknown", // Missing!
"build_time": "unknown" // Missing!
}
```
- **Lines:** 28-30 (delete) + add to packageRules section
- **Priority:** 🔴 CRITICAL
#### Change #3: Update Grouped Updates Rule
```diff
{
"description": "THE MEGAZORD: Group ALL non-major updates (NPM, Docker, Go, Actions) into one weekly PR",
"matchPackagePatterns": ["*"],
"matchUpdateTypes": [
"minor",
"patch",
"pin",
"digest"
],
"groupName": "weekly-non-major-updates",
- "automerge": true
}
### 2.2 Recommended Fix for Nightly Workflow
Update [.github/workflows/nightly-build.yml](../../.github/workflows/nightly-build.yml#L137-L139) to pass all build args:
```yaml
build-args: |
VERSION=nightly-${{ github.sha }}
VCS_REF=${{ github.sha }}
BUILD_DATE=${{ github.event.head_commit.timestamp || github.event.repository.pushed_at }}
```
- **Lines:** 116-127
- **Priority:** 🟡 HIGH (automerge now controlled by branch-specific rules)
---
Or more reliably with a timestamp step:
### Playwright Workflow Changes
```yaml
- name: Set build date
id: build_date
run: echo "date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
**File:** `.github/workflows/playwright.yml`
#### Option A: Add Direct Push Triggers (Recommended)
```diff
on:
+ push:
+ branches:
+ - main
+ - development
+ - 'feature/**'
+ paths:
+ - 'frontend/**'
+ - 'backend/**'
+ - 'tests/**'
+ - 'playwright.config.js'
+ - '.github/workflows/playwright.yml'
+
+ pull_request:
+ branches:
+ - main
+ - development
+ - 'feature/**'
+
workflow_run:
workflows: ["Docker Build, Publish & Test"]
types:
- completed
# Then in build-push-action:
build-args: |
VERSION=nightly-${{ github.sha }}
VCS_REF=${{ github.sha }}
BUILD_DATE=${{ steps.build_date.outputs.date }}
```
- **Lines:** 4 (insert after)
- **Priority:** 🔴 CRITICAL
#### Option B: Consolidate Workflows
**Alternative Solution:**
1. Delete `playwright.yml` (post-docker workflow)
2. Keep `e2e-tests.yml` as the primary E2E test runner
3. Update documentation to reference `e2e-tests.yml`
**Pros:**
- `e2e-tests.yml` already has correct triggers
- Includes sharding and coverage collection
- More comprehensive test execution
**Cons:**
- Requires updating CI documentation
- May have different artifact/image handling
---
## 4. Verification Steps
## 3. Frontend Analysis
### After Applying Renovate Changes
### 3.1 Health API Client
**File:** [frontend/src/api/health.ts](../../frontend/src/api/health.ts)
1. **Create test feature branch:**
```bash
git checkout -b feature/test-renovate-config
```
```typescript
export interface HealthResponse {
status: string;
service: string;
version: string;
git_commit: string;
build_time: string;
}
2. **Manually trigger Renovate:**
```bash
# Via GitHub Actions UI
# Or via API
gh workflow run renovate.yml
```
export const checkHealth = async (): Promise<HealthResponse> => {
const { data } = await client.get<HealthResponse>('/health');
return data;
};
```
3. **Verify Renovate creates PRs against feature branch**
**Status:** ✅ Already fetches version, git_commit, and build_time from backend.
4. **Verify automerge behavior:**
- Feature branch: PR should NOT automerge
- Development branch: PR should automerge after 3 days
### 3.2 Layout Component (Footer Display)
**File:** [frontend/src/components/Layout.tsx](../../frontend/src/components/Layout.tsx#L293-L302)
### After Applying Playwright Changes
```tsx
const { data: health } = useQuery({
queryKey: ['health'],
queryFn: checkHealth,
staleTime: 1000 * 60 * 60, // 1 hour
});
1. **Create test commit on feature branch:**
```bash
git checkout -b feature/test-playwright-trigger
# Make trivial change to frontend
git commit -am "test: trigger playwright"
git push origin feature/test-playwright-trigger
```
// In sidebar footer (lines 293-302):
<div className="text-xs text-gray-500 dark:text-gray-500 text-center mb-2 flex flex-col gap-0.5">
<span>Version {health?.version || 'dev'}</span>
{health?.git_commit && health.git_commit !== 'unknown' && (
<span className="text-[10px] opacity-75 font-mono">
({health.git_commit.substring(0, 7)})
</span>
)}
</div>
```
2. **Verify Playwright workflow runs immediately on push**
**Status:** ✅ Already displays version and short commit hash in sidebar footer.
3. **Check GitHub Actions UI:**
- Workflow should appear in "Actions" tab
- Status should show "running" or "completed"
- Should NOT wait for docker-build workflow
**Display behavior:**
- Shows: `Version nightly-abc123def456...` (full SHA from VERSION)
- Shows: `(abc1234)` only if `git_commit` is set (currently "unknown" for nightly)
---
## 5. Root Cause Analysis
## 4. Gap Analysis
### Why These Changes Occurred
**Hypothesis:**
Another AI model likely:
1. **Simplified baseBranches** to reduce complexity
2. **Enabled automerge globally** to reduce manual PR overhead
3. **Removed direct push triggers** to avoid duplicate test runs
**Problems with this approach:**
- Violates user's explicit requirements for manual feature branch approval
- Creates risk by auto-merging untested updates
- Breaks CI/CD by preventing push-triggered tests
| Component | Status | Issue |
|-----------|--------|-------|
| Backend version package | ✅ Complete | None |
| Backend health handler | ✅ Complete | None |
| Dockerfile ldflags | ✅ Complete | None |
| Nightly workflow | ⚠️ Incomplete | Missing `VCS_REF` and `BUILD_DATE` |
| Frontend API client | ✅ Complete | None |
| Frontend UI display | ✅ Complete | None |
---
## 6. Implementation Priority
## 5. Implementation Tasks
### Immediate (Block Development)
1. 🔴 **Renovate:** Add feature branch support (`.github/renovate.json:9`)
2. 🔴 **Playwright:** Add push triggers (`.github/workflows/playwright.yml:4`)
### Task 1: Update Nightly Build Workflow (REQUIRED)
**File:** `.github/workflows/nightly-build.yml`
**Lines:** ~137-139 (build-args section)
### High Priority (Block Production)
3. 🟡 **Renovate:** Fix automerge behavior (branch-specific rules)
**Change:**
```yaml
# FROM:
build-args: |
VERSION=nightly-${{ github.sha }}
### Medium Priority (Technical Debt)
4. 🟢 **Consolidate:** Decide on single E2E workflow (playwright.yml vs e2e-tests.yml)
# TO:
build-args: |
VERSION=nightly-${{ github.sha }}
VCS_REF=${{ github.sha }}
BUILD_DATE=${{ github.event.head_commit.timestamp }}
```
**Alternative with reliable timestamp:**
```yaml
# Add step before build-push-action:
- name: Set build metadata
id: build_meta
run: |
echo "date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
echo "short_sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
# Update build-args:
build-args: |
VERSION=nightly-${{ steps.build_meta.outputs.short_sha }}
VCS_REF=${{ github.sha }}
BUILD_DATE=${{ steps.build_meta.outputs.date }}
```
### Task 2: (OPTIONAL) Improve Version Display Format
If a shorter nightly version is preferred (e.g., `nightly-abc1234` instead of full SHA):
**Option A:** Use short SHA in workflow (recommended):
```yaml
VERSION=nightly-${GITHUB_SHA::7}
```
**Option B:** Truncate in frontend (already partially done for git_commit display)
---
## 7. Configuration Comparison Table
## 6. Expected Result After Implementation
| Setting | Current (Broken) | Required | Priority |
|---------|-----------------|----------|----------|
| **Renovate baseBranches** | `["development"]` | `["development", "feature/*"]` | 🔴 CRITICAL |
| **Renovate automerge** | Global `true` | Conditional by branch | 🔴 CRITICAL |
| **Renovate grouping** | ✅ Weekly grouped | ✅ Weekly grouped | 🟢 OK |
| **Renovate major updates** | ✅ Manual review | ✅ Manual review | 🟢 OK |
| **Playwright triggers** | `workflow_run` only | `push` + `pull_request` + `workflow_run` | 🔴 CRITICAL |
| **E2E workflow count** | 2 workflows | 1 workflow (consolidate) | 🟡 HIGH |
### `/health` Response:
```json
{
"status": "ok",
"service": "Charon",
"version": "nightly-abc1234",
"git_commit": "abc1234def5678901234567890abcdef12345678",
"build_time": "2026-01-30T09:00:00Z",
"internal_ip": "172.17.0.2"
}
```
### UI Footer Display:
```
Version nightly-abc1234
(abc1234)
```
---
## 8. Next Steps
## 7. Files to Modify
1. **Review this specification** with the user
2. **Apply critical changes** to Renovate and Playwright configs
3. **Test changes** on feature branch before merging
4. **Document decision** on e2e-tests.yml vs playwright.yml consolidation
5. **Update CI/CD documentation** to reflect correct workflow triggers
| File | Line(s) | Change |
|------|---------|--------|
| `.github/workflows/nightly-build.yml` | 137-139 | Add `VCS_REF` and `BUILD_DATE` build-args |
### No Changes Required:
- `backend/internal/version/version.go` - Already complete
- `backend/internal/api/handlers/health_handler.go` - Already complete
- `frontend/src/api/health.ts` - Already complete
- `frontend/src/components/Layout.tsx` - Already complete
- `Dockerfile` - Already complete
---
## Appendix: File References
## 8. Testing Verification
### Renovate Configuration
- **Primary Config:** `.github/renovate.json`
- Line 9: `baseBranches` (NEEDS FIX)
- Lines 28-30: Global `automerge` (NEEDS FIX)
- Lines 116-127: Grouped updates (NEEDS UPDATE)
- Lines 145-148: Major updates (CORRECT)
After implementation, verify with:
### Playwright Workflows
- **Primary:** `.github/workflows/playwright.yml`
- Lines 4-15: `on:` triggers (NEEDS FIX)
- Lines 28-30: Execution condition (REVIEW)
- **Alternative:** `.github/workflows/e2e-tests.yml`
- Lines 31-50: `on:` triggers (CORRECT - consider as model)
```bash
# 1. Build with test args
docker build --build-arg VERSION=nightly-test123 \
--build-arg VCS_REF=abc123def456 \
--build-arg BUILD_DATE=2026-01-30T09:00:00Z \
-t charon:test .
# 2. Run container
docker run -d -p 8080:8080 charon:test
# 3. Check health endpoint
curl http://localhost:8080/health | jq
# Expected output:
# {
# "status": "ok",
# "service": "Charon",
# "version": "nightly-test123",
# "git_commit": "abc123def456",
# "build_time": "2026-01-30T09:00:00Z",
# ...
# }
```
---
**End of Investigation Report**
## 9. Summary
The version exposure feature is **90% complete**. The only missing piece is passing `VCS_REF` and `BUILD_DATE` in the nightly build workflow. A single file change (`.github/workflows/nightly-build.yml`) will complete the implementation.
| Component | Lines of Code | Effort |
|-----------|--------------|--------|
| Workflow fix | ~3 lines | 5 min |
| Testing | N/A | 10 min |
| **Total** | **~3 lines** | **15 min** |
2. Docker Run (One Command)
3. Alternative: GitHub Container Registry