MILAB-6648: require a changeset for every edited package, in one gate - #198
Merged
Conversation
`pnpm changeset --empty` already waived require-package-bump's half of the gate but not coverage, so an author who declared "no release needed" was passed by one half and failed by the other. Coverage now accepts the same declaration, waiving every missing package at once. Scoped to changesets ADDED in the branch: an empty changeset inherited from the base branch must not disable the gate for every branch cut after it. Exit 2 (tooling broken) still wins over the waiver. The rule is duplicated rather than shared — there is no bash-sharing precedent between actions here, and refactoring the working, tested require-package-bump.sh was not worth the risk. Both copies state the rule in place. Six cases added to the bats suite.
The per-package coverage check ran as its own always-green job, so a red result cost nothing and nobody had to act on it. It now runs as a second step inside `check for changesets`, under the existing require-package-path-bump toggle, and the separate diagnostic job is gone. Neither half implies the other, so both run and both must pass: require-package-bump ignores the diff and demands a bump of `package-path` on every PR, while check-coverage ignores untouched packages and demands a bump for each edited publishable one. Replacing the first with the second would have weakened the gate — in a block repo the model/ui/workflow/test siblings are private and so skipped by coverage, leaving a ui-only PR unchecked. The second step runs under `!cancelled()` so one red check reports the complete set of missing bumps instead of one per run. No new input and no new check name. With the toggle off — every consumer today — `check for changesets` behaves exactly as before; what those repos give up is the never-actionable diagnostic check.
AStaroverov
marked this pull request as draft
August 5, 2026 15:09
AStaroverov
marked this pull request as ready for review
August 19, 2026 10:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
require-package-path-bumpnow enforces both halves of the release contract under a single check(
check for changesets):require-package-bump— the package atpackage-pathmust be bumped directly, on every PR,whether or not its own files changed.
check-coverage— every other workspace package whose own files the PR edits must bebumped too.
The separate always-green
changeset coverage (diagnostic)job is gone; coverage now runs as asecond step inside
check for changesets. No new input, no new check name.Why
The coverage check already existed, but ran with
continue-on-error: trueand an explicit"keep this job out of required checks" note. A red result cost nothing and nobody had to act on it,
so a PR could edit a package and merge with that package shipping new content under an unchanged
version.
Why both halves rather than one
Neither half implies the other, so replacing the first with the second would have weakened the
gate:
require-package-bumpignores the diff — it demands apackage-pathbump on every PR.check-coverageignores untouched packages, and skips private ones.In a block repo only
blockis published;model/ui/workflow/testareprivate: true.A PR editing only
ui/is therefore invisible to coverage, whilerequire-package-bumpcorrectlyfails it. Both steps run and both must pass.
Half 2 only starts to bite in a repo with more than one publishable package.
The second step runs under
!cancelled(), so one red check reports the complete set of missingbumps instead of one per run.
Empty changeset
pnpm changeset --emptywaivedrequire-package-bumpbut not coverage, so an author declaring"no release needed" was passed by one half and failed by the other.
check-coverage.shnow honoursthe same opt-out, waiving every missing package at once.
Scoped to changesets added in the branch: an empty changeset inherited from the base branch must
not disable the gate for every branch cut after it.
The rule is duplicated rather than extracted into a shared file — there is no bash-sharing
precedent between actions in this repo (
lib/holds TypeScript packages), and refactoring theworking, tested
require-package-bump.shwas not worth the risk. Both copies state the rule inplace and say so.
Behaviour of the coverage half
require-package-path-bumppull_requestmerge_grouppull_request+skip-changeloglabelWith the toggle off,
check for changesetsbehaves exactly as before — non-blocking on PRs,blocking on the merge queue and push-to-default. What those repos give up is the never-actionable
diagnostic check.
changeset-coveragewas in no other job'sneeds, so build/test and the Slack release notificationare unaffected either way.
Tests
actions/changeset/check-coverage/test/coverage.bats— six cases added: the waiver applies; itwaives several packages at once; it waives alongside a partial real changeset; an inherited empty
changeset does not waive; a non-empty changeset is not read as the opt-out; exit 2 (tooling broken)
still wins over the waiver. 21/21 pass.
require-package-bump.batsuntouched, 9/9.Not in this PR
require-package-path-bumpyet. The structurer templatethat generates every block's
build.yaml(block-tools,build.tpl.yaml) can pass it once thisis on
v4.check for changesetsis a requiredcheck in the consuming repo's settings.
@v4, so a consumer pointed at the branch stillresolves the nested
uses:to stablev4. The new step cannot be exercised from a consumer PRuntil this merges.
Greptile Summary
The PR consolidates direct package-bump and edited-package coverage enforcement into the existing
check for changesetsgate, while allowing branch-added empty changesets to waive both requirements.package-path; this remains mandatory on opted-in pull requests unless the gate is waived.check for changesetsjob that now enforces both release-contract halves under one check.Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD PR[Pull request] --> Toggle{require-package-path-bump?} Toggle -- No --> Existing[Run existing changeset status check] Toggle -- Yes --> Label{skip-changelog label?} Label -- Yes --> Skip[Skip changeset gate] Label -- No --> Direct[Require direct package-path bump] Direct --> Coverage[Run edited-package coverage unless cancelled] Coverage --> Empty{Branch-added empty changeset?} Empty -- Yes --> Waive[Waive missing package bumps] Empty -- No --> Compare[Compare edited publishable packages with releases] Compare --> Result{All required packages bumped?} Result -- Yes --> Pass[Gate passes] Result -- No --> Fail[Gate fails]Reviews (2): Last reviewed commit: "MILAB-6707: fold changeset coverage into..." | Re-trigger Greptile
Context used: