Skip to content

Commit 3d61d25

Browse files
buenaflorclaudecodex
authored
ci: Enforce conventional commit format for PR titles (#3666)
* ci: Enforce Sentry commit message convention on PR titles Adds a workflow that fails when a PR title does not match the `<type>(<scope>)?: <Subject>` convention from https://develop.sentry.dev/engineering-practices/commit-messages/. Re-validates on title edits. Can be bypassed with an `ignore-title` label if ever needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci: Align PR title regex with release.yml categories - Add `impr`, `enh`, `deps`, `refactor`, `tests` (plural) to match the types categorized by `.github/release.yml`. - Allow breaking-change `!` suffix (e.g. `feat!: ...`) consistent with the Breaking Changes pattern in release.yml. - Drop `license` — not recognized by release.yml and rare enough to lose. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(agents): Add minimal PR description guidance Document that PR descriptions stay minimal by default and avoid test-plan checklists unless explicitly requested. This keeps /create-pr output concise and aligned with repository expectations. Co-Authored-By: Codex 5.3 <noreply@openai.com> Made-with: Cursor * Revise PR title format for capitalization requirement Updated PR title format to require capitalization. * ci: Inline PR title validation workflow Run title validation directly in github-script, remove the checked-out local JS helper, and validate associated PRs for merge_group events. Also relax subject-case enforcement so updater PR titles like `chore(deps): update ...` continue to pass and map to Dependencies. Co-Authored-By: Codex 5.3 <noreply@openai.com> Made-with: Cursor * ci: Run PR title check on sync updates Include the pull_request synchronize event so the PR title workflow reruns when new commits are pushed to an existing pull request. Co-Authored-By: Codex 5.3 <noreply@openai.com> Made-with: Cursor * ci: Remove ignore-label bypass from title check Drop the ignore-title label escape hatch from the PR title workflow so all non-draft, non-merged PRs are consistently validated. Co-Authored-By: Codex 5.3 <noreply@openai.com> Made-with: Cursor * ci: Rename PR title check job label Update the workflow job name to `Check Conventional PR Title` so the GitHub checks list is more explicit. Co-Authored-By: Codex 5.3 <noreply@openai.com> Made-with: Cursor * ci: Remove merge_group from PR title workflow Drop merge_group triggering and simplify the script to validate only pull_request payloads. This removes an unnecessary code path and avoids misleading merge_group failure messages. Co-Authored-By: Codex 5.3 <noreply@openai.com> Made-with: Cursor * ci: Enforce capitalized PR titles for humans Require capitalized PR title subjects for human-authored pull requests while allowing lowercase starts for automated bot PRs. Update AGENTS guidance to match the bot exception and keep documented conventions aligned with CI behavior. Co-Authored-By: Codex 5.3 <noreply@openai.com> Made-with: Cursor --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Codex 5.3 <noreply@openai.com>
1 parent f7e0e8b commit 3d61d25

2 files changed

Lines changed: 86 additions & 1 deletion

File tree

.github/workflows/pr-title.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: 'PR Title'
2+
on:
3+
pull_request:
4+
types:
5+
[
6+
opened,
7+
synchronize,
8+
edited,
9+
reopened,
10+
ready_for_review,
11+
labeled,
12+
unlabeled,
13+
]
14+
permissions:
15+
contents: read
16+
pull-requests: read
17+
18+
concurrency:
19+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
20+
cancel-in-progress: true
21+
22+
jobs:
23+
check:
24+
name: Check Conventional PR Title
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
28+
with:
29+
script: |
30+
const TITLE_RE = /^(ci|build|docs|feat|fix|perf|ref|refactor|impr|enh|deps|style|chore|tests?|meta)(\([^)]+\))?!?: [A-Z`'"].*[^,.]$/;
31+
const AUTOMATED_TITLE_RE = /^(ci|build|docs|feat|fix|perf|ref|refactor|impr|enh|deps|style|chore|tests?|meta)(\([^)]+\))?!?: [A-Za-z`'"].*[^,.]$/;
32+
33+
function isRevert(title) {
34+
return /^Revert ".*"$/.test(title || '');
35+
}
36+
37+
function isAutomatedPr(pr) {
38+
const login = (pr.user?.login || '').toLowerCase();
39+
return (
40+
pr.user?.type === 'Bot' ||
41+
login === 'github-actions' ||
42+
login === 'github-actions[bot]' ||
43+
login === 'dependabot[bot]' ||
44+
login === 'renovate' ||
45+
login === 'renovate[bot]'
46+
);
47+
}
48+
49+
function validateTitle(pr) {
50+
if (pr.merged || pr.draft) {
51+
return null;
52+
}
53+
54+
const titleRe = isAutomatedPr(pr) ? AUTOMATED_TITLE_RE : TITLE_RE;
55+
if (titleRe.test(pr.title || '') || isRevert(pr.title)) {
56+
return null;
57+
}
58+
59+
return `#${pr.number}: "${pr.title}"`;
60+
}
61+
62+
const pr = context.payload.pull_request;
63+
if (!pr) {
64+
core.setFailed('Missing pull_request payload.');
65+
return;
66+
}
67+
68+
const failures = [validateTitle(pr)].filter(Boolean);
69+
if (failures.length > 0) {
70+
core.setFailed(
71+
`PR title does not match Sentry conventions:\n${failures.join('\n')}`
72+
);
73+
core.info(
74+
'Please follow the Sentry commit message conventions: https://develop.sentry.dev/engineering-practices/commit-messages/'
75+
);
76+
core.info('Format: <type>(<scope>): <subject>');
77+
core.info(
78+
'For human-authored PRs, subject must be capitalized and must not end with a period.'
79+
);
80+
core.info(
81+
'Automated bot PRs (dependabot/github-actions/renovate) may start with lowercase.'
82+
);
83+
} else {
84+
core.info('Validated PR title.');
85+
}

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Run from within the package directory (e.g., `cd packages/dart/`):
6868

6969
## Pull Requests
7070

71-
- **Title** — same format as commit subject (Conventional Commits): `type(scope): description`
71+
- **Title** — same format as commit subject where the beginning of subject must be capitalized for human-authored PRs (Conventional Commits): `type(scope): Capitalized description` (automated bot PRs may start lowercase)
7272
- **Branch naming**`<type>/<short-description>` (e.g., `feat/session-replay-privacy`, `fix/memory-leak-scope`)
7373
- **PR template**`.github/pull_request_template.md` includes: description, motivation, how tested, checklist
7474
- **Reviewers** — assigned via `CODEOWNERS` (`.github/CODEOWNERS`); one maintainer approval is sufficient

0 commit comments

Comments
 (0)