feat(release): MVP — release-please + v1.0.0 manifest + hybrid pin guidance#29
Conversation
Architectural design for cutting v1.0.0 on this repo and migrating consumers from raw-SHA pinning (post #27) to the hybrid pattern @<sha> # v1.0.0. Hybrid is the only strategy that's positive across immutable-execution, readable-diff, Dependabot-friendly, and tag- rewrite-resistant — see comparison table. Key decisions: - Cut v1.0.0 + push floating v1 major; release-please with release-type: simple owns subsequent versioning from Conventional Commits. - Consumers pin @<sha> # v1.0.0; Dependabot rewrites BOTH lines on bump since dependabot-core PR #5951 (2024). - v* tags protected via rulesets (legacy tag-protection-rules deprecated): restrict creation/update/deletion, bypass = repo admins only. - Defines what counts as a "breaking change" for a reusable workflow (inputs/secrets/outputs/permissions/observable side effects). - Honest critique: hybrid wins for our 5-consumer scale; raw @v1 is unacceptable for workflows that handle secrets (tj-actions/changed- files March 2025 incident as reference). Includes: - 8-step one-shot rollout checklist (Conventional Commits adoption → release-please wiring → v1.0.0 cut → floating v1 → ruleset → 5 consumer PRs → Dependabot enablement) - release-please.yml workflow skeleton with floating-v1-tag move step - per-consumer dependabot.yml skeleton with grouped bumps under muntianus-workflows pattern - ongoing release process narrative No automation wired yet — that's the PR after this design lands. https://claude.ai/code/session_01NXqUreamtsrtqYAVBURZY4
There was a problem hiding this comment.
Code Review
This pull request introduces a release strategy document proposing a hybrid pinning approach for reusable workflows to balance security and maintainability. The review feedback correctly identifies three key issues in the proposed configurations: the release-please workflow is missing a checkout step, the tag ruleset bypass list must include GitHub Actions to allow automated tag updates, and the Dependabot group pattern needs to be adjusted to match the repository name correctly.
| steps: | ||
| - uses: googleapis/release-please-action@db8f2c60ee802b3748b512940dde88eabd7b7e01 # v4.4.0 |
There was a problem hiding this comment.
The workflow steps do not clone the repository. Without a cloned repository, the runner's workspace is empty, and the subsequent git tag and git push commands in the Move floating v1 tag step will fail with a not a git repository error.
Please add the actions/checkout step at the beginning of the job, using a SHA-pinned reference to adhere to the repository's security guidelines.
| steps: | |
| - uses: googleapis/release-please-action@db8f2c60ee802b3748b512940dde88eabd7b7e01 # v4.4.0 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: googleapis/release-please-action@db8f2c60ee802b3748b512940dde88eabd7b7e01 # v4.4.0 |
| - Restrict creations (allow only via release-please) | ||
| - Restrict updates | ||
| - Restrict deletions | ||
| - Bypass list: repository admins only, with audit logging. |
There was a problem hiding this comment.
Since the release-please workflow runs automatically in CI and needs to force-push/update the floating v1 tag (which matches the v* pattern), restricting the bypass list to repository admins only will cause the automated workflow to fail when attempting to push the tag.
You should update the bypass list to also allow the GitHub Actions bypass actor (or the specific integration/app used for the workflow) to bypass the ruleset for tag updates.
| - Bypass list: repository admins only, with audit logging. | |
| - Bypass list: repository admins and GitHub Actions (for tag updates), with audit logging. |
| patterns: | ||
| - muntianus/.github/* |
There was a problem hiding this comment.
In Dependabot, the dependency name for a reusable workflow is the repository name (e.g., muntianus/.github), not the full path to the workflow file. Therefore, the pattern muntianus/.github/* will not match the dependency name because of the trailing slash and wildcard.
To have the group correctly match and group updates for these workflows, the pattern should be updated to muntianus/.github.
| patterns: | |
| - muntianus/.github/* | |
| patterns: | |
| - muntianus/.github |
…idance Phase 1 implementation of the release strategy design (PR #29): - `.github/workflows/release-please.yml` — opens release PRs from Conventional Commits, cuts the tag + GitHub Release on merge, and re-points the floating `v1` major tag in lockstep. Action pinned to SHA + version comment per the hybrid pattern this PR establishes. - `version.txt` + `.release-please-manifest.json` — `release-type: simple` source of truth (no language manifests to bump in a workflows-only repo). - `release-please-config.json` — Conventional Commit → changelog section mapping; hides internal sections (ci/docs/chore/refactor/test) from consumer-facing notes. - `CHANGELOG.md` v1.0.0 entry — hand-authored initial release notes documenting the public input/secret/output contract of every reusable workflow shipped (`reusable-ci-go`, `reusable-ci-node`, `reusable-deploy-vps`, `reusable-security-gate`, `openapi-sync`, `claude.yml`). This is the document downstream consumers cite when judging "is this bump safe for me?". - `docs/release/consumer-dependabot.example.yml` — drop-in dependabot.yml for any of the 5 consumer repos. Grouped under `muntianus-workflows` pattern so 5 daily PRs become 1 weekly batch. AGENTS.md updated: - Rule 3 (Reuse over fork) — hybrid pin pattern `@<sha> # v1.0.0` instead of bare SHA, with rationale (tj-actions Mar-2025 incident reference). - Rule 4 (NEW) — Conventional Commits requirement for this repo; definition of "breaking change" for a reusable workflow. What still needs to happen out-of-band after this lands: - Cut the actual `v1.0.0` tag and Release manually (one-time bootstrap; release-please takes over for v1.0.1+). - Push the floating `v1` tag pointing at the same SHA. - Configure a ruleset on `v*` (Restrict creation/update/deletion, bypass = repo admins only) — UI-only, no PR. - 5 consumer PRs swapping current `@<sha>` to `@<sha> # v1.0.0` and enabling `.github/dependabot.yml` per the example file. See `docs/release/v1-strategy.md` for the full rationale, comparison table, and honest critique of when SHA-only vs `@v1` vs hybrid is appropriate. https://claude.ai/code/session_01NXqUreamtsrtqYAVBURZY4
Summary
Closes the audit follow-up tracked in #27's PR body. Migrates this repo from "designed-but-not-implemented" to "live release pipeline + hand-authored v1.0.0 contract".
This PR ships:
docs/release/v1-strategy.md(commit 1).release-pleaseworkflow + v1.0.0 manifest + hand-authored CHANGELOG entry + consumer dependabot example + AGENTS.md guidance bump.What lands
Release automation:
.github/workflows/release-please.yml— opens release PRs from Conventional Commits, cuts tag + GitHub Release on merge, re-points floatingv1major tag in lockstep.googleapis/release-please-actionSHA-pinned with# v4.4.0comment per the hybrid pattern this repo now enforces.version.txt+.release-please-manifest.json+release-please-config.json—release-type: simplesource of truth. No language package manifests to bump in a workflows-only repo.Hand-authored v1.0.0 contract:
CHANGELOG.mddocuments the public input/secret/output contract of every reusable workflow in this release:reusable-ci-go,reusable-ci-node,reusable-deploy-vps,reusable-security-gate,openapi-sync,claude.yml. This is the document downstream consumers cite when judging "is this bump safe for me?".Consumer dependabot template:
docs/release/consumer-dependabot.example.yml— drop-independabot.ymlfor any of the 5 consumer repos. Grouped under themuntianus-workflowspattern so 5 weekly PRs collapse to 1.AGENTS.mdupdates:@<sha> # v1.0.0, withtj-actions/changed-filesMar-2025 as the reference incident.Out-of-band steps after merge (manual, no PR needed)
v1.0.0tag and GitHub Release manually —git tag v1.0.0 && git push origin v1.0.0plus a Release with the CHANGELOG body. One-time bootstrap; release-please takes over from v1.0.1+.v1tag pointing at the same SHA —git tag -f v1 v1.0.0 && git push -f origin v1.v*in Settings → Rules → Rulesets: Restrict creation/update/deletion, bypass = repo admins only. UI-only.@<sha>to@<sha> # v1.0.0and dropping in.github/dependabot.ymlper the example file.Test plan for this PR
release-please.ymllints underactionlint(action SHAs verified)version.txt+.release-please-manifest.jsonmatch (1.0.0)CHANGELOG.mddocuments every workflow currently in this repoinputs:/secrets:block (I worked from the files in.github/workflows/; if I missed an input default, flag it)Follow-up PRs (separate)
Tracked in the design doc:
@<sha>→@<sha> # v1.0.0+ dependabot.yml.https://claude.ai/code/session_01NXqUreamtsrtqYAVBURZY4