Repository navigation
Tags: stacklet/github-tooling
Tags
chore: share the release workflow and cut releases here (ENG-9233) (#3) [ENG-9233](https://stacklet.atlassian.net/browse/ENG-9233) ### what Adds `cut-release.yml`, a `workflow_call` workflow that works out the next version from the tag history and publishes a GitHub release for it. It is the release workflow from `terraform-azure-stacklet-cost-setup`, lifted so the other five module repositories call it instead of copying it. Adds `release.yml`, the dispatch caller, so this repository cuts its own releases down the same path the module repositories will. Documents `cut-release` in the README beside `run-script`, with the caller block to copy. ### why Five Terraform module repositories have no release workflow, and the sixth already had this one. Copying it five more times leaves six sets of the same guards to keep in step. The guards are the part worth sharing, because a published release is immutable and a slip in one cannot be taken back. The lift departs from the original in four places. 1. The `bump` input is a string rather than a choice, because `workflow_call` has no choice type. A new step rejects anything but patch, minor, or major. Without it the tag action reads an unrecognised `force_bump` as no bump, falls back to the commit messages, and publishes a version nobody asked for. 2. The branch guard compares against the calling repository's default branch rather than the literal `main`, so it holds for a caller whose default branch has another name. 3. The version job gains the Harden Runner step `run-script` already uses. That job fetches and runs a third-party action, while the publish job runs nothing but `gh`. 4. The run claims the tag with `POST git/refs` before creating the release, rather than letting `gh release create` make it. The old order answers a name taken in the gap by releasing the tag that is there and ignoring `--target`, which publishes an immutable release against a commit nobody chose. An `EXIT` trap removes the ref if the release call then fails, so a retry still works out the same number. It is armed before the write rather than after, which is safe because the cleanup confirms the tag is this run's before deleting it. Raised by cubic on this PR. The caller keeps the `workflow_dispatch` trigger and the `concurrency` group. Both matter only on the workflow a person dispatches, and a called workflow cannot serialise its caller. ### testing - [x] `just lint` passes. - [x] `uvx zizmor@1.23.1 -v --gh-token=... .github/workflows/` reports no findings, with the five online audits scheduled rather than skipped. - [x] Each action pin resolves to a commit via `gh api repos/<owner>/<repo>/commits/<sha>`. - [x] Ran the publish step against a stubbed `gh` on ten paths: a clean publish leaves the tag, a failing release call deletes it, both refusal paths create nothing, a tag someone else holds survives the pre-check and the claim whether it sits on this commit or another, and neither a release that landed while the client died nor a failing release lookup loses its tag. A tag moved after the claim survives. A run killed before it records the claim leaves the tag, which is the deliberate side of that trade. - [x] Ran the bump check against `patch`, `minor`, `major`, `Major`, `PATCH`, empty, `majorly`, and `patch minor`, accepting only the three lowercase values. - [ ] After merge, dispatch Release on `main` with dry run checked, and confirm the summary reports `v0.0.0` as previous and `v1.0.0` as new. - [ ] Dispatch Release with a `major` bump and confirm `v1.0.0` is published against the dispatched commit. ### docs The README gains a `cut-release` section under Reusable workflows. The pinning note at the top no longer says this repository publishes no release tags, because after this it does. [ENG-9233]: https://stacklet.atlassian.net/browse/ENG-9233?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>