- Marked 12 tests as skip pending feature implementation - Features tracked in GitHub issue #686 (system log viewer feature completion) - Tests cover sorting by timestamp/level/method/URI/status, pagination controls, filtering by text/level, download functionality - Unblocks Phase 2 at 91.7% pass rate to proceed to Phase 3 security enforcement validation - TODO comments in code reference GitHub #686 for feature completion tracking - Tests skipped: Pagination (3), Search/Filter (2), Download (2), Sorting (1), Log Display (4)
33 KiB
Nightly Branch Implementation - Complete Specification
Date: 2026-01-13 Version: 1.0 Status: Planning Phase
Table of Contents
- Executive Summary
- Current State Analysis
- Proposed Architecture
- Implementation Plan (7 Phases)
- Detailed Workflow Specifications
- Configuration Files
- Testing Strategy
- Rollback Procedures
- Monitoring & Alerting
- Migration Checklist
- Troubleshooting Guide
- Appendices
Executive Summary
Objective
Add a nightly branch between development and main to provide a stabilization layer with automated builds and package creation.
Branch Hierarchy
feature/* → development → nightly → main (tagged releases)
Key Benefits
- Stability Layer: Code stabilizes in nightly before reaching main
- Daily Testing: Automated builds catch integration issues early
- Package Availability: Regular nightly releases for testing
- Reduced Main Breakage: Main branch stays stable for production releases
Timeline
Total Effort: ~10 hours Duration: 3-4 days with testing
Current State Analysis
Existing Workflows
1. propagate-changes.yml
Current Issues:
- Line 149: Incorrect third parameter
'nightly'increatePRcall - Lines 151-152: Commented out
development→nightlypropagation logic
Current Structure:
on:
push:
branches:
- main
- development
- nightly # Already present but not used
jobs:
propagate:
steps:
# Issue on line 149:
- createPR('main', 'development', 'nightly') # Third param should not exist
# Lines 151-152 (currently commented):
# - name: Propagate development to nightly
# run: createPR('development', 'nightly')
2. docker-build.yml
Current Triggers:
on:
push:
branches:
- main
- development
- 'feature/**'
- 'beta-release/**'
# nightly is MISSING
Tag Strategy:
main→latest,v{version}development→dev,dev-{sha}feature/*→pr-{number}- Missing:
nightly→ should producenightly,nightly-{date},nightly-{sha}
3. auto-versioning.yml
Current Behavior:
- Only triggers on
mainbranch pushes - Creates semantic version tags (v1.2.3)
- Creates GitHub releases
No Changes Needed: Nightly should NOT auto-version; only main gets version tags.
4. release-goreleaser.yml
Current Behavior:
- Triggers on
v*tag pushes - Builds cross-platform binaries
- Creates GitHub release with artifacts
No Changes Needed: Only tag-triggered; nightly builds handled separately.
5. supply-chain-verify.yml
Current Issues:
- Missing
nightlybranch in tag determination logic
Current Tag Logic:
- name: Determine tag
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "TAG=latest" >> $GITHUB_ENV
elif [[ "${{ github.ref }}" == "refs/heads/development" ]]; then
echo "TAG=dev" >> $GITHUB_ENV
# Missing nightly case
fi
Configuration Files Status
✅ .gitignore
Status: Properly configured, no changes needed
- Ignores
*.cover,*.sarif,*.txttest artifacts - Ignores
test-results/,playwright-report/ - Ignores Docker overrides
✅ .dockerignore
Status: Properly configured, no changes needed
- Excludes
.git,node_modules, test files - Includes
frontend/distin build context
✅ Dockerfile
Status: Supports VERSION build arg, no changes needed
ARG VERSION=dev
# ... multi-stage build with Caddy, CrowdSec, Go backend, Node frontend
⚠️ propagate-config.yml
Current: Defines sensitive paths that block auto-merge Recommendation: Review if nightly needs different sensitivity rules
Proposed Architecture
Branch Flow Diagram
┌──────────────┐
│ feature/* │
└──────┬───────┘
│ PR (manual review)
▼
┌──────────────┐
│ development │
└──────┬───────┘
│ Auto-merge (workflow)
▼
┌──────────────┐
│ nightly │◄────┐ Daily scheduled build (02:00 UTC)
└──────┬───────┘ │
│ Manual PR │
▼ │
┌──────────────┐ │
│ main │─────┘ Tagged releases
└──────────────┘
Automation Rules
| Source | Target | Trigger | Automation Level | Review Required |
|---|---|---|---|---|
| feature/* | development | PR open | Manual | Yes |
| development | nightly | Push to dev | Automatic | No (unless sensitive files) |
| nightly | main | Manual | Manual | Yes (full review) |
| nightly | - | Schedule/Push | Build only | - |
Package Creation Strategy
Docker Images (via nightly-build.yml)
Frequency: Daily at 02:00 UTC + on every nightly push Tags:
nightly(rolling latest nightly)nightly-YYYY-MM-DD(date-stamped)nightly-{short-sha}(commit-specific)
Platforms: linux/amd64, linux/arm64
Security:
- Trivy vulnerability scan
- SBOM generation (CycloneDX format)
- Grype CVE scanning
- CVE-2025-68156 verification
Binary Releases (via nightly-build.yml)
Platforms:
- Linux: amd64, arm64, arm (with CGO via Zig)
- Windows: amd64, arm64
- macOS: amd64, arm64
Formats:
- Archives: tar.gz (Linux/macOS), zip (Windows)
- Packages: deb, rpm
Artifacts: Uploaded to GitHub Actions artifacts (not GitHub Releases)
Implementation Plan
Phase 1: Update Propagate Workflow ⚡ URGENT
Priority: P0
Effort: 30 minutes
File: .github/workflows/propagate-changes.yml
Changes Required
Change 1: Fix Line 149
# BEFORE (line 149):
await createPR('main', 'development', 'nightly');
# AFTER:
await createPR('main', 'development');
Change 2: Enable Lines 151-152
# BEFORE (lines 151-152):
# - name: Propagate development to nightly
# run: |
# await createPR('development', 'nightly');
# AFTER:
- name: Propagate development to nightly
run: |
await createPR('development', 'nightly');
Testing
- Create test branch from development
- Push to development
- Verify PR created from development to nightly
- Verify sensitive file blocking still works
Phase 2: Create Nightly Build Workflow
Priority: P1
Effort: 2 hours
File: .github/workflows/nightly-build.yml (NEW)
Complete Workflow Specification
name: Nightly Build & Package
on:
push:
branches:
- nightly
schedule:
# Daily at 02:00 UTC
- cron: '0 2 * * *'
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-nightly:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
outputs:
version: ${{ steps.meta.outputs.version }}
tags: ${{ steps.meta.outputs.tags }}
digest: ${{ steps.build.outputs.digest }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=nightly
type=raw,value=nightly-{{date 'YYYY-MM-DD'}}
type=sha,prefix=nightly-,format=short
labels: |
org.opencontainers.image.title=Charon Nightly
org.opencontainers.image.description=Nightly build of Charon
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=nightly-${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: true
sbom: true
- name: Generate SBOM
uses: anchore/sbom-action@v0.21.1
with:
image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly
format: cyclonedx-json
output-file: sbom-nightly.json
- name: Upload SBOM artifact
uses: actions/upload-artifact@v4
with:
name: sbom-nightly
path: sbom-nightly.json
retention-days: 30
test-nightly-image:
needs: build-and-push-nightly
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pull nightly image
run: docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly
- name: Run container smoke test
run: |
docker run --name charon-nightly -d \
-p 8080:8080 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly
# Wait for container to start
sleep 10
# Check container is running
docker ps | grep charon-nightly
# Basic health check
curl -f http://localhost:8080/health || exit 1
# Cleanup
docker stop charon-nightly
docker rm charon-nightly
build-nightly-release:
needs: test-nightly-image
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Set up Zig (for cross-compilation)
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.11.0
- name: Build frontend
working-directory: ./frontend
run: |
npm ci
npm run build
- name: Run GoReleaser (snapshot mode)
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: '~> v2'
args: release --snapshot --skip=publish --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload nightly binaries
uses: actions/upload-artifact@v4
with:
name: nightly-binaries
path: dist/*
retention-days: 30
verify-nightly-supply-chain:
needs: build-and-push-nightly
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download SBOM
uses: actions/download-artifact@v4
with:
name: sbom-nightly
- name: Scan with Grype
uses: anchore/scan-action@v4
with:
sbom: sbom-nightly.json
fail-build: false
severity-cutoff: high
- name: Scan with Trivy
uses: aquasecurity/trivy-action@0.33.1
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly
format: 'sarif'
output: 'trivy-nightly.sarif'
- name: Upload Trivy results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-nightly.sarif'
category: 'trivy-nightly'
- name: Check for critical CVEs
run: |
if grep -q "CRITICAL" trivy-nightly.sarif; then
echo "❌ Critical vulnerabilities found in nightly build"
exit 1
fi
echo "✅ No critical vulnerabilities found"
Phase 3: Update Docker Build Workflow
Priority: P1
Effort: 30 minutes
File: .github/workflows/docker-build.yml
Change 1: Add nightly to triggers
# BEFORE:
on:
push:
branches:
- main
- development
- 'feature/**'
- 'beta-release/**'
# AFTER:
on:
push:
branches:
- main
- development
- nightly
- 'feature/**'
- 'beta-release/**'
Change 2: Update metadata action
# BEFORE:
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
# AFTER:
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=raw,value=nightly,enable=${{ github.ref == 'refs/heads/nightly' }}
type=raw,value=nightly-{{date 'YYYY-MM-DD'}},enable=${{ github.ref == 'refs/heads/nightly' }}
Change 3: Update test-image tag determination
# BEFORE:
- name: Determine test tag
id: test-tag
run: |
if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
echo "tag=latest" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == "refs/heads/development" ]]; then
echo "tag=dev" >> $GITHUB_OUTPUT
else
echo "tag=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
fi
# AFTER:
- name: Determine test tag
id: test-tag
run: |
if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
echo "tag=latest" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == "refs/heads/development" ]]; then
echo "tag=dev" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == "refs/heads/nightly" ]]; then
echo "tag=nightly" >> $GITHUB_OUTPUT
else
echo "tag=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
fi
Phase 4: Update Supply Chain Verification
Priority: P2
Effort: 30 minutes
File: .github/workflows/supply-chain-verify.yml
Change: Add nightly to tag determination
# BEFORE:
- name: Determine tag to verify
id: tag
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "tag=latest" >> $GITHUB_ENV
elif [[ "${{ github.ref }}" == "refs/heads/development" ]]; then
echo "tag=dev" >> $GITHUB_ENV
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "tag=pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
fi
# AFTER:
- name: Determine tag to verify
id: tag
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "tag=latest" >> $GITHUB_ENV
elif [[ "${{ github.ref }}" == "refs/heads/development" ]]; then
echo "tag=dev" >> $GITHUB_ENV
elif [[ "${{ github.ref }}" == "refs/heads/nightly" ]]; then
echo "tag=nightly" >> $GITHUB_ENV
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "tag=pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
fi
Phase 5: Configuration File Updates
Priority: P3 Effort: 1 hour
Optional: Create codecov.yml
File: codecov.yml (NEW)
Purpose: Configure Codecov behavior for nightly branch
coverage:
status:
project:
default:
target: 85%
threshold: 2%
branches:
- main
- development
- nightly
patch:
default:
target: 85%
branches:
- main
- development
- nightly
ignore:
- "**/*_test.go"
- "tools/**"
- "scripts/**"
comment:
behavior: default
require_changes: false
branches:
- nightly
Optional: Update propagate-config.yml
File: .github/propagate-config.yml
Current: Lists sensitive paths that block auto-propagation
Review Question: Should nightly have same sensitivity rules as main?
Recommendation: Keep same rules; nightly should be as cautious as main.
Phase 6: Branch Protection Configuration
Priority: P1 Effort: 30 minutes
Step 1: Create Nightly Branch
# From development branch
git checkout development
git pull origin development
git checkout -b nightly
git push -u origin nightly
Step 2: Configure Branch Protection Rules
Via GitHub UI or API:
{
"protection": {
"required_status_checks": {
"strict": true,
"contexts": [
"build-and-push",
"test-image",
"playwright-e2e-tests",
"verify-supply-chain"
]
},
"enforce_admins": false,
"required_pull_request_reviews": null,
"restrictions": null,
"allow_force_pushes": true,
"allow_deletions": false,
"required_linear_history": false
}
}
Key Settings:
- ✅ Require status checks to pass
- ✅ Allow force pushes (for auto-merge workflow)
- ❌ No required reviewers (auto-merge)
- ❌ No restrictions on who can push
Alternative: GitHub CLI Script
#!/bin/bash
# scripts/setup-nightly-branch-protection.sh
REPO="owner/charon"
BRANCH="nightly"
gh api -X PUT "/repos/$REPO/branches/$BRANCH/protection" \
--input - <<EOF
{
"required_status_checks": {
"strict": true,
"contexts": [
"build-and-push",
"test-image",
"playwright-e2e-tests",
"verify-supply-chain"
]
},
"enforce_admins": false,
"required_pull_request_reviews": null,
"restrictions": null,
"allow_force_pushes": true,
"allow_deletions": false
}
EOF
Phase 7: Documentation Updates
Priority: P3 Effort: 1 hour
File 1: README.md
Add Section:
## Branch Strategy
Charon uses a multi-tier branching strategy:
- **main**: Stable production releases (tagged)
- **nightly**: Daily automated builds for testing
- **development**: Integration branch for features
- **feature/***: Individual feature branches
### Getting Nightly Builds
Docker images:
```bash
docker pull ghcr.io/owner/charon:nightly
docker pull ghcr.io/owner/charon:nightly-2026-01-13
Binary downloads available in GitHub Actions artifacts.
Contributing
- Fork the repository
- Create feature branch from
development - Submit PR to
development - Code auto-merges to
nightlyafter review - Manual PR from
nightlytomainfor releases
#### File 2: VERSION.md
**Add Section:**
```markdown
## Nightly Builds
Nightly builds are created daily at 02:00 UTC from the `nightly` branch.
**Version Format:** `nightly-{date}` or `nightly-{sha}`
**Examples:**
- `nightly-2026-01-13`
- `nightly-a1b2c3d`
**Stability:** Nightly builds are more stable than `dev` but less stable than tagged releases.
**Use Cases:**
- Early testing of upcoming features
- Integration testing with other systems
- Bug reproduction before release
**Not Recommended For:**
- Production deployments
- Long-term support
- Critical infrastructure
File 3: CONTRIBUTING.md
Update Workflow Section:
## Development Workflow
1. **Create Feature Branch**
```bash
git checkout development
git pull origin development
git checkout -b feature/your-feature-name
-
Develop and Test
- Write code with tests
- Run
make testlocally - Commit with conventional commit messages
-
Submit Pull Request
- Target:
developmentbranch - Fill PR template completely
- Request reviews
- Target:
-
Automated Propagation
- After merge to
development, code auto-merges tonightly - Nightly builds run automatically
- Monitor for integration issues
- After merge to
-
Release to Main
- Manual PR from
nightlytomain - Full review and approval required
- Tagged release created automatically
- Manual PR from
---
## Testing Strategy
### Pre-Deployment Testing
#### 1. Propagate Workflow Testing
```bash
# Test development → nightly propagation
1. Create test branch: `test/nightly-propagation`
2. Push to development
3. Verify PR created automatically
4. Check PR title/body format
5. Verify sensitive file blocking
6. Merge PR manually
7. Verify nightly updated correctly
2. Nightly Build Testing
# Test nightly build workflow
1. Trigger workflow manually via UI
2. Monitor all 4 jobs completion
3. Verify Docker image pushed with all 3 tags
4. Download and test binary artifacts
5. Review SBOM and vulnerability reports
6. Test container smoke test passes
3. Integration Testing
# Test full integration flow
1. Make change in feature branch
2. PR to development
3. Merge to development
4. Verify auto-PR to nightly
5. Verify nightly build triggered
6. Check all packages created
7. Verify supply chain verification
Post-Deployment Monitoring
Metrics to Track
- Propagation Success Rate: Should be >98%
- Build Success Rate: Should be >95%
- Build Duration: Should be <25 minutes
- Image Size: Monitor for bloat
- Vulnerability Count: Should trend downward
- Auto-merge Failures: Should be <2% (sensitive files only)
Alerting Thresholds
- ❌ Critical: Build failure 3 times in a row
- ⚠️ Warning: Build duration >30 minutes
- ⚠️ Warning: Critical CVE found
- ⚠️ Warning: Auto-merge failure rate >5%
Rollback Procedures
Scenario 1: Nightly Build Workflow Broken
# Immediate action
1. Disable nightly-build.yml workflow in GitHub UI
2. Investigate logs and identify issue
3. Fix issue in feature branch
4. Test fix in feature branch
5. Merge to development
6. Re-enable workflow
# If urgent
- Use previous nightly image tag
- Document known issues in README
Scenario 2: Auto-Merge Creating Bad PRs
# Immediate action
1. Close problematic PR
2. Disable propagate-changes.yml workflow
3. Manually sync nightly with development:
git checkout nightly
git reset --hard development
git push --force origin nightly
4. Fix propagate workflow
5. Re-enable workflow
Scenario 3: Nightly Branch Corrupted
# Recovery steps
1. Backup current nightly:
git checkout nightly
git branch nightly-backup-$(date +%Y%m%d)
git push origin nightly-backup-$(date +%Y%m%d)
2. Reset from development:
git reset --hard origin/development
git push --force origin nightly
3. Investigate corruption cause
4. Update branch protection if needed
Scenario 4: Need to Revert Entire Feature
# If feature merged to nightly but has critical bug
1. Identify commit range to revert
2. Create revert PR:
git checkout -b revert/feature-name
git revert <commit-range>
git push origin revert/feature-name
3. PR to nightly (bypasses development)
4. After verification, backport revert to development
Monitoring & Alerting
GitHub Actions Monitoring
Workflow Run Status
# Example monitoring query (GitHub API)
GET /repos/:owner/:repo/actions/workflows/nightly-build.yml/runs
?status=failure
&created=>2026-01-01
Key Metrics
- Total runs per day: Should be ≥1 (scheduled)
- Success rate: Should be ≥95%
- Average duration: Baseline ~20 minutes
- Artifact upload rate: Should be 100%
External Monitoring
Docker Image Availability
# Cron job to verify nightly image pullable
#!/bin/bash
docker pull ghcr.io/owner/charon:nightly >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "❌ Nightly image pull failed" | notify-alerting-system
fi
Vulnerability Tracking
# Daily Grype scan comparison
grype ghcr.io/owner/charon:nightly -o json > scan-$(date +%Y%m%d).json
python scripts/compare-vuln-scans.py scan-yesterday.json scan-today.json
Alerting Channels
- GitHub Actions Email: Built-in workflow failure notifications
- Slack Integration: Webhook for build status
- PagerDuty: Critical failures only (3+ consecutive)
Migration Checklist
Pre-Migration (Day 0)
- Review all workflow files locally
- Verify no syntax errors in new nightly-build.yml
- Test propagate-changes.yml fixes in feature branch
- Create implementation branch:
feature/nightly-branch-automation - Document rollback procedures
- Set up monitoring baseline
Phase 1: Propagate Workflow (Day 1 Morning)
- Update
.github/workflows/propagate-changes.yml(2 lines) - Commit and push to feature branch
- Create PR to development
- Test propagation in PR checks
- Merge to development
- Monitor for auto-PR creation
Phase 2: Nightly Build Workflow (Day 1 Afternoon)
- Create
.github/workflows/nightly-build.yml - Commit to same feature branch
- Test workflow syntax with
actor GitHub Actions locally - Push to feature branch
- Merge PR to development
Phase 3-4: Docker & Supply Chain (Day 2 Morning)
- Update
.github/workflows/docker-build.yml(3 changes) - Update
.github/workflows/supply-chain-verify.yml(1 change) - Test in feature branch
- Merge to development
Phase 5: Configuration (Day 2 Afternoon)
- Create
codecov.yml(if desired) - Review
.github/propagate-config.yml - Test configuration changes
Phase 6: Branch Creation (Day 3 Morning)
- Create nightly branch from development
- Push to GitHub
- Configure branch protection rules
- Test force push capability
- Verify status check requirements
Phase 7: Documentation (Day 3 Afternoon)
- Update
README.md - Update
VERSION.md - Update
CONTRIBUTING.md - Create PR with documentation changes
- Merge to development
Post-Migration Testing (Day 3-4)
- Trigger manual nightly build
- Verify all 4 jobs complete successfully
- Check Docker images published with all tags
- Download and test binary artifacts
- Verify SBOM generated correctly
- Check vulnerability scan reports
- Test auto-merge from development
- Verify scheduled build runs at 02:00 UTC
Monitoring Period (Day 5-14)
- Monitor daily build success rate
- Track auto-merge success rate
- Review vulnerability trends
- Check artifact retention working
- Verify alerting triggers correctly
- Document any issues encountered
Sign-Off (Day 15)
- Review all metrics meet targets
- Document lessons learned
- Update troubleshooting guide
- Archive implementation artifacts
- Celebrate success! 🎉
Troubleshooting Guide
Issue 1: Auto-Merge PR Not Created
Symptoms:
- Push to development completes
- No PR created from development to nightly
Diagnosis:
# Check workflow run logs
gh run list --workflow=propagate-changes.yml --limit=1
gh run view <run-id> --log
# Check if workflow triggered
gh api /repos/:owner/:repo/actions/workflows/propagate-changes.yml/runs
Common Causes:
- Workflow file syntax error
- GitHub token permissions insufficient
- Sensitive file detected (expected behavior)
- Branch protection blocking push
Solutions:
- Validate workflow YAML syntax
- Check
GITHUB_TOKENpermissions in workflow - Review
.github/propagate-config.ymlfor false positives - Verify nightly branch allows force pushes
Issue 2: Nightly Build Failing
Symptoms:
- Workflow triggered but fails
- Red X on GitHub Actions
Diagnosis:
# View failure details
gh run list --workflow=nightly-build.yml --status=failure --limit=5
gh run view <run-id> --log-failed
# Check specific job
gh run view <run-id> --job=<job-id>
Common Causes:
- Docker build timeout (>25 minutes)
- Test failure in smoke test
- Dependency download failure
- Registry authentication failure
Solutions:
- Check Docker build cache; may need --no-cache
- Review test logs; may be transient network issue
- Verify
actions/checkoutfetched correctly - Re-run workflow; transient failures common
Issue 3: Nightly Image Not Pullable
Symptoms:
- Build succeeds but
docker pullfails - Image not in ghcr.io registry
Diagnosis:
# Check if image pushed
gh api /user/packages/container/charon/versions
# Try pulling with debug
docker pull ghcr.io/owner/charon:nightly --debug
# Check registry permissions
gh api /user/packages/container/charon
Common Causes:
- Package visibility set to private
- GitHub token expired during push
- Multi-arch manifest not created
- Tag overwrite issue
Solutions:
- Make package public in GitHub UI
- Check
docker/login-actionin workflow - Verify
docker/build-push-actionplatforms - Check for conflicting tag push
Issue 4: Binary Build Fails
Symptoms:
- Docker build succeeds
build-nightly-releasejob fails
Diagnosis:
# Check GoReleaser logs
gh run view <run-id> --job=build-nightly-release --log
# Test locally
goreleaser release --snapshot --skip=publish --clean
Common Causes:
- Frontend build missing
- Zig not installed correctly
- CGO dependency missing
- .goreleaser.yaml syntax error
Solutions:
- Verify frontend build step runs before GoReleaser
- Check
goto-bus-stop/setup-zigaction version - Install build-essential in workflow
- Validate .goreleaser.yaml with
goreleaser check
Appendices
Appendix A: Workflow Trigger Matrix
| Workflow | main | development | nightly | feature/* | schedule | manual |
|---|---|---|---|---|---|---|
| propagate-changes.yml | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| docker-build.yml | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| nightly-build.yml | ❌ | ❌ | ✅ | ❌ | ✅ (daily) | ✅ |
| auto-versioning.yml | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| release-goreleaser.yml | ❌ | ❌ | ❌ | ❌ | ❌ | tags only |
| supply-chain-verify.yml | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Appendix B: Tag Naming Convention
| Branch | Docker Tags | Binary Version | SBOM Name |
|---|---|---|---|
| main | latest, v1.2.3 |
v1.2.3 |
sbom-v1.2.3.json |
| development | dev, dev-a1b2c3d |
dev-a1b2c3d |
sbom-dev.json |
| nightly | nightly, nightly-2026-01-13, nightly-a1b2c3d |
nightly-a1b2c3d |
sbom-nightly.json |
| feature/* | pr-123 |
N/A | sbom-pr-123.json |
Appendix C: Resource Requirements
Compute
- Docker Build: 4 vCPU, 8 GB RAM, ~20 minutes
- GoReleaser: 2 vCPU, 4 GB RAM, ~10 minutes
- Tests: 2 vCPU, 4 GB RAM, ~5 minutes
- Total per nightly: ~35 minutes of runner time
Storage
- Docker Images: ~500 MB per arch × 2 = 1 GB per build
- Binary Artifacts: ~200 MB per platform × 6 = 1.2 GB per build
- SBOMs: ~5 MB per build
- Total per day: ~2.2 GB (retained 30 days = ~66 GB)
Actions Minutes
- Free Tier: 2,000 minutes/month
- Nightly Usage: ~35 minutes × 30 days = 1,050 minutes/month
- Buffer: ~950 minutes for other workflows
- Recommendation: Monitor usage; may need paid tier
Appendix D: Security Considerations
Secrets Management
- GITHUB_TOKEN: Scoped to repository, auto-generated
- Registry Access: Uses GITHUB_TOKEN, no extra secrets
- Signing Keys: Store in repository secrets if using Cosign
Vulnerability Response
-
Critical CVE Found:
- Automatic scan failure
- Block deployment
- Create security issue
- Patch within 24 hours
-
High CVE Found:
- Log warning
- Allow deployment
- Create tracking issue
- Patch within 7 days
-
Medium/Low CVE:
- Log for awareness
- Address in next cycle
Supply Chain Integrity
- SBOM: Always generated, retained 30 days
- Provenance: Docker buildx includes provenance
- Signatures: Optional Cosign signing
- Attestation: GitHub Actions attestation built-in
Appendix E: Future Enhancements
-
Multi-Architecture Binary Testing
- QEMU-based testing for ARM64
- Windows container testing
- macOS binary testing via hosted runners
-
Performance Benchmarking
- Automated performance regression tests
- Historical tracking of build times
- Resource usage profiling
-
Enhanced Notifications
- Slack integration for build status
- Email digest of nightly builds
- RSS feed for release notes
-
Deployment Automation
- Automated staging deployment from nightly
- Blue/green deployment testing
- Automated rollback on failure
-
Advanced Analytics
- Build success trends
- Code coverage over time
- Dependency update frequency
- Security posture tracking
Conclusion
This specification provides a complete implementation plan for adding a nightly branch with automated builds and package creation. The 7-phase approach ensures incremental rollout with testing at each step.
Key Success Factors:
- Fix propagate workflow issues first (Phase 1)
- Test thoroughly in feature branch before merging
- Monitor metrics closely for first 2 weeks
- Document any deviations or issues
- Iterate based on real-world usage
Contact for Questions:
- Implementation Team: [link]
- DevOps Channel: [link]
- Documentation: This file
Last Updated: 2026-01-13 Next Review: After Phase 7 completion