Skip to content

Commit 11beb6d

Browse files
committed
Conventional Commits Check for PR titles
1 parent f921f04 commit 11beb6d

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Conventional Commits Check
2+
3+
on:
4+
# Using pull_request_target instead of pull_request for secure handling of fork PRs
5+
pull_request_target:
6+
# Re-run on title edits so a corrected title clears the check
7+
types: [opened, synchronize, reopened, edited]
8+
# Only check PRs targeting the dev branch
9+
branches:
10+
- dev
11+
12+
permissions:
13+
pull-requests: write
14+
issues: write
15+
16+
jobs:
17+
conventional-commits:
18+
name: Validate Conventional Commits
19+
runs-on: ubuntu-slim
20+
steps:
21+
- name: Validate PR title
22+
uses: actions/github-script@v9
23+
with:
24+
github-token: ${{ secrets.GITHUB_TOKEN }}
25+
script: |
26+
const title = context.payload.pull_request.title || '';
27+
const pattern = /^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\(.+\))?!?: .+/;
28+
29+
if (pattern.test(title)) {
30+
console.log(`✓ PR title follows Conventional Commits format: "${title}"`);
31+
return;
32+
}
33+
34+
console.log(`❌ PR title does not follow Conventional Commits format: "${title}"`);
35+
36+
const message = [
37+
'❌ **This PR title does not follow the [Conventional Commits](https://www.conventionalcommits.org/) format.**',
38+
'',
39+
'Expected format: `type(scope)?: description`',
40+
'',
41+
'Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`, `ci`, `build`, `revert`',
42+
'',
43+
'Examples:',
44+
'- `feat: add SharePoint external user management`',
45+
'- `fix(auth): handle expired refresh tokens`',
46+
'- `docs: update self-hosting guide`',
47+
'',
48+
`Received: \`${title}\``,
49+
'',
50+
'🔒 This PR has been automatically closed. Please update the title to match the format above and reopen the PR.'
51+
].join('\n');
52+
53+
await github.rest.issues.createComment({
54+
...context.repo,
55+
issue_number: context.issue.number,
56+
body: message
57+
});
58+
59+
await github.rest.pulls.update({
60+
...context.repo,
61+
pull_number: context.issue.number,
62+
state: 'closed'
63+
});
64+
65+
core.setFailed(`PR title does not follow Conventional Commits format: "${title}"`);

0 commit comments

Comments
 (0)