Principles:
- •Release from a clean, tagged source of truth (tags/releases)
- •Use least privilege and environments for production publishing
- •Prefer OIDC + GitHub artifact attestations for provenance
- •Make releases reproducible and auditable
Checklist:
- •Release trigger model
- •Choose one:
- •
on: push: tags: ['v*'](tag-driven releases) - •
on: release: types: [published](GitHub Release as source of truth) - •
workflow_dispatchfor manual/promoted releases
- •
- •Ensure tag naming/versioning policy is explicit (SemVer or repo standard)
- •Ensure the workflow is deterministic across reruns (same inputs => same outputs)
- •Build stages (separate concerns)
- •Split into jobs/stages:
- •build & test (no publishing permissions)
- •package (creates artifacts)
- •attest (provenance + SBOM)
- •publish (GitHub Release / Packages / external registries)
- •Keep publishing credentials isolated to the publish job only
- •Artifact production
- •Produce release artifacts (zip, container image, NuGet/npm packages, etc.)
- •Store as workflow artifacts for attestation + later publishing
- •Record checksums (sha256) for key artifacts
- •Provenance attestation (GitHub attestations)
- •Use
actions/attest-build-provenanceto generate signed provenance for built artifacts - •Ensure the attesting job has:
- •
permissions: id-token: write - •
permissions: attestations: write - •minimal
contentspermission as required (oftenread)
- •
- •SBOM generation + attestation
- •Generate SBOM for artifacts (SPDX JSON or CycloneDX JSON)
- •Use tooling appropriate to your ecosystem (.NET, Node, containers)
- •Use
actions/attest-sbomto generate signed SBOM attestations - •Keep SBOM generation deterministic and tied to the exact built artifact digest
- •Publishing & release notes
- •Publish artifacts:
- •GitHub Release assets (preferred default distribution channel)
- •GitHub Packages / external registries only if needed
- •Use environments for prod publishing (required reviewers, protected secrets)
- •Generate release notes from commits/PRs if repo uses that convention
- •Include migration notes (DB/schema), feature flags, and rollback notes
- •Guardrails
- •Set explicit
permissions:everywhere (no implicit broad permissions) - •Pin third-party actions to commit SHA
- •Add
concurrencyfor release runs to avoid parallel publishes - •Add
timeout-minuteson publish/attest steps - •Ensure the pipeline fails if tests fail (no “continue-on-error” on critical steps)
Finish with:
- •Release workflow outline (triggers + jobs + permissions per job)
- •What is attested (which artifacts + where to find/verifiy attestations)
- •What is published (channels + names + versioning)
- •Any prerequisites (environments, OIDC, required secrets, branch protection)