Skip to content

ci: gate master on required checks and validate PR titles - #360

Merged
chhoumann merged 13 commits into
masterfrom
ci/gates-and-governance
Oct 10, 2026
Merged

chhoumann merged 13 commits into
masterfrom
ci/gates-and-governance

Conversation

@chhoumann

@chhoumann chhoumann commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Why

Nothing stops a red PR from merging into master today, and the squash title that the release planner reads is never checked. This PR adds the workflows and a ruleset definition so that master only takes squash-merged PRs that passed every required check, with a title the planner reads correctly.

What changed

  • New PR Title workflow (Validate PR title) and Dependency Review workflow. Docs now runs on every PR. Test cancels superseded PR runs, checks out without persisted credentials, and drops the dead targetSha input and the duplicate type check (npm run build already runs it).
  • .github/rulesets/protect-master.json blocks deletion and force push, allows only squash merges of up-to-date PRs, and requires Test, Docs, Validate PR title, Dependency Review, and CodeQL, each pinned to the app that reports it.
  • Issue forms, PR template, CODEOWNERS, SECURITY.md, one Dependabot group for Actions bumps, and an AGENTS.md Release Workflow section that matches the pinned v4 release workflows.

Scope

  • The ruleset is not applied here. Apply it only after this PR merges, because pull_request_target runs pr-title.yml from master, so Validate PR title cannot report on this PR.
  • Left out: QuickAdd's code_scanning alert rule, and a guard ruleset on release/** branches. Both are follow-ups.

Tradeoffs

  • The title check is a bash pattern, not QuickAdd's amannn/action-semantic-pull-request. That action's parser matches feat!: with a built-in breaking-header pattern that no input can override. The planner then plans no release for that title. The script rejects ! and needs no third-party code in a pull_request_target job.
  • Strict up-to-date checks, unlike QuickAdd. The release validator rejects a release PR that is squash-merged after master moves, and every later Prepare release run then refuses to plan. Strict checks block that merge until the bot refreshes the PR.

Blast Radius

Every future PR needs the five checks, and must be up to date before it merges. The release flow cannot deadlock. The bot App opens the release PR, so it gets the normal pull_request and pull_request_target runs. Each push to master force-refreshes the PR onto the new head. Nothing in the pipeline pushes to master, so no bypass actor is needed. CodeQL reports neutral on docs-only PRs, which counts as passing for a required check.

Verification

  • actionlint 1.7.12 on all workflows, then lint, format, typecheck, build, test (78 files, 1152 tests), and docs build pass locally on Node 22.23.2.
  • A harness runs the pr-title.yml script under bash on 18 titles, with a mock gh that answers only the exact API call. It compares each title with the planner's commit analyzer. The script accepts every title the planner reads correctly and rejects feat!:, which QuickAdd's action config lets through. A real gh read passes PR build(deps-dev): bump the npm-development-minor-patch group across 1 directory with 9 updates #343 and fails PR Feat/improvements #156.
  • Test job median over 10 dispatched runs each: 102s before, 87s after. About 8s of that is the removed type check (16s to 8s for the two steps). The rest is runner variance in the test step. This PR's own two runs took 94s, against 105.5s for the previous 10 PR runs.
  • On this PR's head, Test, Docs, Dependency Review, and CodeQL report from the apps the ruleset pins (15368 and 57789). Validate PR title starts reporting once pr-title.yml is on master.

Apply after merge:

gh api -X POST repos/chhoumann/PodNotes/rulesets --input .github/rulesets/protect-master.json

Release impact: none. No src/, settings, API, or URI change.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Deploying podnotes with  Cloudflare Pages  Cloudflare Pages

Latest commit: 76ce75f
Status: ✅  Deploy successful!
Preview URL: https://2f5d2dae.podnotes.pages.dev
Branch Preview URL: https://ci-gates-and-governance.podnotes.pages.dev

View logs

@chhoumann
chhoumann merged commit 0d83671 into master Oct 10, 2026
8 checks passed
@chhoumann
chhoumann deleted the ci/gates-and-governance branch October 10, 2026 23:45
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