feat: add nightly branch workflow

This commit is contained in:
GitHub Actions
2026-01-13 22:11:28 +00:00
parent d27c925ba5
commit 4adcd9eda1
187 changed files with 8897 additions and 1614 deletions
@@ -15,6 +15,7 @@ Restore DoD to ✅ PASS by eliminating **all HIGH/CRITICAL** findings from:
- Trivy results produced by **Security: Trivy Scan**
Hard constraints:
- Do **not** weaken gates (no suppressing findings unless a false-positive is proven and documented).
- Prefer minimal, targeted changes.
- Avoid adding new runtime dependencies.
@@ -40,10 +41,12 @@ QA report note: Trivy filesystem scan may be picking up **workspace caches/artif
## Step 0 — Trivy triage (required first)
Objective: Re-run the current Trivy task and determine whether HIGH/CRITICAL findings are attributable to:
- **Repo-tracked paths** (e.g., `backend/go.mod`, `backend/go.sum`, `Dockerfile`, `frontend/`, etc.), or
- **Generated/cache paths** under the workspace (e.g., `.cache/`, `**/*.cover`, `codeql-db-*`, temporary build outputs).
Steps:
1. Run **Security: Trivy Scan**.
2. For each HIGH/CRITICAL item, record the affected file path(s) reported by Trivy.
3. Classify each finding:
@@ -51,6 +54,7 @@ Steps:
- **Scan-scope noise**: path is a workspace cache/artifact directory not intended as deliverable input.
Decision outcomes:
- If HIGH/CRITICAL are **repo-tracked / shipped** → remediate by upgrading only the affected components to Trivys fixed versions (see Workstreams C/D).
- If HIGH/CRITICAL are **only cache/artifact paths** → treat as scan-scope noise and align Trivy scan scope to repo contents by excluding those directories (without disabling scanners or suppressing findings).
@@ -68,6 +72,7 @@ Implementation direction (minimal + CodeQL-friendly):
4. Add unit tests that attempt CRLF injection in subject/from/to and assert the send/build path rejects it.
Acceptance criteria:
- CodeQL Go scan shows **0** `go/email-injection` findings.
- Backend unit tests cover the rejection paths.
@@ -76,9 +81,11 @@ Acceptance criteria:
Objective: Remove an “incomplete hostname regex” pattern flagged by CodeQL.
Preferred change:
- Replace hostname regex usage with an exact string match (or an anchored + escaped regex like `^link\.example\.com$`).
Acceptance criteria:
- CodeQL JS scan shows **0** `js/incomplete-hostname-regexp` findings.
### Workstream C — Container / embedded binaries (DevOps): Fix Trivy image finding
@@ -92,6 +99,7 @@ Implementation direction:
3. If no suitable CrowdSec release is available, patch the build in the CrowdSec build stage similarly to the existing Caddy stage override (force `expr@1.17.7` before building).
Acceptance criteria:
- Trivy image scan reports **0 HIGH/CRITICAL**.
### Workstream D — Go module upgrades (Backend_Dev + QA_Security): Fix Trivy repo scan findings
@@ -101,13 +109,17 @@ Objective: Eliminate Trivy filesystem-scan HIGH/CRITICAL findings without over-u
Implementation direction (conditional; driven by Step 0 triage):
1. If Trivy attributes HIGH/CRITICAL to `backend/go.mod` / `backend/go.sum` **or** to the built `app/charon` binary:
- Bump **only the specific Go modules Trivy flags** to Trivys fixed versions.
- Run `go mod tidy` and ensure builds/tests stay green.
2. If Trivy attributes HIGH/CRITICAL **only** to workspace caches / generated artifacts (e.g., `.cache/go/pkg/mod/...`):
- Treat as scan-scope noise and align Trivys filesystem scan scope to repo-tracked content by excluding those directories.
- This is **not** gate weakening: scanners stay enabled and the project must still achieve **0 HIGH/CRITICAL** in Trivy outputs.
- Bump **only the specific Go modules Trivy flags** to Trivys fixed versions.
- Run `go mod tidy` and ensure builds/tests stay green.
1. If Trivy attributes HIGH/CRITICAL **only** to workspace caches / generated artifacts (e.g., `.cache/go/pkg/mod/...`):
- Treat as scan-scope noise and align Trivys filesystem scan scope to repo-tracked content by excluding those directories.
- This is **not** gate weakening: scanners stay enabled and the project must still achieve **0 HIGH/CRITICAL** in Trivy outputs.
Acceptance criteria:
- Trivy scan reports **0 HIGH/CRITICAL**.
## Validation (VS Code tasks)
@@ -122,14 +134,14 @@ Run tasks in this order (only run frontend ones if Workstream B changes anything
If any changes are made to `Dockerfile` / CrowdSec build stage:
6. **Build & Run: Local Docker Image No-Cache** (recommended)
7. **Security: Trivy Scan** (re-verify image scan after rebuild)
1. **Build & Run: Local Docker Image No-Cache** (recommended)
2. **Security: Trivy Scan** (re-verify image scan after rebuild)
If `frontend/` changes are made:
6. **Lint: TypeScript Check**
7. **Test: Frontend with Coverage**
8. **Lint: Frontend**
1. **Lint: TypeScript Check**
2. **Test: Frontend with Coverage**
3. **Lint: Frontend**
## Handoff checklist
@@ -9,6 +9,7 @@
## Executive Summary
GitHub Advanced Security is reporting that 2 workflow configurations from `refs/heads/main` are missing in the current PR branch (`feature/beta-release`):
1. `.github/workflows/security-weekly-rebuild.yml:security-rebuild`
2. `.github/workflows/docker-publish.yml:build-and-push`
@@ -23,6 +24,7 @@ GitHub Advanced Security is reporting that 2 workflow configurations from `refs/
### 1. File State Analysis
#### Current Branch (`feature/beta-release`)
```
✅ .github/workflows/security-weekly-rebuild.yml EXISTS
- Job name: security-rebuild
@@ -42,6 +44,7 @@ GitHub Advanced Security is reporting that 2 workflow configurations from `refs/
```
#### Main Branch (`refs/heads/main`)
```
✅ .github/workflows/security-weekly-rebuild.yml EXISTS
- Job name: security-rebuild
@@ -67,6 +70,7 @@ Date: Sun Dec 21 15:11:25 2025 +0000
```
**Key Findings:**
- `docker-publish.yml` was deleted on **BOTH** main and feature/beta-release branches
- `docker-build.yml` exists on **BOTH** branches with the **SAME** job name
- The warning is a GitHub Advanced Security tracking artifact from when `docker-publish.yml` existed
@@ -85,6 +89,7 @@ Date: Sun Dec 21 15:11:25 2025 +0000
| **Concurrency Control** | ✅ Yes | ✅ Yes (ENHANCED) |
**Improvement Analysis:** `docker-build.yml` is **MORE SECURE** than the deleted `docker-publish.yml`:
- Added SBOM generation (supply chain security)
- Added SBOM attestation with cryptographic signing
- Added CVE-2025-68156 verification for Caddy
@@ -102,6 +107,7 @@ Date: Sun Dec 21 15:11:25 2025 +0000
| `docker-build.yml` | `trivy-pr-app-only` | ✅ Yes (app binary) | ❌ No | PR only |
**Coverage Assessment:**
- Weekly security rebuilds: ✅ ACTIVE
- Per-commit scanning: ✅ ACTIVE
- PR-specific scanning: ✅ ACTIVE
@@ -117,6 +123,7 @@ Date: Sun Dec 21 15:11:25 2025 +0000
**Symptom:** GitHub Advanced Security tracks workflow configurations by **filename + job name**. When a workflow file is deleted/renamed, GitHub Security's internal tracking doesn't automatically update the reference mapping.
**Root Cause Chain:**
1. `docker-publish.yml` existed on main branch (tracked as `docker-publish.yml:build-and-push`)
2. Commit `f640524b` deleted `docker-publish.yml` and functionality was moved to `docker-build.yml`
3. GitHub Security still has historical tracking data for `docker-publish.yml:build-and-push`
@@ -124,6 +131,7 @@ Date: Sun Dec 21 15:11:25 2025 +0000
5. File not found → Warning generated
**Why This is a False Positive:**
- The job name `build-and-push` still exists in `docker-build.yml`
- All Trivy scanning functionality is preserved (and enhanced)
- Both branches have the same state (file deleted, functionality moved)
@@ -132,6 +140,7 @@ Date: Sun Dec 21 15:11:25 2025 +0000
### Why Was docker-publish.yml Deleted?
Based on git history and inspection:
1. **Consolidation:** Functionality was merged/improved in `docker-build.yml`
2. **Enhancement:** `docker-build.yml` added SBOM, attestation, and CVE checks
3. **Maintenance:** Reduced workflow file duplication
@@ -142,15 +151,18 @@ Based on git history and inspection:
## Resolution Strategy
### Option 1: Do Nothing (RECOMMENDED)
**Rationale:** This is a **false positive tracking issue**, not a functional security problem.
**Pros:**
- No code changes required
- No risk of breaking existing functionality
- Security coverage is complete and enhanced
- Warning will eventually clear when GitHub Security updates its tracking
**Cons:**
- Warning remains visible in GitHub Security UI
- May confuse reviewers/auditors
@@ -159,19 +171,23 @@ Based on git history and inspection:
---
### Option 2: Force GitHub Security to Update Tracking
**Approach:** Trigger a manual re-scan or workflow dispatch on main branch to refresh GitHub Security's workflow registry.
**Steps:**
1. Navigate to Actions → `security-weekly-rebuild.yml`
2. Click "Run workflow" → Run on main branch
3. Wait for workflow completion
4. Check if GitHub Security updates its tracking
**Pros:**
- May clear the warning faster
- No code changes required
**Cons:**
- No guarantee GitHub Security will update tracking immediately
- May need to wait for GitHub's internal cache/indexing to refresh
- Uses CI/CD resources
@@ -181,9 +197,11 @@ Based on git history and inspection:
---
### Option 3: Re-create docker-publish.yml as a Wrapper (NOT RECOMMENDED)
**Approach:** Create a new `docker-publish.yml` that calls `docker-build.yml` via `workflow_call`.
**Example Implementation:**
```yaml
# .github/workflows/docker-publish.yml
name: Docker Publish (Deprecated - Use docker-build.yml)
@@ -197,10 +215,12 @@ jobs:
```
**Pros:**
- Satisfies GitHub Security's filename tracking
- Maintains backward compatibility for any external references
**Cons:**
- ❌ Creates unnecessary file duplication
- ❌ Adds maintenance burden
- ❌ Confuses future developers (two files doing the same thing)
@@ -212,21 +232,25 @@ jobs:
---
### Option 4: Add Comprehensive Documentation
**Approach:** Document the workflow file rename/migration in repository documentation.
**Implementation:**
1. Update `CHANGELOG.md` with entry for docker-publish.yml removal
2. Add section to `SECURITY.md` explaining current Trivy coverage
3. Create `.github/workflows/README.md` documenting workflow structure
4. Add comment to `docker-build.yml` explaining it replaced `docker-publish.yml`
**Pros:**
- ✅ Improves project documentation
- ✅ Helps future maintainers understand the change
- ✅ Provides audit trail for security reviews
- ✅ No functional changes, zero risk
**Cons:**
- Doesn't clear the GitHub Security warning
- Requires documentation updates
@@ -237,11 +261,14 @@ jobs:
## Recommended Action Plan
### Phase 1: Documentation (IMMEDIATE)
**Objective:** Create audit trail and improve project documentation.
**Tasks:**
1. ✅ Create this plan document (`docs/plans/GITHUB_SECURITY_WARNING_RESOLUTION_PLAN.md`) ← DONE
2. Add entry to `CHANGELOG.md`:
```markdown
### Changed
- Replaced `.github/workflows/docker-publish.yml` with `.github/workflows/docker-build.yml` for enhanced supply chain security
@@ -249,7 +276,9 @@ jobs:
- Added CVE-2025-68156 verification for Caddy
- Job name `build-and-push` preserved for continuity
```
3. Add section to `SECURITY.md`:
```markdown
## Security Scanning Coverage
@@ -267,7 +296,9 @@ jobs:
All Trivy results are uploaded to the [Security tab](../../security/code-scanning).
```
4. Add header comment to `docker-build.yml`:
```yaml
# This workflow replaced docker-publish.yml on 2025-12-21
# Enhancement: Added SBOM generation, attestation, and CVE verification
@@ -281,13 +312,17 @@ jobs:
---
### Phase 2: Verification (AFTER DOCUMENTATION)
**Objective:** Confirm that security scanning is functioning correctly.
**Tasks:**
1. Verify `security-weekly-rebuild.yml` is scheduled correctly:
```bash
git show main:.github/workflows/security-weekly-rebuild.yml | grep -A 5 "schedule:"
```
2. Check recent workflow runs in GitHub Actions UI:
- Verify `docker-build.yml` runs on push/PR
- Verify `security-weekly-rebuild.yml` runs weekly
@@ -298,6 +333,7 @@ jobs:
- Check for any missed scans
**Success Criteria:**
- ✅ All workflows show successful runs
- ✅ Trivy SARIF results appear in Security tab
- ✅ No scan failures in last 30 days
@@ -310,14 +346,17 @@ jobs:
---
### Phase 3: Monitor (ONGOING)
**Objective:** Track if GitHub Security warning clears naturally.
**Tasks:**
1. Check PR status page weekly for warning persistence
2. If warning persists after 4 weeks, try Option 2 (manual workflow dispatch)
3. If warning persists after 8 weeks, open GitHub Support ticket
**Success Criteria:**
- Warning clears within 4-8 weeks as GitHub Security updates tracking
**Estimated Time:** 5 minutes/week
@@ -341,6 +380,7 @@ jobs:
### Impact Analysis
**If We Do Nothing:**
- Security scanning: ✅ UNAFFECTED (fully functional)
- Code quality: ✅ UNAFFECTED
- Developer experience: ✅ UNAFFECTED
@@ -348,6 +388,7 @@ jobs:
- Compliance audits: ✅ PASS (coverage is complete, documented)
**If We Implement Phase 1 (Documentation):**
- Security scanning: ✅ UNAFFECTED
- Code quality: ✅ IMPROVED (better documentation)
- Developer experience: ✅ IMPROVED (clearer history)
@@ -361,6 +402,7 @@ jobs:
### Workflow File Comparison
#### security-weekly-rebuild.yml
```yaml
name: Weekly Security Rebuild
on:
@@ -376,6 +418,7 @@ jobs:
```
#### docker-build.yml (current)
```yaml
name: Docker Build, Publish & Test
on:
@@ -396,6 +439,7 @@ jobs:
```
#### docker-publish.yml (DELETED on 2025-12-21)
```yaml
name: Docker Build, Publish & Test # ← Same name as docker-build.yml
on:
@@ -414,6 +458,7 @@ jobs:
```
**Migration Notes:**
- ✅ Job name `build-and-push` preserved for continuity
- ✅ All Trivy functionality preserved
- ✅ Enhanced with SBOM generation and attestation
@@ -425,12 +470,14 @@ jobs:
## Dependencies
### Files to Review/Update (Phase 1)
- [ ] `CHANGELOG.md` - Add entry for workflow migration
- [ ] `SECURITY.md` - Document security scanning coverage
- [ ] `.github/workflows/docker-build.yml` - Add header comment
- [ ] `.github/workflows/README.md` - Create workflow documentation (optional)
### No Changes Required (Already Compliant)
- ✅ `.gitignore` - No new files/folders added
- ✅ `.dockerignore` - No Docker changes
- ✅ `.codecov.yml` - No coverage changes
@@ -441,6 +488,7 @@ jobs:
## Success Criteria
### Phase 1 Success (Documentation)
- [x] Plan document created and comprehensive
- [x] Root cause identified (workflow file renamed)
- [x] Security coverage verified (all scans active)
@@ -451,12 +499,14 @@ jobs:
- [ ] No linting or formatting errors
### Phase 2 Success (Verification)
- [ ] All workflows show successful recent runs
- [ ] Trivy SARIF results visible in Security tab
- [ ] No scan failures in last 30 days
- [ ] Weekly security rebuild on schedule
### Phase 3 Success (Monitoring)
- [ ] GitHub Security warning tracked weekly
- [ ] Warning clears within 8 weeks OR GitHub Support ticket opened
- [ ] No functional issues with security scanning
@@ -468,6 +518,7 @@ jobs:
### Why Not Fix the "Warning" Immediately?
**Considered Approaches:**
1. **Re-create docker-publish.yml as wrapper**
- ❌ Creates maintenance burden
- ❌ Doesn't solve root cause
@@ -484,6 +535,7 @@ jobs:
- ⚠️ Should be last resort after monitoring
**Selected Approach: Document and Monitor**
- ✅ Zero risk to existing functionality
- ✅ Improves project documentation
- ✅ Provides audit trail
@@ -494,26 +546,34 @@ jobs:
## Questions and Answers
### Q: Is this a security vulnerability?
**A:** No. This is a tracking/reporting issue in GitHub Advanced Security's workflow registry. All security scanning functionality is active and enhanced compared to the deleted workflow.
### Q: Will this block merging the PR?
**A:** No. GitHub Advanced Security warnings are informational and do not block merges. The warning indicates a tracking discrepancy, not a functional security gap.
### Q: Should we re-create docker-publish.yml?
**A:** No. Re-creating the file would be symptom patching and create maintenance burden. The functionality exists in `docker-build.yml` with enhancements.
### Q: How long will the warning persist?
**A:** Unknown. It depends on GitHub's internal tracking cache refresh cycle. Typically, these warnings clear within 4-8 weeks as GitHub's systems update. If it persists beyond 8 weeks, we can escalate to GitHub Support.
### Q: Does this affect compliance audits?
**A:** No. This document provides a complete audit trail showing:
1. Security scanning coverage is complete
2. Functionality was enhanced, not reduced
3. The warning is a false positive from filename tracking
4. All Trivy scans are active and uploading to Security tab
### Q: What if reviewers question the warning?
**A:** Point them to this document which provides:
1. Complete investigation summary
2. Root cause analysis
3. Risk assessment (LOW severity, tracking issue only)
@@ -528,6 +588,7 @@ jobs:
**Security Status:** ✅ **NO SECURITY GAPS** - All Trivy scanning is active, functional, and enhanced compared to the deleted workflow.
**Recommended Action:**
1. ✅ **Implement Phase 1** - Document the migration (30 minutes, zero risk)
2. ✅ **Implement Phase 2** - Verify scanning functionality (15 minutes, read-only)
3. ✅ **Implement Phase 3** - Monitor warning status (5 min/week, optional escalation)
@@ -543,19 +604,22 @@ jobs:
## References
### Git Commits
- `f640524b` - Removed docker-publish.yml (Dec 21, 2025)
- `e58fcb71` - Created docker-build.yml (initial)
- `8311d68d` - Updated docker-build.yml buildx action (latest)
### Workflow Files
- `.github/workflows/security-weekly-rebuild.yml` - Weekly security rebuild
- `.github/workflows/docker-build.yml` - Current build and publish workflow
- `.github/workflows/docker-publish.yml` - DELETED (replaced by docker-build.yml)
### Documentation
- GitHub Advanced Security: https://docs.github.com/en/code-security
- Trivy Scanner: https://github.com/aquasecurity/trivy
- SARIF Format: https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning
- GitHub Advanced Security: <https://docs.github.com/en/code-security>
- Trivy Scanner: <https://github.com/aquasecurity/trivy>
- SARIF Format: <https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning>
---
@@ -18,6 +18,7 @@
Successfully resolved issue where PR status checks didn't appear when docs-to-issues workflow ran.
**Documentation:**
- **Implementation Summary**: [docs/implementation/DOCS_TO_ISSUES_FIX_2026-01-11.md](../implementation/DOCS_TO_ISSUES_FIX_2026-01-11.md)
- **QA Report**: [docs/reports/qa_docs_to_issues_workflow_fix.md](../reports/qa_docs_to_issues_workflow_fix.md)
- **Archived Plan**: [docs/plans/archive/docs_to_issues_workflow_fix_2026-01-11.md](archive/docs_to_issues_workflow_fix_2026-01-11.md)
@@ -33,6 +34,7 @@ Successfully resolved issue where PR status checks didn't appear when docs-to-is
The CI workflow investigation and documentation has been completed. Both issues were determined to be false positives or expected GitHub behavior with no security gaps.
**Final Documentation:**
- **Implementation Summary**: [docs/implementation/CI_WORKFLOW_FIXES_2026-01-11.md](../implementation/CI_WORKFLOW_FIXES_2026-01-11.md)
- **QA Report**: [docs/reports/qa_report.md](../reports/qa_report.md)
- **Archived Plan**: [docs/plans/archive/GITHUB_SECURITY_WARNING_RESOLUTION_PLAN_2026-01-11.md](archive/GITHUB_SECURITY_WARNING_RESOLUTION_PLAN_2026-01-11.md)
@@ -46,6 +48,7 @@ The CI workflow investigation and documentation has been completed. Both issues
Successfully fixed workflow orchestration issue where supply-chain-verify was running before docker-build completed, causing verification to skip on PRs.
**Documentation:**
- **Implementation Summary**: [docs/implementation/WORKFLOW_ORCHESTRATION_FIX.md](../implementation/WORKFLOW_ORCHESTRATION_FIX.md)
- **QA Report**: [docs/reports/qa_report_workflow_orchestration.md](../reports/qa_report_workflow_orchestration.md)
- **Archived Plan**: [docs/plans/archive/workflow_orchestration_fix_2026-01-11.md](archive/workflow_orchestration_fix_2026-01-11.md)
@@ -59,6 +62,7 @@ Successfully fixed workflow orchestration issue where supply-chain-verify was ru
Successfully resolved CI/CD failures in the Supply Chain Verification workflow caused by Grype SBOM format mismatch.
**Documentation:**
- **Implementation Summary**: [docs/implementation/GRYPE_SBOM_REMEDIATION.md](../implementation/GRYPE_SBOM_REMEDIATION.md)
- **QA Report**: [docs/reports/qa_report.md](../reports/qa_report.md)
- **Archived Plan**: [docs/plans/archive/grype_sbom_remediation_2026-01-10.md](archive/grype_sbom_remediation_2026-01-10.md)
@@ -93,6 +97,7 @@ When a specification is complete:
## Archive Location
Completed and archived specifications can be found in:
- [docs/plans/archive/](archive/)
---
@@ -40,6 +40,7 @@ syft ${IMAGE} -o spdx-json > sbom-generated.json || {
\`\`\`
**Issues**:
- Generates SBOM in **SPDX-JSON** format
- Error handling exits with code 0, masking failures
- Empty or malformed file may be created if image doesn't exist
@@ -55,6 +56,7 @@ grype sbom:sbom-generated.json -o json > vuln-scan.json || {
\`\`\`
**Issues**:
- Assumes SBOM file is valid without checking
- Fails if SBOM is empty, corrupted, or malformed
- Error is suppressed with `exit 0`
@@ -83,11 +85,13 @@ grype sbom:sbom-generated.json -o json > vuln-scan.json || {
### Supported Formats (Anchore Documentation)
**Grype** supports:
- Syft JSON (native format)
- SPDX JSON/XML
- CycloneDX JSON/XML
**Syft** outputs:
- Syft JSON
- SPDX JSON/XML
- CycloneDX JSON/XML
@@ -126,6 +130,7 @@ grype sbom:sbom-generated.json -o json > vuln-scan.json || {
Combine format standardization, validation, and conditional execution.
**Phase 1** (Immediate - 2-4 hours):
1. Standardize on **CycloneDX-JSON** format (aligns with docker-build.yml)
2. Add image existence check before SBOM generation
3. Add comprehensive SBOM validation before Grype scan
@@ -133,6 +138,7 @@ Combine format standardization, validation, and conditional execution.
5. Skip gracefully when image doesn't exist
**Phase 2** (Future enhancement - 4-8 hours):
- Retrieve attested SBOM from registry instead of regenerating
- Eliminates duplication and ensures consistency
@@ -147,6 +153,7 @@ Combine format standardization, validation, and conditional execution.
**Location**: After "Determine Image Tag" step (after line 54)
\`\`\`yaml
- name: Check Image Availability
id: image-check
env:
@@ -187,6 +194,7 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
**Before**:
\`\`\`yaml
- name: Verify SBOM Completeness
env:
IMAGE: ghcr.io/${{ github.repository_owner }}/charon:${{ steps.tag.outputs.tag }}
@@ -194,6 +202,7 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
**After**:
\`\`\`yaml
- name: Verify SBOM Completeness
if: steps.image-check.outputs.exists == 'true'
env:
@@ -205,27 +214,31 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
**Location**: New step after "Verify SBOM Completeness" (after line 77)
\`\`\`yaml
- name: Validate SBOM File
id: validate-sbom
if: steps.image-check.outputs.exists == 'true'
run: |
echo "Validating SBOM file..."
# Check file exists
# Check file exists
if [[ ! -f sbom-generated.json ]]; then
echo "❌ SBOM file does not exist"
echo "valid=false" >> $GITHUB_OUTPUT
exit 0
fi
# Check file is non-empty
# Check file is non-empty
if [[ ! -s sbom-generated.json ]]; then
echo "❌ SBOM file is empty"
echo "valid=false" >> $GITHUB_OUTPUT
exit 0
fi
# Validate JSON structure
# Validate JSON structure
if ! jq empty sbom-generated.json 2>/dev/null; then
echo "❌ SBOM file contains invalid JSON"
cat sbom-generated.json
@@ -233,7 +246,8 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
exit 0
fi
# Validate CycloneDX structure
# Validate CycloneDX structure
BOMFORMAT=$(jq -r '.bomFormat // "missing"' sbom-generated.json)
SPECVERSION=$(jq -r '.specVersion // "missing"' sbom-generated.json)
COMPONENTS=$(jq '.components // [] | length' sbom-generated.json)
@@ -262,6 +276,7 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
**Location**: Lines 81-103 (replace entire "Scan for Vulnerabilities" step)
\`\`\`yaml
- name: Scan for Vulnerabilities
if: steps.validate-sbom.outputs.valid == 'true'
env:
@@ -272,7 +287,8 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
echo "SBOM size: $(wc -c < sbom-generated.json) bytes"
echo ""
# Run Grype with explicit path and better error handling
# Run Grype with explicit path and better error handling
if ! grype sbom:./sbom-generated.json --output json --file vuln-scan.json; then
echo ""
echo "❌ Grype scan failed"
@@ -290,11 +306,13 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
echo "✅ Grype scan completed successfully"
echo ""
# Display human-readable results
# Display human-readable results
echo "Vulnerability summary:"
grype sbom:./sbom-generated.json --output table || true
# Parse and categorize results
# Parse and categorize results
CRITICAL=$(jq '[.matches[] | select(.vulnerability.severity == "Critical")] | length' vuln-scan.json 2>/dev/null || echo "0")
HIGH=$(jq '[.matches[] | select(.vulnerability.severity == "High")] | length' vuln-scan.json 2>/dev/null || echo "0")
MEDIUM=$(jq '[.matches[] | select(.vulnerability.severity == "Medium")] | length' vuln-scan.json 2>/dev/null || echo "0")
@@ -307,12 +325,14 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
echo " Medium: ${MEDIUM}"
echo " Low: ${LOW}"
# Set warnings for critical vulnerabilities
# Set warnings for critical vulnerabilities
if [[ ${CRITICAL} -gt 0 ]]; then
echo "::warning::${CRITICAL} critical vulnerabilities found"
fi
# Store for PR comment
# Store for PR comment
echo "CRITICAL_VULNS=${CRITICAL}" >> $GITHUB_ENV
echo "HIGH_VULNS=${HIGH}" >> $GITHUB_ENV
echo "MEDIUM_VULNS=${MEDIUM}" >> $GITHUB_ENV
@@ -344,6 +364,7 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
**Location**: Lines 107-122 (replace entire "Comment on PR" step)
\`\`\`yaml
- name: Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
@@ -388,6 +409,7 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
issue_number: context.issue.number,
body: body
});
\`\`\`
---
@@ -399,40 +421,52 @@ syft ${IMAGE} -o cyclonedx-json > sbom-generated.json || {
#### 1. Local SBOM Generation and Validation
\`\`\`bash
# Test SBOM generation with existing image
docker pull ghcr.io/wikid82/charon:latest
# Generate SBOM in CycloneDX format
syft ghcr.io/wikid82/charon:latest -o cyclonedx-json > test-sbom.json
# Validate JSON structure
jq empty test-sbom.json && echo "✅ Valid JSON" || echo "❌ Invalid JSON"
# Check CycloneDX fields
jq '.bomFormat, .specVersion, .components | length' test-sbom.json
# Test Grype scan
grype sbom:./test-sbom.json -o table
# Test with explicit path
grype sbom:./test-sbom.json -o json > vuln-test.json
# Check results
jq '.matches | length' vuln-test.json
\`\`\`
#### 2. Test Empty/Invalid SBOM Handling
\`\`\`bash
# Test with empty file
touch empty.json
grype sbom:./empty.json 2>&1 | grep -i "format"
# Test with invalid JSON
echo "{invalid json" > invalid.json
grype sbom:./invalid.json 2>&1 | grep -i "format"
# Test with missing fields
echo '{"bomFormat":"test"}' > incomplete.json
grype sbom:./incomplete.json 2>&1 | grep -i "format"
\`\`\`
@@ -440,10 +474,13 @@ grype sbom:./incomplete.json 2>&1 | grep -i "format"
#### 3. Test Image Availability Check
\`\`\`bash
# Test manifest check for existing image
docker manifest inspect ghcr.io/wikid82/charon:latest
# Test manifest check for non-existent image
docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
\`\`\`
@@ -495,11 +532,14 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
3. **Alternative: Pin Tool Versions**
If the issue is version-related:
\`\`\`yaml
# Pin Syft version
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v0.100.0
curl -sSfL <https://raw.githubusercontent.com/anchore/syft/main/install.sh> | sh -s -- -b /usr/local/bin v0.100.0
# Pin Grype version
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin v0.74.0
curl -sSfL <https://raw.githubusercontent.com/anchore/grype/main/install.sh> | sh -s -- -b /usr/local/bin v0.74.0
\`\`\`
### Investigation Steps
@@ -515,12 +555,14 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
## Dependencies and Prerequisites
### Tool Versions
- **Syft**: Latest from install script (currently v0.100+)
- **Grype**: Latest from install script (currently v0.74+)
- **Docker**: v20+ (available in GitHub runners)
- **jq**: v1.6+ (available in GitHub runners)
### GitHub Permissions Required
- `contents: read` - Repository code access
- `packages: read` - Container registry access
- `pull-requests: write` - Comment on PRs
@@ -529,6 +571,7 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
- `attestations: write` - Create/verify attestations
### External Dependencies
- GitHub Container Registry (ghcr.io) must be accessible
- Anchore install scripts must be available
- Internet access required for tool installation
@@ -538,11 +581,13 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
## Implementation Checklist
### Preparation
- [ ] Review current workflow file
- [ ] Document current behavior
- [ ] Create feature branch
### Implementation
- [ ] Add image existence check step
- [ ] Change SBOM format from SPDX to CycloneDX
- [ ] Add SBOM validation step
@@ -552,6 +597,7 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
- [ ] Update workflow documentation
### Testing
- [ ] Test locally with existing image
- [ ] Test with empty SBOM file
- [ ] Test with invalid JSON
@@ -562,12 +608,14 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
- [ ] Verify success path
### Documentation
- [ ] Update README if needed
- [ ] Document SBOM format choice
- [ ] Add troubleshooting guide
- [ ] Update CI/CD documentation
### Deployment
- [ ] Create PR with changes
- [ ] Code review
- [ ] Merge to main
@@ -609,6 +657,7 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
## Success Metrics
### Technical Metrics
- Workflow success rate: 100% on valid images
- SBOM validation accuracy: 100%
- Grype scan completion rate: 100% on valid SBOMs
@@ -616,12 +665,14 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
- False negative rate: 0%
### Operational Metrics
- Time to detect vulnerability: < 5 minutes after image build
- Mean time to remediate issues: Immediate (next workflow run)
- Manual intervention required: 0
- CI/CD pipeline reliability: > 99%
### Quality Metrics
- Zero "format not recognized" errors in 30 days
- Clear, actionable error messages
- Comprehensive workflow logs
@@ -636,6 +687,7 @@ docker manifest inspect ghcr.io/wikid82/charon:pr-99999 2>&1
Instead of regenerating SBOM, retrieve the one created by docker-build:
\`\`\`yaml
- name: Retrieve Attested SBOM
if: steps.image-check.outputs.exists == 'true'
env:
@@ -644,7 +696,8 @@ Instead of regenerating SBOM, retrieve the one created by docker-build:
run: |
echo "Retrieving attested SBOM from registry..."
# Download attestation using GitHub CLI
# Download attestation using GitHub CLI
gh attestation verify oci://${IMAGE} \
--owner ${{ github.repository_owner }} \
--format json > attestation.json 2>&1 || {
@@ -652,10 +705,12 @@ Instead of regenerating SBOM, retrieve the one created by docker-build:
exit 0
}
# Extract SBOM from attestation
# Extract SBOM from attestation
jq -r '.predicate' attestation.json > sbom-attested.json
# Validate and use
# Validate and use
if jq empty sbom-attested.json 2>/dev/null; then
echo "✅ Retrieved attested SBOM"
mv sbom-attested.json sbom-generated.json
@@ -665,12 +720,14 @@ Instead of regenerating SBOM, retrieve the one created by docker-build:
\`\`\`
**Benefits**:
- Single source of truth
- Eliminates duplication
- Uses verified, signed SBOM
- Aligns with supply chain best practices
**Requirements**:
- GitHub CLI with attestation support
- Attestation must be published to registry
- Additional testing for attestation retrieval
@@ -680,11 +737,13 @@ Instead of regenerating SBOM, retrieve the one created by docker-build:
## Related Documentation
### Internal References
- [.github/workflows/supply-chain-verify.yml](.github/workflows/supply-chain-verify.yml)
- [.github/workflows/docker-build.yml](.github/workflows/docker-build.yml)
- Project README (Security section)
### External References
- [Anchore Grype Documentation](https://github.com/anchore/grype)
- [Anchore Syft Documentation](https://github.com/anchore/syft)
- [CycloneDX Specification](https://cyclonedx.org/specification/overview/)
@@ -702,6 +761,7 @@ Instead of regenerating SBOM, retrieve the one created by docker-build:
**Review Status**: Ready for Review
**Required Reviewers**:
- [ ] DevOps Lead / CI/CD Owner
- [ ] Security Team Representative
- [ ] Repository Maintainer
@@ -20,6 +20,7 @@
**Translation:** Staticcheck must be a **COMMIT GATE** - failures must BLOCK the commit, forcing immediate fix before commit succeeds.
**Current Gaps:**
- ✅ Staticcheck IS enabled in golangci-lint (`.golangci.yml` line 14)
- ✅ Staticcheck IS running in CI via golangci-lint-action (`quality-checks.yml` line 65-70)
- ❌ Staticcheck is NOT running in local pre-commit hooks as a BLOCKING gate
@@ -28,6 +29,7 @@
- ⚠️ Test files excluded from staticcheck in `.golangci.yml` (line 68-70)
**Why This Matters:**
- Developers see staticcheck warnings/errors in VS Code editor
- **These issues are NOT blocked at commit time** ← CRITICAL PROBLEM
- CI failures don't block merges (continue-on-error: true)
@@ -40,10 +42,12 @@
### Supervisor Critical Feedback & Decisions
**Feedback #1: Redundancy Issue**
- Current plan creates duplicate staticcheck runs (standalone + golangci-lint)
- **Decision:** Use **Hybrid Approach** (Supervisor's recommendation) - explained below
**Feedback #2: Performance Benchmarks Required**
- **ACTUAL MEASUREMENT (2026-01-11):**
- Command: `time staticcheck ./...` (in backend/)
- **Runtime: 15.3 seconds (real), 44s CPU (user), 4.3s I/O (sys)**
@@ -52,20 +56,24 @@
- Exit code: 1 (FAILS - this is what we want for blocking)
**Feedback #3: Version Pinning**
- **Decision:** Pin to `@2024.1.1` in installation docs
- Note: Installation of 2024.1.1 failed due to compiler bug; fallback to @latest (2025.1.1) works
- Will document @latest with version verification step
**Feedback #4: CI Alignment Issue**
- CI has `continue-on-error: true` for golangci-lint (line 71 in quality-checks.yml)
- **Local will be STRICTER than CI** - local BLOCKS, CI warns
- **Decision:** Document this discrepancy; recommend CI fix in Phase 6 (future work)
**Feedback #5: Test File Exclusion**
- `.golangci.yml` line 68-70: staticcheck excluded from `_test.go` files
- **Decision:** Match this behavior in new hook - exclude test files
**Feedback #6: Pre-flight Check**
- **Decision:** Add verification step that staticcheck is installed before running
---
@@ -75,6 +83,7 @@
**Why Hybrid Approach?**
**Advantages:**
1. **No Duplication:** Uses existing golangci-lint infrastructure
2. **Consistent Configuration:** Single source of truth (`.golangci.yml`)
3. **Test Exclusions Aligned:** Automatically respects test file exclusions
@@ -82,17 +91,20 @@
5. **Standard Practice:** Many projects use golangci-lint with selective linters for pre-commit
**Performance Comparison:**
- Standalone staticcheck: **15.3s**
- golangci-lint (staticcheck only): ~**18-22s** (estimated +20% overhead)
- golangci-lint (all 8 linters): 30-60s (too slow for pre-commit)
**Implementation Strategy:**
- Create lightweight pre-commit hook using golangci-lint with **ONLY fast linters**
- Enable: staticcheck, govet, errcheck, ineffassign, unused
- Disable: gosec, gocritic, bodyclose (slower or less critical)
- **CRITICAL:** Hook MUST exit with non-zero code to BLOCK commits
**Why NOT Standalone?**
- Supervisor correctly identified duplication concern
- Maintaining two configurations (hook + `.golangci.yml`) creates drift risk
- golangci-lint overhead is acceptable (3-7s) for consistency benefits
@@ -123,11 +135,13 @@
**File:** `backend/.golangci.yml`
**Staticcheck Configuration:**
- ✅ Line 14: `- staticcheck` (enabled in linters.enable)
- ✅ Lines 68-70: **Test file exclusions** (staticcheck excluded from `_test.go`)
- **IMPORTANT:** New hook MUST match this exclusion behavior
**Other Enabled Linters:**
- Fast: govet, ineffassign, unused, errcheck, staticcheck
- Slower: bodyclose, gocritic, gosec
@@ -136,11 +150,13 @@
**File:** `.github/workflows/quality-checks.yml`
**Lines 65-71:**
- Runs golangci-lint (includes staticcheck) in CI
- **⚠️ CRITICAL ISSUE:** `continue-on-error: true` means failures **don't block merges**
- This creates **local stricter than CI** situation
**Implication:**
- Local pre-commit will BLOCK on staticcheck errors
- CI will ALLOW merge with same errors
- **Recommendation:** Remove `continue-on-error: true` in future PR (Phase 6)
@@ -148,6 +164,7 @@
#### System Environment
**Staticcheck Installation Status:**
- ✅ **NOW INSTALLED:** staticcheck 2025.1.1 (0.6.1)
- Location: `$GOPATH/bin/staticcheck`
- **Benchmark Complete:** 15.3s runtime on full codebase
@@ -219,6 +236,7 @@ issues:
```
**Key Features:**
- **Pre-flight check:** Verifies golangci-lint is installed before running
- **Fast config:** Uses `.golangci-fast.yml` (only 5 linters, ~20s runtime)
- **BLOCKING:** Exit code propagates - failures BLOCK commit
@@ -231,6 +249,7 @@ issues:
**Location:** Development Setup section (after pre-commit installation)
**Addition:**
```markdown
### Go Development Tools
@@ -300,13 +319,13 @@ golangci-lint --version
.PHONY: lint-fast
lint-fast:
@echo "Running fast linters (staticcheck, govet, errcheck, ineffassign, unused)..."
cd backend && golangci-lint run --config .golangci-fast.yml ./...
@echo "Running fast linters (staticcheck, govet, errcheck, ineffassign, unused)..."
cd backend && golangci-lint run --config .golangci-fast.yml ./...
.PHONY: lint-staticcheck
lint-staticcheck:
@echo "Running staticcheck only..."
cd backend && golangci-lint run --config .golangci-fast.yml --disable-all --enable staticcheck ./...
@echo "Running staticcheck only..."
cd backend && golangci-lint run --config .golangci-fast.yml --disable-all --enable staticcheck ./...
```
---
@@ -504,6 +523,7 @@ make lint-staticcheck # Should run staticcheck only
**File:** `docs/implementation/STATICCHECK_BLOCKING_INTEGRATION_COMPLETE.md`
**Contents:**
```markdown
# Staticcheck BLOCKING Pre-Commit Integration - Implementation Complete
@@ -678,12 +698,14 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
**Line 71:** Remove or change `continue-on-error: true` to `continue-on-error: false`
**Requires:**
- Team discussion and agreement
- Ensure existing codebase passes golangci-lint cleanly
- May need to fix existing issues first
- Consider adding lint-fixes PR before enforcing
**Trade-offs:**
- **Pro:** Consistent quality enforcement (local + CI)
- **Pro:** Prevents merging code with linter issues
- **Con:** May slow down initial adoption
@@ -745,6 +767,7 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
### Performance Benchmarks (ACTUAL - Measured 2026-01-11)
**Environment:**
- System: Development environment
- Backend: Go 1.x codebase
- Lines of Go code: ~XX,XXX (estimate)
@@ -759,12 +782,14 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
| go vet | <5s | - | - | 0 | (active) |
**Analysis:**
- ✅ Fast config overhead acceptable: +30% vs standalone (~5s)
- ✅ Well under 30s target for pre-commit
- ✅ BLOCKING behavior confirmed (exit code 1)
- ✅ Consistency: Both tools find same staticcheck issues
**Current Issues Found (2026-01-11):**
- 1x Deprecated API (SA1019): `filepath.HasPrefix`
- 5x Unused values (SA4006): test setup code
- 1x Simplification opportunity (S1017): if statement
@@ -780,11 +805,13 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
### File Reference Summary
**Files to Create:**
1. `backend/.golangci-fast.yml` - Lightweight config for pre-commit (5 linters)
2. `docs/implementation/STATICCHECK_BLOCKING_INTEGRATION_COMPLETE.md` - Implementation summary
3. `docs/plans/archive/staticcheck_blocking_integration_2026-01-11.md` - Archived spec (after completion)
**Files to Modify:**
1. `.pre-commit-config.yaml` (line ~44: add golangci-lint-fast hook after go-vet)
2. `.vscode/tasks.json` (line ~211: add 2 new lint tasks after go-vet task)
3. `Makefile` (line ~141: add lint-fast and lint-staticcheck targets after lint-backend)
@@ -796,6 +823,7 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
6. `CHANGELOG.md` (Unreleased section: add breaking change notice)
**Files to Review (No Changes):**
- `backend/.golangci.yml` - Reference for test exclusions (lines 68-70)
- `.github/workflows/quality-checks.yml` - Reference for CI config (line 71: continue-on-error)
@@ -806,6 +834,7 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
**If problems occur during implementation:**
1. **Remove pre-commit hook:**
```bash
# Edit .pre-commit-config.yaml - remove golangci-lint-fast hook
git checkout HEAD -- .pre-commit-config.yaml
@@ -814,16 +843,19 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
```
2. **Delete fast config:**
```bash
rm backend/.golangci-fast.yml
```
3. **Revert documentation:**
```bash
git checkout HEAD -- README.md CHANGELOG.md .github/instructions/copilot-instructions.md
```
4. **Remove VS Code tasks and Makefile targets:**
```bash
git checkout HEAD -- .vscode/tasks.json Makefile
```
@@ -831,6 +863,7 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
**Rollback Time:** < 5 minutes (all changes are additive, easy to remove)
**Risk Mitigation:**
- Test each phase independently before proceeding
- Keep backup of original files during implementation
- Document any unexpected issues in implementation summary
@@ -876,6 +909,7 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
- **Residual Risk:** MEDIUM - requires cultural change
**Risk Mitigation Strategy:**
- Phased rollout: Test with subset of developers first (if possible)
- Clear communication: Explain WHY blocking is important
- Support: Troubleshooting guide and quick-check tasks
@@ -898,10 +932,12 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
**Total Estimated Time:** 3-4 hours (excluding Phase 6)
**Critical Path:**
- Phase 1 → Phase 4 (must verify blocking works)
- Phase 4 → Phase 5 (documentation depends on successful testing)
**Parallel Work Possible:**
- Phase 2 can start while Phase 1 is being tested
- Phase 3 documentation can be drafted during Phase 1-2
@@ -945,6 +981,7 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
- **Alternative Rejected:** Full golangci-lint (30-60s too slow)
**Review Conditions:**
- Re-evaluate after 1 month of usage
- Gather developer feedback on performance and adoption
- Measure impact on commit frequency and quality
@@ -955,12 +992,15 @@ Move `docs/plans/current_spec.md` to `docs/plans/archive/staticcheck_blocking_in
## Archive Location
**Current Specification:**
- This file: `docs/plans/current_spec.md`
**After Implementation:**
- Archive to: `docs/plans/archive/staticcheck_blocking_integration_2026-01-11.md`
**Previous Specifications:**
- See: [docs/plans/archive/](archive/) for historical specs
---
@@ -33,6 +33,7 @@ PR Opened
**Architecture Decision**: Keep workflows separate with dependency orchestration via `workflow_run` trigger.
**Rationale**:
- **Modularity**: Each workflow has a distinct, cohesive purpose
- **Reusability**: Verification can run on-demand or scheduled independently
- **Maintainability**: Easier to test, debug, and understand individual workflows
@@ -45,6 +46,7 @@ PR Opened
Modify `supply-chain-verify.yml` triggers:
**Current**:
```yaml
on:
release:
@@ -57,6 +59,7 @@ on:
```
**Proposed**:
```yaml
on:
release:
@@ -77,6 +80,7 @@ on:
```
**Key Changes**:
1. Remove `pull_request` trigger (prevents premature execution)
2. Add `workflow_run` trigger that waits for docker-build workflow
3. Specify branches to match docker-build's branch targets
@@ -164,6 +168,7 @@ Update the "Comment on PR" step to work with `workflow_run` context:
### Workflow Execution Flow (After Fix)
**PR Workflow**:
```
PR Opened/Updated
└─> docker-build.yml runs
@@ -179,6 +184,7 @@ PR Opened/Updated
```
**Push to Main**:
```
Push to main
└─> docker-build.yml runs
@@ -190,12 +196,14 @@ Push to main
### Implementation Checklist
**Changes to `.github/workflows/supply-chain-verify.yml`**:
- [x] Update triggers section (remove pull_request, add workflow_run)
- [x] Add job conditional (check workflow_run.conclusion)
- [x] Update tag determination (handle workflow_run context)
- [x] Update PR comment logic (extract PR number correctly)
**Testing Plan**:
- [ ] Test PR workflow (verify sequential execution and correct tagging)
- [ ] Test push to main (verify 'latest' tag usage)
- [ ] Test manual trigger (verify workflow_dispatch works)
@@ -247,6 +255,7 @@ Push to main
**Status**: ✅ All phases completed successfully
**Changes Made**:
1. ✅ Added `workflow_run` trigger to supply-chain-verify.yml
2. ✅ Removed `pull_request` trigger
3. ✅ Added workflow success filter
@@ -255,12 +264,14 @@ Push to main
6. ✅ Added debug logging for validation
**Validation**:
- ✅ Security audit passed (see [qa_report_workflow_orchestration.md](../../reports/qa_report_workflow_orchestration.md))
- ✅ Pre-commit hooks passed
- ✅ YAML syntax validated
- ✅ No breaking changes to other workflows
**Documentation**:
- [Implementation Summary](../../implementation/WORKFLOW_ORCHESTRATION_FIX.md)
- [QA Report](../../reports/qa_report_workflow_orchestration.md)