Skip to content

Stricter release-note rules, live pull request reads and Dependabot release labels - #127

Merged
woksin merged 4 commits into
mainfrom
release-notes-stricter-gates
Oct 1, 2026
Merged

woksin merged 4 commits into
mainfrom
release-notes-stricter-gates

Conversation

@woksin

@woksin woksin commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Added

Changed

… read pull requests live, and normalize Dependabot release labels
@woksin woksin added the minor label Oct 1, 2026
@woksin woksin self-assigned this Oct 1, 2026
@woksin woksin added the minor label Oct 1, 2026
@woksin

woksin commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Notes for reviewers (not part of the release notes).

Merging deploys organization-wide. This PR changes .github/scripts/bootstrap-common-workflows.sh and .github/pull_request_template.md, both push paths of organization-wide write workflows. Merging to main therefore runs Bootstrap Common Workflows (rewrites verify-release-notes.yml and adds/overwrites verify-semver-label.yml in every non-ignored repository) and Propagate PR Templates. bootstrap-package-update-safety.test.py flags exactly this when run locally against this diff (it only runs in CI for package-update paths). If the bootstrap should run separately, disable it or split the script change out before merging.

What the bootstrap changes. 27 repositories have a verify-semver-label.yml today. Outside REPOS_TO_IGNORE, the canonical copy replaces it (job renamed verify to release-intent, Dependabot normalizer added); cli and Prologue only lose a custom workflow display name. Arc.Kotlin is skipped through the new SKIP_FILE_REPOS. Repositories without one (Samples, Common, ...) get it for the first time and then need one of the four labels on every PR (see #84 for repositories missing labels). The ignored repositories that have a caller (Ante, Components, Orleans, Stage, Templates, Chronicle.Elixir, Chronicle.Python) keep the old caller: their Dependabot PRs labelled major by Dependabot will now fail release-intent until their caller gains the normalizer job.

Required checks. Only Cratis/AI requires verify and release-intent / verify; AI's own caller is being reworked separately, so the job rename affects no other repository.

Permissions. The reusable gates no longer declare permissions: a called workflow can only narrow its caller's grant, and requesting more than a caller grants fails the run at startup. Callers that grant only contents: read (private copies, AI) keep working from the event payload, with a notice.

False positives of the new rules, measured on 925 published release bodies from 19 repositories (now fixtures/release-notes/corpus.json, with recorded rules the spec pins): the new rules add 80 line-level findings in 56 bodies. I read every one; none is a product bullet. One is borderline: Chronicle v19.1.2 has Reproduced end-to-end with the Kotlin client inside a product bullet, which is a verification note. Of the 581 bodies that passed before, 3 now fail (Chronicle v19.1.2, cli v3.16.0 Draft:, Chronicle.Kotlin v2.10.0 Stacked on #46), all genuine. The spec adds about 30 product-wording guards that must pass.

Deviations from the plan. No comma clause start (it flagged Forms are submitted, validated in the browser and saved). Provenance is only recognised where the note opens a clause, because Release notes are now checked on main is product wording. No bare ### CI heading ban, because it groups CI changes. this branch only counts with a need (needs, depends, is stacked), because The CLI now warns when this branch is behind main is product wording. The live read uses Node fetch in the release-notes gate, because self-hosted images have no gh. The drift checkout keeps credentials so private repositories can fetch blobs on demand (filter: blob:none); the job never runs code from the PR. The caller runs the gate after a failed normalizer (!cancelled()) instead of skipping it.

Local checks run: both specs (63 + 6 tests), update-packages.test.py, cleanup-pr-artifacts.test.py, the AI-profile specs, actionlint on the changed workflows (the existing publish.template.yml findings are untouched), shellcheck on the bootstrap script.

…ase-intent caller only where a repository releases, and run the drift check on label changes
@woksin

woksin commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Notes for reviewers (not part of the release notes), after review.

  • Dependabot in ignored repositories. The gate itself now never fails a Dependabot pull request for its labels. When the author is dependabot[bot] and the labels are not exactly no-release, it removes major/minor/patch and adds no-release if its token can write, and otherwise passes with a ::notice. Callers without the normalizer (Templates, Stage, Ante, Chronicle.Elixir, Components, Orleans, Chronicle.Python) therefore keep working. normalize-dependabot-labels.yml stays: the bootstrapped caller gives the gate job only pull-requests: read, so the normalizer job is what holds pull-requests: write there.
  • Non-releasing repositories. The bootstrap installs verify-semver-label.yml only where the repository already has it or one of its workflows references Cratis/release-action (owner matched case-insensitively), decided by the script on every run. Checked read-only against the non-ignored repositories: blog.cratis.io, Common, cratis.no, homebrew-cratis, Samples and Workshops are skipped; every other one is covered. Arc.Kotlin is still skipped through SKIP_FILE_REPOS. Eventmodelers-Build-Kit-CSharp releases (its publish.yml uses cratis/release-action@v1), so it was missing the major and minor labels; I created both there (same colours and descriptions as in Eventmodelers-Build-Kit-Java).
  • Drift job. It now also runs on labeled/unlabeled; the caller's concurrency group cancels the whole run on a label change, so skipping those events left the check cancelled with nothing to replace it.
  • Header comment in bootstrap-common-workflows.yml not edited. The script's header already lists verify-semver-label.yml; the workflow's header does not, and I left it that way on purpose. The header text is not what fails bootstrap-package-update-safety.test.py: locally it fails in test_effective_changed_files_do_not_trigger_organization_writes because this PR changes .github/scripts/bootstrap-common-workflows.sh and .github/pull_request_template.md, which are push-trigger paths of the organization-wide write workflows. But verify-package-updates.yml runs that test only when a PR touches bootstrap-common-workflows.yml (among a few other files). Editing the header would therefore start that job on this PR, where it would fail for the reason above. Merging still runs Bootstrap Common Workflows and Propagate PR Templates, as noted earlier.
  • Local checks run: both node specs (63 + 8 tests), update-packages.test.py, cleanup-pr-artifacts.test.py, the AI-profile specs, shellcheck on the bootstrap script, actionlint on the three changed workflows.

@woksin

woksin commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Review follow-ups pushed (a45eeaa):

  • Release-note patterns no longer flag product wording: do not merge is an instruction only when it opens a clause or is followed by this/it/yet/until/before/after; before|after|once (merging|deploying|releasing) this needs this (pr|pull request|branch|change); should be (deployed|merged|released) ... needs this/it/this PR/this pull request as the subject; this branch needs ... and retarget ... to main must open a clause; N of N runs counts only at the start of a clause or before verification wording (passed/green/failed...). The six reported bullets are now must-pass guards, and the 925-body corpus keeps exactly the recorded rules. The "Once merging this, bump the kernel." example in the instruction spec became "Once merging this PR, ..." because bare this is no longer enough.
  • normalize-dependabot-labels.yml never fails the run: a failed read, a failed or 404 DELETE and a failed POST each end in a ::notice::, and the labels are read again at the end. New readOnly spec case expects exit 0.
  • bootstrap-common-workflows.yml header lists verify-semver-label.yml (installed only where a release-intent check exists or the repo uses Cratis/release-action; Arc.Kotlin skipped). bootstrap-package-update-safety.test.py still passes.
  • Arc.Kotlin follow-up (bump the pinned verify-release-intent.yml SHA to the merged commit and add the normalizer job; Arc.Kotlin#268 fails today): Bump the pinned verify-release-intent.yml to Workflows#127 and add the Dependabot label normalizer Arc.Kotlin#270

…ackage-update safety check on this pull request
@woksin

woksin commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Correction to the previous comment (head now 13d1ddb): the verify-semver-label.yml entry in the bootstrap-common-workflows.yml header is not added. Any edit to that file runs "Verify Package Updates", and bootstrap-package-update-safety.test.py fails it because this pull request also changes .github/scripts/bootstrap-common-workflows.sh and .github/pull_request_template.md, which are organization-wide write triggers. The header should list verify-semver-label.yml (installed only where a release-intent check already exists or the repo uses Cratis/release-action; Arc.Kotlin skipped) in a separate follow-up change that does not touch those files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant