Cutting a release¶
Maintainer notes for immutable, ordered publication (US-RELEASE-1). Ordinary
pushes never release — only an annotated or lightweight v* tag does.
Policy¶
- Order — build then publish.
.github/workflows/release.ymlexports and validates PDFs + the offline site zip in thebuildjob, then thepublishjob creates the GitHub Release. Publish cannot run withoutneeds: build, andfail_on_unmatched_files: truerefuses a Release with missing artifacts. - Immutability — tags never move. A release tag names one commit forever.
Do not
git tag -f/ force-push a publishedv*tag. The publish job runsscripts/release-tag-guard.sh, which allows same-commit retries (idempotent) and refuses when the remote tag or GitHub Release already points at a different commit. API lookup failures (rate-limit, 5xx, auth) fail closed asunknown— they never green-light publish. Annotated tags are peeled to the commit SHA; a peel failure is alsounknown(never compared against the tag-object SHA). Limit: the CI guard cannot stop a force-pushed tag whose tip already equalsgithub.sha— after a force-move to the commit being published, the check looks idempotent. Enforce tag immutability with GitHub branch/tag protection or a ruleset that blocks force-pushes tov*; do not treat the workflow alone as a hard immutability boundary. - Provenance. Every exported deck stamps
VITE_WORKSHOP_VERSION(the tag) andVITE_WORKSHOP_SHA(the tagged commit) into the slide chrome. - Permissions. Workflow default +
buildusecontents: read. Onlypublishgetscontents: write.
What a release ships¶
| Artifact | Source |
|---|---|
kubernetes-workshop-day-{1,2,3}-<tag>.pdf |
Live Day 1/2/3 entry decks |
kubernetes-workshop-full-<tag>.pdf |
Compatibility superset (slides.md) |
kubernetes-workshop-3day-<tag>.pdf |
Compatibility combined cut |
kubernetes-workshop-site-<tag>.zip |
Offline HTML bundle of the release-time deck export (compatibility layout; see release notes). Live docs+decks on Pages use / + /deck/… instead. |
Pre-release tags (name contains -, e.g. v0.2.0-beta.1) set
prerelease: true and prepend beta-limitations.md
(known limitations). Stable tags such as v0.4.0 publish a normal Release.
How to cut¶
Before you tag (checklist)¶
- [ ]
maintip is the commit you intend, and CI is green for that tip. - [ ] Re-verify statuses on the public
roadmap.mdpage (in progress/planned/exploring) against what is actually onmain— no dates, no commitment language, nothing listed as shipped that is not merged. Update the page in the same release window if anything drifted.
# Confirm main is the commit you intend (and CI is green for that tip).
git checkout main && git pull --ff-only
# Optional local preflight (needs gh auth); dry-run prints the decision only.
bash scripts/release-tag-guard.sh check --dry-run v1.2.0 "$(git rev-parse HEAD)"
git tag v1.2.0 # stable
# git tag v0.3.0-beta.1 # pre-release
git push origin v1.2.0 # → Release workflow
If the guard refuses, do not move the tag. Cut a new version or investigate why the existing tag/release points elsewhere.
Out of scope here¶
The workshop-web container image (workshop-web.yml) is a separate pipeline
with its own digest/alias rules. This document covers GitHub Release
PDF/site publication only.