forked from Lumina-eX/TaskChain
-
Notifications
You must be signed in to change notification settings - Fork 0
121 lines (104 loc) · 4.84 KB
/
Copy pathcommit-message-validation.yml
File metadata and controls
121 lines (104 loc) · 4.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
name: Commit Message Validation
on:
pull_request:
types: [opened, synchronize]
permissions:
pull-requests: write
contents: read
jobs:
validate-commit-messages:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate Commit Messages
uses: actions/github-script@v7
with:
script: |
const { execSync } = require('child_process');
const pr = context.payload.pull_request;
// Get commits in the PR
const commits = await github.rest.pulls.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number
});
const validCommitPattern = /^(feat|fix|docs|style|refactor|perf|test|chore|ci)(\(.+\))?!?: .{1,100}$/;
const invalidCommits = [];
commits.data.forEach(commit => {
const message = commit.commit.message.split('\n')[0]; // Get first line
if (!validCommitPattern.test(message)) {
invalidCommits.push({
sha: commit.sha.substring(0, 7),
message: message
});
}
});
if (invalidCommits.length > 0) {
core.setFailed(` Found ${invalidCommits.length} commit(s) with invalid message format`);
return;
}
core.info(' All commit messages follow the conventional commits format');
- name: Comment on commit validation failure
if: failure()
uses: actions/github-script@v7
with:
script: |
const { execSync } = require('child_process');
const pr = context.payload.pull_request;
const commits = await github.rest.pulls.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number
});
const validCommitPattern = /^(feat|fix|docs|style|refactor|perf|test|chore|ci)(\(.+\))?!?: .{1,100}$/;
const invalidCommits = [];
commits.data.forEach(commit => {
const message = commit.commit.message.split('\n')[0];
if (!validCommitPattern.test(message)) {
invalidCommits.push({
sha: commit.sha.substring(0, 7),
message: message
});
}
});
if (invalidCommits.length > 0) {
let commitsList = invalidCommits.map(c => '- `' + c.sha + '`: ' + c.message).join('\n');
const body = '### Commit Message Validation Failed \n\n' +
'The following commits do not follow the Conventional Commits format:\n\n' +
commitsList + '\n\n' +
'**Required Format:** `type(scope)?: message`\n\n' +
'**Allowed Types:**\n' +
'- `feat` - A new feature\n' +
'- `fix` - A bug fix\n' +
'- `docs` - Documentation only changes\n' +
'- `style` - Changes that do not affect code meaning (formatting, etc.)\n' +
'- `refactor` - A code change that neither fixes a bug nor adds a feature\n' +
'- `perf` - A code change that improves performance\n' +
'- `test` - Adding missing tests or correcting existing tests\n' +
'- `chore` - Changes to build process, dependencies, or tooling\n' +
'- `ci` - Changes to CI configuration files\n\n' +
'**Message Rules:**\n' +
'- Use imperative mood ("add" not "adds" or "added")\n' +
'- Do not capitalize the first letter\n' +
'- Do not end with a period\n' +
'- Maximum 100 characters\n' +
'- Be specific and descriptive\n\n' +
'**Examples:**\n' +
'- `feat: add user authentication system`\n' +
'- `fix(login): resolve session timeout issue`\n' +
'- `docs: update API documentation`\n' +
'- `refactor(utils): simplify date formatting`\n' +
'- `Added new feature` (missing type)\n' +
'- `feat: Add user authentication system` (capitalized)\n' +
'- `feat: add user authentication system.` (period at end)\n\n' +
'Please amend your commits to follow the conventional commits format.';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}