diff --git a/.github/release_template.md b/.github/release_template.md new file mode 100644 index 00000000..7f5a07e3 --- /dev/null +++ b/.github/release_template.md @@ -0,0 +1,37 @@ +## Highlights + + + +## What's changed + +### Added +- + +### Changed +- + +### Fixed +- + +## Breaking changes and upgrade notes + + + +## Security + + + +## Release artifacts and verification + +- Release: +- Checksums: +- Signatures and provenance: +- Post-release smoke checks: + +## Known issues + + + +## Acknowledgments + + diff --git a/.github/workflows/release-cli.yml b/.github/workflows/release-cli.yml index 108f7130..98463a85 100644 --- a/.github/workflows/release-cli.yml +++ b/.github/workflows/release-cli.yml @@ -11,6 +11,7 @@ on: permissions: contents: read id-token: write + attestations: write jobs: build: @@ -71,6 +72,11 @@ jobs: binary="dist/release/gasguard-${{ matrix.asset }}${{ matrix.target == 'win-x64' && '.exe' || '' }}" cosign sign-blob --yes --bundle "${binary}.sigstore.json" "$binary" + - name: Attest executable provenance + uses: actions/attest-build-provenance@v2 + with: + subject-path: dist/release/gasguard-${{ matrix.asset }}${{ matrix.target == 'win-x64' && '.exe' || '' }} + - name: Upload signed executable uses: actions/upload-artifact@v4 with: @@ -99,4 +105,59 @@ jobs: with: files: release-assets/* env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + release-smoke: + name: Smoke-test ${{ matrix.asset }} release binary + if: github.event_name == 'release' + needs: attach-release-assets + runs-on: ${{ matrix.runner }} + permissions: + contents: read + attestations: read + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-latest + asset: linux-x64 + binary: gasguard-linux-x64 + - runner: macos-15-intel + asset: macos-x64 + binary: gasguard-macos-x64 + - runner: macos-14 + asset: macos-arm64 + binary: gasguard-macos-arm64 + - runner: windows-latest + asset: windows-x64 + binary: gasguard-windows-x64.exe + defaults: + run: + shell: bash + steps: + - name: Download published binary + env: + GH_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + BINARY_NAME: ${{ matrix.binary }} + run: | + mkdir -p "$RUNNER_TEMP/release" + gh release download "$RELEASE_TAG" \ + --repo "$GITHUB_REPOSITORY" \ + --pattern "$BINARY_NAME" \ + --dir "$RUNNER_TEMP/release" + + - name: Verify build provenance + env: + GH_TOKEN: ${{ github.token }} + BINARY_NAME: ${{ matrix.binary }} + run: gh attestation verify "$RUNNER_TEMP/release/$BINARY_NAME" --repo "$GITHUB_REPOSITORY" + + - name: Run release binary smoke checks + env: + BINARY_NAME: ${{ matrix.binary }} + run: | + binary="$RUNNER_TEMP/release/$BINARY_NAME" + chmod +x "$binary" + "$binary" --help + "$binary" version \ No newline at end of file diff --git a/docs/RELEASE_ARTIFACT_POLICY.md b/docs/RELEASE_ARTIFACT_POLICY.md index 2cbe5a28..1a2b04ea 100644 --- a/docs/RELEASE_ARTIFACT_POLICY.md +++ b/docs/RELEASE_ARTIFACT_POLICY.md @@ -6,10 +6,38 @@ Temporary artifacts produced by release workflows are retained for 90 days. The Temporary workflow artifacts are for verification and recovery during the release window; they are not the archival copy of a release. +The CLI release workflow also publishes Sigstore signature bundles and GitHub +build-provenance attestations for each standalone platform executable. The +workflow grants `id-token: write` and `attestations: write` only so the build +job can create these attestations. Release smoke jobs use read-only +`contents` and `attestations` permissions. + ## Published Release Assets Files attached to a published GitHub Release remain available for as long as that release exists. GasGuard does not automatically delete or expire published release assets. Repository maintainers handle release deletion or replacement through the normal release process. +### Verify CLI provenance + +With GitHub CLI authenticated and the release asset downloaded, verify the +artifact against the repository's GitHub-hosted attestation: + +```bash +gh attestation verify ./gasguard-linux-x64 --repo MDTechLabs/GasGuard +``` + +Use the matching platform executable path for other releases. The +`release-smoke` job runs this verification and executes `--help` and `version` +against each published platform binary. It requires GitHub Releases assets, +GitHub artifact attestations, the Actions `attestations: write` permission for +the build, and a runner with GitHub CLI available. + ## Dependencies and Troubleshooting -This policy relies on GitHub Actions artifact retention and GitHub Releases storage. If an Actions artifact expires, retrieve the corresponding SBOM from the published release assets. If release assets are unavailable, verify the release was published and that the workflow had `contents: write` permission. \ No newline at end of file +This policy relies on GitHub Actions artifact retention, GitHub Releases +storage, GitHub artifact attestations, and GitHub CLI verification. If an +Actions artifact expires, retrieve the corresponding SBOM from the published +release assets. If assets are unavailable, verify the release was published +and that the workflow had `contents: write` permission. If attestation +verification fails, do not treat the binary as verified; check that it came +from the expected repository and release, and inspect the workflow run and +attestation permissions before republishing. \ No newline at end of file diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index a7d1c2ff..082b728c 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -1,10 +1,10 @@ # Public Release Checklist -This is the checklist every GasGuard release runs through before it ships. -Copy the [Checklist](#checklist) section into the release PR or tracking -issue, check items off with a link to the evidence (CI run, dashboard -screenshot, doc), and do not tag the release until every box is checked and -every sign-off is recorded. +This is the checklist every GasGuard release runs through. Copy the +[Checklist](#checklist) section into the release PR or tracking issue and check +items off with links to evidence (CI run, dashboard, or document). Complete all +pre-release checks and record every sign-off before tagging; complete the +post-release section after publication. For the one-time mainnet launch specifically, also see [PRODUCTION_READINESS_REVIEW.md](PRODUCTION_READINESS_REVIEW.md), which @@ -69,7 +69,29 @@ No release ships until every row below is filled in by the named person, not on | Operations / on-call | | | | | Release manager (final go) | | | | +### 7. Post-release verification + +Complete these checks after publication and record the evidence in the release +tracking issue. A failure requires a release-manager decision on remediation, +rollback, or a corrected release. + +- [ ] `CLI Release Builds` completed and all expected platform binaries and + Sigstore signature bundles are attached to the release +- [ ] `release-smoke` passed for Linux x64, macOS x64, macOS arm64, and Windows + x64; the published binaries' `--help` and `version` commands both ran +- [ ] GitHub build provenance attestations can be verified for each published + CLI executable; see [RELEASE_ARTIFACT_POLICY.md](RELEASE_ARTIFACT_POLICY.md) +- [ ] Release SBOM workflow completed and its expected SBOM files are attached +- [ ] Published announcement is accurate, links to the release and relevant + upgrade/security notes, and contains no secrets or private production data +- [ ] Production health checks, error rates, and service metrics are normal + after deployment; record the observation window and dashboard or CI evidence +- [ ] Any regression, failed smoke check, or unexpected operational signal has + an owner and tracked follow-up; escalate rollback decisions to the release + manager + ## Notes - This checklist is intentionally generic so it applies to every release, not just the first mainnet launch. Update it as new CI jobs or operational tooling are added — if a checklist item's evidence source moves or is renamed, fix the link here in the same PR. -- If any box can't be checked, the release does not proceed until it's fixed or the release manager explicitly accepts the risk in writing in the sign-off table. +- If any pre-release box can't be checked, the release does not proceed until it's fixed or the release manager explicitly accepts the risk in writing in the sign-off table. +- Post-release checks are necessarily completed after publication; keep the release under active observation until those checks and any required decisions are recorded.