Skip to content

ci: release per-target archives with one checksum file and provenance - #4

Open
Patel230 wants to merge 2 commits into
mainfrom
ci/release-artifacts
Open

Patel230 wants to merge 2 commits into
mainfrom
ci/release-artifacts

Conversation

@Patel230

Copy link
Copy Markdown
Contributor

Summary

Adds the tag-triggered release workflow from the chore/phase-zero-trust working tree, held back into its own PR as the audit recommended. Two commits: the owner's draft exactly as written, then the fix, so the change is reviewable against the draft.

The draft built identically named outputs on three runners (dist/across, dist/across-agent-*, dist/SHA256SUMS, dist/go-modules.json, dist/sbom.spdx.json) and merged them with merge-multiple: true into one dist/, so the release would have carried one unlabeled binary of unknown OS and a SHA256SUMS that did not match the attachments. It also ran with a workflow-wide contents: write token and tag-pinned actions (two third-party), installed an unused Node toolchain, and relied on sha256sum on macOS.

The fixed workflow:

  • checks that the tag equals VERSION and across version before building;
  • runs the test suite, then builds one archive per tested target: across_<version>_linux_amd64.tar.gz (ubuntu-latest) and across_<version>_darwin_arm64.tar.gz (macos-latest), each containing across, the nine across-agent-* binaries, LICENSE, README and CHANGELOG. Windows is compile-only in CI and is not released;
  • computes one SHA256SUMS in the publish job over the archives, the module inventory and a single SPDX SBOM, and attests build provenance for exactly those subjects (actions/attest-build-provenance);
  • scopes contents: write, id-token: write and attestations: write to the publish job only; pins every action to a commit SHA; pins syft; disables the SBOM action's own artifact/release uploads; checks out without persisted credentials; disables build cache for release builds;
  • creates a draft pre-release, so a maintainer reviews the assets before publishing.

Findings addressed

  • F048 — colliding release artifacts and a checksum file that could not match: per-target archive names, single checksum file computed after download.
  • F247 (release half; reproduced from source: permissions: contents: write at workflow level, actions/checkout@v4, actions/setup-go@v5, actions/setup-node@v4, anchore/sbom-action@v0, actions/upload-artifact@v4, actions/download-artifact@v4, softprops/action-gh-release@v2, no signature/attestation) — SHA pins, job-scoped write permissions, provenance attestation over SHA256SUMS.

Not reproduced / deferred

  • The workflow has not run on a real tag (no tags were pushed, per campaign rules). Test it with a pre-release tag before relying on it.

Verification

Command Result
actionlint .github/workflows/release.yml (v1.7.12) clean (an initial SC2012 ls-count warning was fixed with a bash array)
Tag/version step locally with GITHUB_REF_NAME=v0.0.1 version ok: 0.0.1 / 0.0.1; v9.9.9 detected as a mismatch
Build-and-package step locally (darwin/arm64, go1.26.6) produced across_0.0.1_darwin_arm64.tar.gz containing across, the nine across-agent-* binaries, LICENSE, README.md, CHANGELOG.md
Pinned SHAs resolved with gh api repos/<action>/git/ref/tags/<tag> (annotated anchore/sbom-action tag dereferenced to its commit)

Follow-ups

  • Push a pre-release tag (for example v0.0.2-rc.1 after VERSION is bumped) to exercise the workflow end to end, then decide whether to keep drafts.
  • Add Windows (and darwin/amd64) archives only after those targets are tested in CI.

🤖 Generated with Claude Code

across added 2 commits September 27, 2026 04:40
Owner's draft from the phase-zero-trust working tree, committed as
written so the follow-up fix is reviewable against it.
The draft release workflow built identically named
binaries, SHA256SUMS and SBOMs on three runners and merged them into one
directory, so the release would have carried one unlabeled binary of
unknown OS and a checksum file that did not match the attachments. It
also ran with a workflow-wide contents:write token and mutable action
tags, including two third-party actions.

This version:
- verifies the tag equals VERSION and `across version` before building
- runs the test suite, then builds and packages one archive per tested
  target (across_<version>_<goos>_<goarch>.tar.gz for linux/amd64 and
  darwin/arm64); Windows is compile-only in CI and is not released
- computes a single SHA256SUMS in the publish job over the archives,
  the module inventory and one SPDX SBOM, and attests build provenance
  for exactly those subjects
- scopes contents:write/id-token/attestations to the publish job,
  pins every action to a commit SHA, pins syft, disables the SBOM
  action's own uploads, and checks out without persisted credentials
- creates a draft pre-release so a maintainer reviews it before
  publishing
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