laywill / laywill/laywill.github.io
Protect released v* tags with a tag ruleset
Nobody has claimed this yet.
- Dominant language
- HTML
- Stars
- 0
- Forks
- 0
- Avg merge
- 8h 17m
- Merged PRs (30d)
- 58
Description
Problem
v* tags are now the only path to a production deploy (#52), but nothing makes
a released tag immutable. There is no tag ruleset on this repo — the only
ruleset is Protect main, which targets branches.
So after v2.0.0 has built, passed every gate and deployed, the tag can be
deleted and re-pushed at a different commit:
git tag -d v2.0.0 && git push origin :refs/tags/v2.0.0
git tag v2.0.0 <any-commit> && git push origin v2.0.0
That re-runs the whole pipeline and deploys the new commit under a version
number that already means something else. The release history stops being a
record of what was shipped, and the github-pages environment's v* tag policy
happily allows it because the ref name is unchanged.
Proposed fix
Add a repository ruleset targeting tags:
- Target: tag, include pattern
v* - Rules:
deletion(block tag deletion),non_fast_forward(block force
updates) - Enforcement: active, no bypass actors
gh api repos/laywill/laywill.github.io/rulesets \
-X POST \
-f name='Protect release tags' \
-f target='tag' \
-f enforcement='active' \
-f 'conditions[ref_name][include][]=refs/tags/v*' \
-f 'conditions[ref_name][exclude][]' \
-f 'rules[][type]=deletion' \
-f 'rules[][type]=non_fast_forward'
Worth confirming the resulting conditions.ref_name.include reads back as
refs/tags/v* with no stray quote characters — a literal-quote pattern silently
matches nothing, which is how the github-pages tag policy and the main entry
in Protect main were both broken on first attempt.
Trade-off
Mistyped or premature tags become unfixable in place; the recovery is to burn the
version and tag the next one. That is the normal cost of immutable releases and
is cheap here — pre-release tags (v2.0.0-rc.N) run the full pipeline and skip
deploy, so a candidate can be exercised before the real tag is cut.
Acceptance criteria
- Tag ruleset exists, active, matching
refs/tags/v* -
git push origin :refs/tags/<test-tag>is rejected for av*tag - Force-updating an existing
v*tag is rejected - Non-
v*tags are unaffected
Related
- #25, #52 — the tag-gated release pipeline this protects
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the repository rulesets API and the provided gh api command, then inspect the existing Protect main ruleset for comparison. Create an active tag ruleset matching refs/tags/v*, and verify its ref pattern has no stray quotes. Done means deletion and force updates of v* tags are rejected while non-v* tags remain unaffected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, github
- Domain
- release
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100