Tag-driven service container release #16

Closed
opened 2026-06-12 20:27:51 +00:00 by james · 0 comments
Owner

Scope

  • When a tag matching v*.*.* is pushed, build the service image and publish to the Forgejo container registry on forge.wynning.tech.
  • Tag the image with both vX.Y.Z and latest; latest only for stable releases (no -rc, -beta, etc.).
  • Generate release notes from the commit range since the previous tag and attach them to the Forgejo release.

Supply-chain hardening for the release artifact

The released image is the artifact a self-hoster pulls and trusts. The three items below are the release-pipeline half of the supply-chain story; the PR-time half lives in #44, #45, #46.

  • Pin the container base image by digest, not tag. node:22-slim becomes node:22-slim@sha256:… in the Dockerfile so the image we publish is bit-for-bit derived from the base we tested. Renovate (#44) keeps the digest fresh; humans review the bump.
  • Sign and attest released images with cosign and a SLSA provenance attestation. The attestation describes the workflow run, source commit, builder image, and inputs. Publish the public key in the repo and document the cosign verify / cosign verify-attestation command in the release notes so self-hosters can verify before pulling.
  • Lockfile policy at release time. The release build runs npm ci against the exact package-lock.json in the commit being released — no floating-range resolution at release time. The lockfile itself is maintained under the lockfile-only Renovate policy from #44, so what built green CI is what builds the released image.

Acceptance criteria

  • git tag v0.1.0 && git push --tags produces a published image and a Forgejo release page with notes.
  • The pulled image runs with no manual post-pull tweaks.
  • Dockerfile pins the base image by digest, not by tag.
  • Published images carry a cosign signature and a SLSA provenance attestation. The verification command appears in the release notes and works against the published image.
  • The release workflow uses npm ci (lockfile-strict) and fails if package-lock.json is out of sync with package.json.

Part of epic #2. Depends on #9, #13. Coordinates with #44 (Renovate keeps the base-image digest fresh and enforces the lockfile-only update policy this release flow relies on).

## Scope - When a tag matching `v*.*.*` is pushed, build the service image and publish to the Forgejo container registry on `forge.wynning.tech`. - Tag the image with both `vX.Y.Z` and `latest`; `latest` only for stable releases (no `-rc`, `-beta`, etc.). - Generate release notes from the commit range since the previous tag and attach them to the Forgejo release. ### Supply-chain hardening for the release artifact The released image is the artifact a self-hoster pulls and trusts. The three items below are the release-pipeline half of the supply-chain story; the PR-time half lives in #44, #45, #46. - **Pin the container base image by digest, not tag.** `node:22-slim` becomes `node:22-slim@sha256:…` in the Dockerfile so the image we publish is bit-for-bit derived from the base we tested. Renovate (#44) keeps the digest fresh; humans review the bump. - **Sign and attest released images** with cosign and a SLSA provenance attestation. The attestation describes the workflow run, source commit, builder image, and inputs. Publish the public key in the repo and document the `cosign verify` / `cosign verify-attestation` command in the release notes so self-hosters can verify before pulling. - **Lockfile policy at release time.** The release build runs `npm ci` against the exact `package-lock.json` in the commit being released — no floating-range resolution at release time. The lockfile itself is maintained under the lockfile-only Renovate policy from #44, so what built green CI is what builds the released image. ## Acceptance criteria - [ ] `git tag v0.1.0 && git push --tags` produces a published image and a Forgejo release page with notes. - [ ] The pulled image runs with no manual post-pull tweaks. - [ ] `Dockerfile` pins the base image by digest, not by tag. - [ ] Published images carry a cosign signature and a SLSA provenance attestation. The verification command appears in the release notes and works against the published image. - [ ] The release workflow uses `npm ci` (lockfile-strict) and fails if `package-lock.json` is out of sync with `package.json`. Part of epic #2. Depends on #9, #13. Coordinates with #44 (Renovate keeps the base-image digest fresh and enforces the lockfile-only update policy this release flow relies on).
james closed this issue 2026-06-17 14:02:30 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
james/carol#16
No description provided.