Skip to content

Commit 745d3d9

Browse files
wormeymanclaude
andauthored
chore(renovate): automerge GitHub Action digest re-pins, and only those (#62) (#65)
A digest re-pin moves a SHA and the `# vX.Y.Z` comment beside it, together, and there is nothing else in the diff to read. It also recurs forever. Reviewing it by hand teaches nobody anything and trains the habit of skimming bot PRs, which is worse than automating the boring case. Renovate has one queued already. **Why this is safe now and was not this morning.** Ruleset `EJ` makes `verify` a required check on `main` with no bypass actors AND `strict_required_status_checks_policy: true`, so an automerged PR can neither land red nor land having been tested against a different `main` than the one it merges into. Both had to be true. The strict flip arrived last (#60) and was the actual blocker - it is the specific objection recorded against doing this earlier. The rule is therefore NOT independently safe, and both the config and CLAUDE.md now say so: if bypass actors are added, `verify` dropped, or strict turned off, this rule must be removed in the same change. `platformAutomerge` hands the merge to GitHub's auto-merge so the required check gates it, rather than Renovate polling and merging itself. Everything else stays manual under the global `automerge: false`. The reason is on the record rather than a preference: `verify` proves the repo is CONSISTENT, not that a bump is CORRECT. pako 3.0.0 flipped `legacyHash` to false, which passes a green suite while silently breaking the codec's byte-exactness, and the wrong belief that produced survived about a year. Also corrects CLAUDE.md, which still said branch protection was not configured, and records that it is a RULESET - `gh api .../branches/main/protection` returns 404 for a protected branch here, which reads like "unprotected" and is not. Claude-Session: https://claude.ai/code/session_01F3a2HLJ4beKARi7SPmaM54 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 7c553f1 commit 745d3d9

2 files changed

Lines changed: 66 additions & 2 deletions

File tree

.github/renovate.json5

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,42 @@
100100

101101
packageRules: [
102102
{
103+
// The ONE automerge exception (#62), and it is narrow on purpose.
104+
//
105+
// Why this category and nothing else: a digest re-pin moves a SHA and the
106+
// `# vX.Y.Z` comment beside it, together, and there is nothing else in the
107+
// diff to read. It also recurs forever. Reviewing it by hand teaches
108+
// nobody anything and trains the habit of skimming bot PRs, which is worse
109+
// than automating the boring case.
110+
//
111+
// Why it is safe NOW and was not on 2026-07-30 morning: ruleset `EJ` makes
112+
// `verify` a required check on `main` with `bypass_actors: []` AND
113+
// `strict_required_status_checks_policy: true`. So an automerged PR cannot
114+
// land red, and cannot land having been tested against a different `main`
115+
// than the one it merges into. Both of those had to be true; the second
116+
// arrived last and was the actual blocker.
117+
//
118+
// `platformAutomerge` hands the merge to GitHub's own auto-merge so the
119+
// required check gates it, rather than Renovate polling and merging itself.
120+
//
121+
// If branch protection is ever loosened - bypass actors added, `verify`
122+
// dropped, strict turned off - THIS RULE MUST GO WITH IT. It is not
123+
// independently safe.
124+
matchManagers: ["github-actions"],
125+
matchUpdateTypes: ["digest", "pin", "pinDigest"],
126+
automerge: true,
127+
automergeType: "pr",
128+
platformAutomerge: true,
129+
},
130+
{
131+
// Everything below stays manual, and the global `automerge: false` above is
132+
// the default for anything not named here. The load-bearing reason is that
133+
// `pnpm run verify` proves the repo is CONSISTENT, not that a bump is
134+
// CORRECT - and this repo has the counterexample on record: pako 3.0.0
135+
// flipped `legacyHash` to false, which passes a green suite while silently
136+
// breaking the codec's byte-exactness, and the resulting wrong belief
137+
// survived about a year. Version bumps of real dependencies get read.
138+
//
103139
// THE ONE THAT MATTERS MOST. Without it a bot proposes 6.0.3 -> 7.x every
104140
// single week and someone re-derives the refusal every time (see #48, #52).
105141
// TypeScript 7 exposes no programmatic API yet, the official migration is

CLAUDE.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,36 @@ Two settings whose reasoning is not guessable from the outside:
257257
whole section exists to prevent. 25 hours clears pnpm and still drops the wait
258258
from 3 days to ~1.
259259

260-
Branch protection on `main` is **not** configured. It is the natural follow-up
261-
now that a check exists, but it is a repository setting rather than a file.
260+
### Branch protection is a **ruleset**, and one Renovate rule depends on it
261+
262+
`main` is protected by a repository ruleset named **`EJ`** (2026-07-30, issue
263+
#60), not by classic branch protection. Read it with
264+
`gh api repos/wormeyman/FactorioMapWebUI/rules/branches/main` - the classic
265+
`/branches/main/protection` endpoint returns **404**, which looks exactly like
266+
"unprotected" and is not.
267+
268+
| rule | |
269+
| ------------------------------ | ------------------------------------ |
270+
| `pull_request` | `required_approving_review_count: 0` |
271+
| `required_status_checks` | `verify`, `strict: true` |
272+
| `deletion`, `non_fast_forward` | blocked |
273+
| `bypass_actors` | **empty** - binds the owner too |
274+
275+
Two things here are load-bearing and easy to break by "tidying":
276+
277+
- **The review count is 0 on purpose.** GitHub does not let you approve your own
278+
PR, so `1` would make `main` unmergeable by its only maintainer - a lockout
279+
that looks like correct hardening until the first PR.
280+
- **`strict: true` is what makes the Renovate automerge rule safe.** With strict
281+
checks a PR cannot merge having passed against a different `main` than the one
282+
it lands on. `.github/renovate.json5` automerges GitHub **Action digest
283+
re-pins** and only those; if bypass actors are ever added, `verify` dropped, or
284+
strict turned off, **that rule must be removed in the same change.** It is not
285+
independently safe, and the config says so at the rule.
286+
287+
Everything else stays `automerge: false`, because `verify` proves the repo is
288+
consistent, not that a bump is correct - see the pako table above for the year-long
289+
wrong belief that a green suite endorsed.
262290

263291
#### `testTimeout` is 30s, deliberately, and retries are not used
264292

0 commit comments

Comments
 (0)