Problem
In #2189 we merged hook bundling work with a squash-merge title fix(hooks): … and a changeset for @asyncapi/generator-hooks. That title is valid under Conventional Commits and passes central lint-pr-title.yml (semantic-pull-request allows scopes), but Release only runs when the commit on master starts with an unscoped prefix:
fix:, fix!:, feat:, feat!:, or chore(release):
See .github/workflows/release-with-changesets.yml (startsWith on github.event.commits[0].message).
Squash merges use the PR title as that message (MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})" in automerge). Result: Release was skipped, the changeset stayed on master, and @asyncapi/generator-hooks was not published until a follow-up fix: PR.
Proposal
Add a generator-local required check (similar in spirit to verify-ai-disclosure.yml), without changing centrally managed lint-pr-title.yml from asyncapi/.github.
Rule A — changeset ⇒ release-trigger title
If the PR adds or modifies any .changeset/*.md file (excluding config.json), the PR title must use a Release-compatible unscoped prefix (same list as Release workflow). This would have blocked #2189 (fix(hooks): + changeset).
Rule B — release title + publishable code ⇒ changeset
If the PR title will trigger Release and the diff touches publishable package source paths (e.g. apps/hooks/src/, packages/components/src/, baked-in packages/templates/, etc., excluding tests/snapshots), require either:
- a changeset file in the PR diff, or
- pending changesets already on the branch (
npx -p @changesets/cli@2.27.7 changeset status reports packages to bump).
Wake-up PRs (fix: trigger release… with no publishable path changes) should not fail Rule B.
Bot exemptions
Skip the check for known bots, aligned with existing workflows:
asyncapi-bot / asyncapi-bot-eve when title starts with chore(release): or ci: update of files from global .github repo
dependabot[bot] / dependabot-preview[bot]
allcontributors[bot] when title starts with docs: add
Implementation sketch
- Small Node module under
.github/workflows/scripts/release-pr-guard/ with unit tests (node:test).
- Workflow: e.g.
verify-changeset-release-alignment.yml on pull_request.
- Docs:
Development.md + .github/pr-review-checklist.md — scoped fix(hooks): does not trigger Release.
- Maintainers: add the new check to branch protection after merge.
Non-goals (optional follow-ups)
- Changing Release
if: to accept scoped prefixes (policy decision).
- Org-wide changes to
lint-pr-title.yml.
Related
Acceptance criteria
Problem
In #2189 we merged hook bundling work with a squash-merge title
fix(hooks): …and a changeset for@asyncapi/generator-hooks. That title is valid under Conventional Commits and passes centrallint-pr-title.yml(semantic-pull-request allows scopes), but Release only runs when the commit onmasterstarts with an unscoped prefix:fix:,fix!:,feat:,feat!:, orchore(release):See
.github/workflows/release-with-changesets.yml(startsWithongithub.event.commits[0].message).Squash merges use the PR title as that message (
MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})"in automerge). Result: Release was skipped, the changeset stayed onmaster, and@asyncapi/generator-hookswas not published until a follow-upfix:PR.Proposal
Add a generator-local required check (similar in spirit to
verify-ai-disclosure.yml), without changing centrally managedlint-pr-title.ymlfromasyncapi/.github.Rule A — changeset ⇒ release-trigger title
If the PR adds or modifies any
.changeset/*.mdfile (excludingconfig.json), the PR title must use a Release-compatible unscoped prefix (same list as Release workflow). This would have blocked #2189 (fix(hooks):+ changeset).Rule B — release title + publishable code ⇒ changeset
If the PR title will trigger Release and the diff touches publishable package source paths (e.g.
apps/hooks/src/,packages/components/src/, baked-inpackages/templates/, etc., excluding tests/snapshots), require either:npx -p @changesets/cli@2.27.7 changeset statusreports packages to bump).Wake-up PRs (
fix: trigger release…with no publishable path changes) should not fail Rule B.Bot exemptions
Skip the check for known bots, aligned with existing workflows:
asyncapi-bot/asyncapi-bot-evewhen title starts withchore(release):orci: update of files from global .github repodependabot[bot]/dependabot-preview[bot]allcontributors[bot]when title starts withdocs: addImplementation sketch
.github/workflows/scripts/release-pr-guard/with unit tests (node:test).verify-changeset-release-alignment.ymlonpull_request.Development.md+.github/pr-review-checklist.md— scopedfix(hooks):does not trigger Release.Non-goals (optional follow-ups)
if:to accept scoped prefixes (policy decision).lint-pr-title.yml.Related
Acceptance criteria
fix(hooks):title fails CI with a clear message.fix:title passes.fix:PR changingapps/hooks/src/without changeset fails (unless pending changeset on branch).fix:empty/doc-only wake-up PR passes.chore(release):) are exempt.