Repository navigation
config: reject an unsafe standing PR title at load instead of replacing it at runtime #777
Description
This was generated by AI during triage.
Follow-up to #729, from its review.
Agent Brief
Category: bug
Summary: Reject an unsafe standing-PR title when the config loads, instead of replacing it at runtime on every standing-PR update.
Why: the standing PR's title is also the release commit's subject, and the squash merge carries it onto main. A title that no release.ci.skipPatterns entry matches makes the merge trigger another standing-PR update, which can double-bump off the just-merged, not-yet-tagged version. A title with a CI-skip marker skips the publish workflow on main. After #729, the update warns and swaps in chore: release preparation when that's safe, so a bad title surfaces as a warning repeated on every hourly, label and edit run, and the PR quietly loses its configured title.
Current behavior (after #729):
- Config loading accepts any
ci.standingPr.titleand anyrelease.ci.skipPatterns, including[]. - Each standing-PR update renders the title, warns if it's unsafe, and replaces it with
chore: release preparationwhen the skip patterns match that, or keeps it otherwise.
Desired behavior:
- When
ci.releaseStrategyisstanding-pr, config loading fails if the effective title template is unsafe. The effective template isci.standingPr.title, or the strategy default when unset:chore: release ${tag}whenversion.syncis true (its default),chore: release ${count} package(s)otherwise. Render it with placeholder values for${count},${version}and${tag}. It's unsafe if:- it contains a CI-skip marker (the same set fix(release): commit the standing PR's release branch with the PR title #729 recognises); or
- no entry of the effective
release.ci.skipPatternsmatches it. The effective list is the default['chore: release ']when unset. An empty list matches nothing.
- The error names
ci.standingPr.titleandrelease.ci.skipPatterns, and says which rule failed. - Other strategies are not checked; they don't use the title.
- The runtime fallback from fix(release): commit the standing PR's release branch with the PR title #729 is removed. The update commits and titles the PR with the rendered template, since the load check already guarantees it's safe.
- The schema descriptions for
ci.standingPr.titleandrelease.ci.skipPatterns, and thetitlerows inpackages/release/docs/ci-setup.mdand the release README (if Docs: document config options only in the generated reference #768 hasn't removed them yet), state the rule and that config loading fails otherwise.
Key interfaces:
ReleaseKitConfigSchema, needing a cross-field refinement overciandrelease.LLMConfigSchemaalready usessuperRefinefor load-time validation.- The CI-skip marker pattern, which today lives in the standing-PR module. The config package can't import from
@releasekit/release, so share it from config or core. - The standing-PR update's title rendering and release-branch commit.
Acceptance criteria:
- Through
loadConfig, instanding-prmode: a title with[skip ci]fails; the default title withskipPatterns: ["ci:"]fails; the default title withskipPatterns: []fails. Each error names the keys and the rule. - The same configs load in
directandmanualmode. - The default config in
standing-prmode loads, and so does this repo's ownreleasekit.config.json. - A standing-PR update commits and titles the PR with the rendered template. Nothing in the update replaces the title or warns about it.
-
pnpm schema:checkandpnpm docs:checkpass.
Out of scope:
- The CI-skip marker in the standing PR body (standing PR: neutralise CI-skip markers in the PR body so a squash merge can't skip the publish #776).
- Checking titles whose safety depends on the real version values. Placeholder rendering is enough.
Release: this rejects configs that load today, so it's a ! change for 0.43.0.
Blocked by: #729, which introduces the runtime check this replaces.
Activity