Skip to content

fix(ci): defer release aliases until security gates pass - #1763

Merged
mchmarny merged 4 commits into
mainfrom
fix/defer-release-alias-promotion
Jul 15, 2026
Merged

mchmarny merged 4 commits into
mainfrom
fix/defer-release-alias-promotion

Conversation

@mchmarny

Copy link
Copy Markdown
Member

Summary

Build all seven release images under a run-unique candidate tag, bind downstream security gates to one authoritative digest map, and promote public version/latest aliases only after those gates pass. Keep GitHub releases in draft through promotion and publish Homebrew only after the validated release is public.

Motivation / Context

The release graph previously exposed stable image aliases and the Homebrew formula before image vulnerability and provenance checks completed. This change makes public distribution the final, fail-closed phase and adds deterministic recovery for partial runs.

Fixes: N/A
Related: N/A

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • Build/CI/tooling

Component(s) Affected

  • CLI (cmd/aicr, pkg/cli)
  • API server (cmd/aicrd, pkg/server)
  • Recipe engine / data (pkg/recipe)
  • Bundlers (pkg/bundler, pkg/component/*)
  • Collectors / snapshotter (pkg/collector, pkg/snapshotter)
  • Validator (pkg/validator)
  • Core libraries (pkg/errors, pkg/k8s)
  • Docs/examples (docs/, examples/)
  • Other: tag-release workflows, composite actions, and release policy tests

Implementation Notes

  • Publish all GoReleaser, validator, benchmark, and gate images under candidate-<run-id>-<attempt> first.
  • Resolve one canonical seven-image digest map and scan, generate per-platform SBOMs, and attest exactly linux/amd64 and linux/arm64 for every image.
  • Revalidate every candidate, attestation, immutable version alias, and prior-or-candidate latest state before mutation.
  • Promote and verify all seven immutable version aliases before moving any stable latest alias; prereleases remain version-only.
  • Reject malformed, equal, or newer public stable release history so an older workflow cannot move latest backward.
  • Reuse only an exact GitHub draft identity, allow only expected partial assets, replace stale draft notes/artifacts, require the exact 13-asset set, and publish by validated release ID.
  • Persist the generated Homebrew formula for the full workflow-rerun window and publish only its exact four archive/checksum pairs after the GitHub release is public.
  • Cross-repository alias updates are not transactional. A partial mutation is recovered by rerunning the same tag; the preflight accepts only the recorded prior or current candidate digest for each image.

Testing

GOFLAGS=-mod=vendor go test -count=1 ./tests/releasepolicy/...
GOFLAGS=-mod=vendor go test -count=1 -race ./tests/releasepolicy/...
golangci-lint run -c .golangci.yaml ./tests/releasepolicy/...
shellcheck .github/scripts/release-images.sh .github/scripts/publish-homebrew.sh
actionlint .github/workflows/attest-images.yaml .github/workflows/build-attested.yaml .github/workflows/on-tag.yaml .github/workflows/packaging.yaml
yamllint .github/workflows/attest-images.yaml .github/workflows/build-attested.yaml .github/workflows/on-tag.yaml .github/workflows/packaging.yaml .github/actions/attest-image-from-tag/action.yml .github/actions/go-build-release/action.yml .github/actions/sbom-and-attest/action.yml .goreleaser.yaml
goreleaser release --snapshot --clean --config .goreleaser.yaml --skip=ko --timeout 20m
./tools/check-docs-mdx
(cd fern && fern check)
lychee --offline --no-progress 'docs/**/*.md'
make test-coverage
unset GITLAB_TOKEN && make qualify

All blocking checks passed. Project coverage is 78.8% against the 75% floor; the new Go package contains policy tests only, with no production statements or exported APIs. GoReleaser 2.17 validates the configuration but its standalone check command retains the existing exit-2 warning for the deprecated brews property; the tokenless snapshot build succeeds and produces the expected archives, SBOMs, checksum, and Homebrew formula.

Risk Assessment

  • Low — Isolated change, well-tested, easy to revert
  • Medium — Touches multiple components or has broader impact
  • High — Breaking change, affects critical paths, or complex rollout

Rollout notes: Applies to the next tag release without migration. Revert only before a release starts. If alias promotion is partially complete, fix the candidate path and rerun the same tag so the idempotent checks converge; do not manually repoint latest or Homebrew.

Checklist

  • Tests pass locally (make test with -race)
  • Linter passes (make lint)
  • I did not skip/disable tests to make CI green
  • I added/updated tests for new functionality
  • I updated docs if user-facing behavior changed
  • Changes follow existing patterns in the codebase
  • Commits are cryptographically signed (git commit -S) — GPG signing info
@mchmarny
mchmarny requested review from a team as code owners July 15, 2026 05:46
@mchmarny mchmarny added the theme/supply-chain SLSA, SBOM, Sigstore, and provenance verification label Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor
@github-actions

github-actions Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

Coverage Report ✅

Metric Value
Coverage 79.5%
Threshold 75%
Status Pass
Coverage Badge
![Coverage](https://img.shields.io/badge/coverage-79.5%25-green)

Coverage unchanged by this PR.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 6284f2fe-fd8b-4397-84c3-b23a2a26c8fb

📥 Commits

Reviewing files that changed from the base of the PR and between 5e380ca and 92b6977.

📒 Files selected for processing (17)
  • .github/actions/README.md
  • .github/actions/attest-image-from-tag/action.yml
  • .github/actions/go-build-release/action.yml
  • .github/actions/release-input-validation.sh
  • .github/actions/sbom-and-attest/action.yml
  • .github/scripts/publish-homebrew.sh
  • .github/scripts/release-images.sh
  • .github/workflows/attest-images.yaml
  • .github/workflows/build-attested.yaml
  • .github/workflows/on-tag.yaml
  • .github/workflows/packaging.yaml
  • .goreleaser.yaml
  • RELEASING.md
  • docs/contributor/validator.md
  • tests/releasepolicy/doc.go
  • tests/releasepolicy/release_scripts_test.go
  • tests/releasepolicy/release_workflow_test.go

📝 Walkthrough

Walkthrough

The release pipeline now uses run-unique candidate tags and authoritative digest maps for scanning, attestation, promotion, and publication. Composite actions validate inputs before execution, SBOM generation covers both Linux platforms, and release scripts enforce image, release, asset, alias, and Homebrew integrity. Workflows, documentation, and comprehensive Go tests cover rerun safety and fail-closed promotion behavior.

Estimated code review effort: 5 (Critical) | ~120 minutes

Suggested labels: area/security, theme/validation

Suggested reviewers: ayuskauskas, yuanchen8911

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: deferring release aliases until security gates pass.
Description check ✅ Passed The description is directly related to the PR and accurately summarizes the release sequencing and gating changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/defer-release-alias-promotion

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]

This comment was marked as resolved.

@mchmarny mchmarny self-assigned this Jul 15, 2026
@mchmarny
mchmarny force-pushed the fix/defer-release-alias-promotion branch from 99bef9a to 5e380ca Compare July 15, 2026 12:02

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/actions/README.md:
- Around line 166-174: Add blank lines around the sbom-and-attest section
heading and the fenced YAML example in the README, ensuring the heading and code
fence are each separated from surrounding content to satisfy Markdown formatting
rules MD022 and MD031.

In @.github/actions/sbom-and-attest/action.yml:
- Around line 64-86: Update both Generate amd64 SBOM and Generate arm64 SBOM
configurations to set upload-release-assets explicitly to the intended boolean
value true instead of auto. Leave the remaining sbom-action inputs unchanged.

In @.github/workflows/on-tag.yaml:
- Around line 157-205: Move the security-sensitive Homebrew artifact naming,
validation, filesystem staging, and upload logic from the workflow steps “Name
Homebrew artifact,” “Stage Homebrew formula,” and “Upload Homebrew formula” into
a reusable Layer-2 composite. Apply the same extraction to the related manifest,
SSH setup, and Git mutation blocks, leaving Layer 3 responsible only for
orchestration; add an inline rationale comment wherever narrowly scoped logic
intentionally remains inline.

In `@RELEASING.md`:
- Around line 187-189: Update the promoted public tags statement in RELEASING.md
to include prerelease version aliases such as vX.Y.Z-rc… alongside latest and
stable vX.Y.Z, matching the release workflow behavior described earlier. Keep
the existing explanation of retained candidate tags unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: f2c7165c-258c-4351-9d19-f2050f2bfd55

📥 Commits

Reviewing files that changed from the base of the PR and between b30bfda and 5e380ca.

📒 Files selected for processing (17)
  • .github/actions/README.md
  • .github/actions/attest-image-from-tag/action.yml
  • .github/actions/go-build-release/action.yml
  • .github/actions/release-input-validation.sh
  • .github/actions/sbom-and-attest/action.yml
  • .github/scripts/publish-homebrew.sh
  • .github/scripts/release-images.sh
  • .github/workflows/attest-images.yaml
  • .github/workflows/build-attested.yaml
  • .github/workflows/on-tag.yaml
  • .github/workflows/packaging.yaml
  • .goreleaser.yaml
  • RELEASING.md
  • docs/contributor/validator.md
  • tests/releasepolicy/doc.go
  • tests/releasepolicy/release_scripts_test.go
  • tests/releasepolicy/release_workflow_test.go
Comment thread .github/actions/README.md
Comment thread .github/actions/sbom-and-attest/action.yml Outdated
Comment thread .github/workflows/on-tag.yaml
Comment thread RELEASING.md Outdated
Signed-off-by: Mark Chmarny <mark@chmarny.com>
@mchmarny
mchmarny force-pushed the fix/defer-release-alias-promotion branch from 5e380ca to 92b6977 Compare July 15, 2026 12:31

@ArangoGutierrez ArangoGutierrez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found — checked for bugs and CLAUDE.md compliance.

@mchmarny
mchmarny enabled auto-merge (squash) July 15, 2026 14:50
@mchmarny
mchmarny merged commit 2e0bc38 into main Jul 15, 2026
42 checks passed
@mchmarny
mchmarny deleted the fix/defer-release-alias-promotion branch July 15, 2026 15:20
mohityadav8 pushed a commit to mohityadav8/aicr that referenced this pull request Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ci area/docs area/tests size/XL theme/supply-chain SLSA, SBOM, Sigstore, and provenance verification

2 participants