Skip to content

chore(gha): gate dependency upgrades on release age - #418

Open
jsteinich wants to merge 1 commit into
open-constructs:mainfrom
jsteinich:chore/upgrade-release-age-cooldown
Open

chore(gha): gate dependency upgrades on release age#418
jsteinich wants to merge 1 commit into
open-constructs:mainfrom
jsteinich:chore/upgrade-release-age-cooldown

Conversation

@jsteinich

Copy link
Copy Markdown
Contributor

Draft for review — not urgent, and the two numbers below (25h / 24h) are the main thing worth a second opinion.

Problem

pnpm applies a 24h minimumReleaseAge by default. Without minimumReleaseAgeStrict it doesn't block — it records the exception in minimumReleaseAgeExclude and installs the fresh version anyway.

The weekly upgrade run hit this with knip@6.35.1, published ~6h earlier. pnpm waived its own delay and wrote the bypass into pnpm-workspace.yaml, where it would have merged unnoticed had it not been spotted in review on #326. The delay exists precisely so a compromised publish has time to be caught; auto-waiving it defeats the mechanism.

Change

Two halves that only work together:

ncu --cooldown 25h (all 7 invocations) never proposes a version inside pnpm's window; falls back to the newest version that clears it
minimumReleaseAge: 1440 + minimumReleaseAgeStrict: true pnpm now enforces rather than waives — a backstop that should never fire

Enabling strict alone would break the upgrade job the way strictDepBuilds did in #399: the bot would die instead of producing a PR. The cooldown is what makes strict safe to turn on.

The window is pinned rather than inherited so the one-hour buffer stays meaningful if pnpm changes its default. Note that explicitly setting minimumReleaseAge auto-enables strict on its own; both are set explicitly so the intent is readable.

Why 25h and not 24h: just enough margin that a version sitting exactly on the boundary at ncu time is still clear when pnpm re-verifies minutes later, without adding a full day of lag.

Verification

# ncu holds back the fresh version and says so
knip  ^6.16.1  →  ^6.35.1                      # without cooldown
knip  ^6.16.1  →  ^6.35.0  [cooldown] 6.35.1   # with --cooldown 25h
  • A planted knip@6.35.1 fails pnpm ci with ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION, confirming the gate is live from pnpm-workspace.yaml and not a silent no-op.
  • main's current lockfile passes the strict check unchanged — this doesn't turn CI red on merge.
  • prettier --check clean; both YAML files parse with all 7 cooldown flags in place.

Trade-off

Upgrades lag up to ~25h. A version published the morning of the Monday run gets picked up the following week instead. That is the intended cost.

Not included

Pruning the existing minimumReleaseAgeExclude entry — that was already handled on #326 by rolling knip back to main's 6.16.1 and removing the bypass.

🤖 Generated with Claude Code

pnpm applies a 24h minimumReleaseAge by default, but without
minimumReleaseAgeStrict it does not block: it records the exception in
minimumReleaseAgeExclude and installs the fresh version anyway. The
weekly upgrade run hit this with knip@6.35.1, published ~6h earlier, and
silently waived the delay the policy exists to enforce.

Pair two changes so the policy actually holds:

- ncu gains --cooldown 25h on all seven invocations, so it never
  proposes a version inside pnpm's window and falls back to the newest
  version that clears it.
- pnpm-workspace.yaml pins minimumReleaseAge to pnpm's current 24h
  default and sets minimumReleaseAgeStrict, turning the policy into a
  backstop that should never fire.

Enabling strict alone would break the upgrade job the way strictDepBuilds
did (open-constructs#399); the cooldown is what makes strict safe. The window is pinned
rather than inherited so the one-hour buffer stays meaningful if pnpm
changes its default.

Verified: ncu --cooldown 25h holds knip at 6.35.0 with "[cooldown]
6.35.1" while the same command without it proposes 6.35.1; a planted
knip@6.35.1 fails `pnpm ci` with ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION;
and main's current lockfile passes the strict check unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jsteinich
jsteinich marked this pull request as ready for review September 10, 2026 01:19
@jsteinich
jsteinich requested a review from a team as a code owner September 10, 2026 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant