ci: emit signed release.json from the release workflow#127
Merged
Conversation
Layers on top of the release workflow (#125) and the release-helper / schema landed in #126. On every semver tag push, the workflow now also: 1. Sets up Go (uses go.mod for version) 2. Builds the release-helper binary (build/release-helper) 3. Runs release-helper with env vars wired from the buildx / metadata step outputs, producing dist/release.json 4. Signs release.json as a blob with cosign keyless (Sigstore OIDC): dist/release.json.sig -- detached signature dist/release.json.crt -- signing certificate dist/release.json.cosign.bundle -- self-contained verification bundle 5. Verifies the blob signature inline as a smoke test 6. Attaches release.json + all three signature artifacts to the GitHub Release alongside the source tarball Wiring details: - IMAGE_DIGEST comes from steps.build.outputs.digest (the multi-arch index digest produced by docker/build-push-action). - IMAGE_ADDITIONAL_TAGS is computed from steps.meta.outputs.tags by excluding the primary `:VERSION` tag and stripping to bare tag-names. - SOURCE_TARBALL_URL is constructed deterministically from the GH Release download URL pattern; SHA256 + size are read from the artifacts produced by the existing "Create source tarball" step. - SIGNING_IDENTITY_REGEX and SIGNING_ISSUER are hard-coded to match the workflow's own OIDC identity, so consumers can derive a verify command from the manifest alone. Verifying release.json on a deployment: cosign verify-blob \ --signature release.json.sig \ --certificate release.json.crt \ --certificate-identity-regexp \ '^https://github.com/Algomation-AI/ProcessGit/\.github/workflows/release\.yml@.*' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ release.json After this lands, tagging v0.1.0 produces: - signed multi-arch image at ghcr.io/algomation-ai/processgit - signed release.json describing the image + signing identity - source tarball + sha256 all as assets of a single GitHub Release. Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slice 2 wiring — emit signed
release.jsonfrom the release workflowFinal piece of the Slice 1 / Slice 2A foundation. Layers cleanly on top of #125 (workflow scaffold) and #126 (release-helper + schema). After this lands, tagging
v0.1.0produces a complete signed release.What this PR adds to
release.yml5 new steps + 4 new release-asset entries:
go-version-file: go.mod→ matches repo's Go 1.25)go buildof the stdlib-only Go tool from Slice 2A: release.json schema + generator +processgit update check#126release-helperwith env vars wired from buildx / metadata step outputsrelease.json.sig(detached signature)release.json.crt(signing certificate)release.json.cosign.bundle(self-contained verification bundle)GitHub Release
files:list extended with all four new artifacts.Verifying
release.jsonon a deploymentcosign verify-blob \ --signature release.json.sig \ --certificate release.json.crt \ --certificate-identity-regexp '^https://github.com/Algomation-AI/ProcessGit/\.github/workflows/release\.yml@.*' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ release.jsonOr, using the self-contained bundle (no separate
.sig/.crtneeded):cosign verify-blob \ --bundle release.json.cosign.bundle \ --certificate-identity-regexp '^https://github.com/Algomation-AI/ProcessGit/\.github/workflows/release\.yml@.*' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ release.jsonWiring details
IMAGE_DIGESTcomes fromsteps.build.outputs.digest(the multi-arch index digest fromdocker/build-push-action)IMAGE_ADDITIONAL_TAGSis computed fromsteps.meta.outputs.tags: drops the primary:VERSIONentry, strips to bare tag names, joins CSVSOURCE_TARBALL_URLis constructed deterministically from the GitHub Release download URL pattern; SHA256 + size are read from the artifacts the existing "Create source tarball" step already producedSIGNING_IDENTITY_REGEXandSIGNING_ISSUERare hard-coded to match the workflow's own OIDC identity, so consumers can derive verification commands from the manifest aloneValidation done
release.ymlvalidatedrelease-helperalready independently validated in Slice 2A: release.json schema + generator +processgit update check#126 (compiles, emits valid JSON, output validates againstrelease.schema.json)Set up Gois early;Build release-helper,Generate release.json, sign, verify all run AFTER the image build (need digest) and AFTER the source tarball (need its sha+size)After this merges → first real release
git checkout main && git pull --ff-onlygit tag -a v0.1.0 -m "ProcessGit v0.1.0 — first release"git push origin v0.1.0Expected workflow output: signed multi-arch image at
ghcr.io/algomation-ai/processgit:0.1.0+ signedrelease.json+ source tarball + auto-generated changelog, all attached to a single GitHub Release.Next slices
processgit update download+apply(binary self-update for bare-metal installs)processgit-updatersidecar for Docker self-update/-/admin/updates