Skip to content

fix(ci): build PR images with a read-only token; publish only from main - #2179

Merged
Smana merged 4 commits into
mainfrom
fix/ci-image-build-split
Oct 3, 2026
Merged

Smana merged 4 commits into
mainfrom
fix/ci-image-build-split

Conversation

@Smana

@Smana Smana commented Oct 2, 2026

Copy link
Copy Markdown
Owner

What

Splits the single build-container-images.yml (PR + push + dispatch) into two workflows:

Workflow Triggers Permissions Login Push
check-container-images.yml (new) pull_request only contents: read workflow-wide no push: false
build-container-images.yml (keeps the name) push to main + workflow_dispatch contents: read, packages: write, security-events: write (job-level) yes push: true, Trivy/SARIF

Why

The old job held packages: write on pull_request while checking out the PR head and running PR-controlled build code. Fork PRs were saved only by GitHub's read-only fork token; same-repo PRs were not — any same-repo PR could overwrite published image tags. All four published images are consumed via mutable v* tag pins, so a tag overwrite reaches workloads (openbao-snapshot CronJob, headlamp-plugin-app, token-exchange-proxy, pev2). Verified exposure evidence in the SDD report f5-packages-write-report.md (same directory as the fix report below).

This is the remedy the SP3 plan's Task 6.3 names ("split the push out of the PR path"), so that plan's future workflow-secrets lint passes with no exception for this job.

Preserved by construction

  • Action pins — byte-identical (ref + comment tag) to the pre-split file, verified programmatically; zero lapsed to a tag, zero missing from the union of the two files.
  • Concurrency — the publish file keeps the workflow name Build Container Images, so main's group key (Build Container Images-refs/heads/main) is unchanged across the transition; the PR file keeps today's PR semantics (cancel-in-progress: true).
  • Tags — the load-bearing type=raw,value=<app-version> (v*) line is verbatim in both; each file lists only what its triggers can express (structurally-dead conditionals dropped, each a no-op for the surviving trigger).
  • gh workflow run build-container-images.yml and every existing link to the filename still target the workflow that builds and publishes.

Docs corrected to match

  • container-images/README.md and ci-workflows.md updated truthfully — including correcting the "immutable <branch>-<sha>" pinning claim: consumers pin the mutable v* tags, not digests.
  • docs/architecture/ci-pipeline.drawio's same false claims corrected (PR cell: read-only, never pushes or scans; publish cell: deployments pin the v* tag — mutable, not a digest); ci-pipeline.svg regenerated with the pinned drawio.

Verification

YAML parse of both files (exit 0); structural self-check passed (PR triggers exactly pull_request, every PR job ⊆ contents: read, no login step, publish triggers exactly push/workflow_dispatch, pins verbatim, push: false/true as mapped); validate-links.sh, validate-doc-claims.sh, verify-doc-paths.sh all exit 0; pre-commit green over the staged diffs. One transient at merge time: an in-flight PR run started under the old workflow name will not be cancelled by a newer run under the new one — it finishes and is ignored; main's queue is unaffected.

Detail and review evidence: .superpowers/sdd/2026-09-27-agent-dark-factory-plan/f5-fix-report.md (exposure analysis in f5-packages-write-report.md) in the o1-agent-observability worktree.

Out of scope, flagged: consumers' mutable-v*-tag pinning itself (digest-pinning, GHCR immutability settings) is unchanged.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

🔍 Rendered manifest diff — this PR vs main (desired state)

No changes to the rendered desired state. ✅

@Smana
Smana merged commit 09eab63 into main Oct 3, 2026
17 checks passed
@Smana
Smana deleted the fix/ci-image-build-split branch October 3, 2026 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant