Skip to content

Commit a9a6a51

Browse files
VexedUXRemaste
authored andcommitted
github: Add new checklist workflow
Add a new 'checklist' workflow that checks the commit messages on pull requests. Currently, the workflow creates a comment on the pull request if any of these conditions are hit: - Missing Signed-off-by - Malformed Signed-off-by - Bad email (i.e *noreply*) Reviewed by: emaste, imp Pull request: #1570 Signed-off-by: Ahmad Khalifa <[email protected]>
1 parent c814172 commit a9a6a51

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

.github/workflows/checklist.yml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Checklist
2+
3+
# Produce a list of things that need to be changed
4+
# for the submission to align with CONTRIBUTING.md
5+
6+
on:
7+
pull_request:
8+
types: [ opened, reopened, edited, synchronize ]
9+
10+
permissions:
11+
pull-requests: write
12+
13+
jobs:
14+
checklist:
15+
name: commit
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/github-script@v7
19+
with:
20+
# An asynchronous javascript function
21+
script: |
22+
/*
23+
* Github's API returns the results in pages of 30, so
24+
* pass the function we want, along with it's arguments,
25+
* to paginate() which will handle gathering all the results.
26+
*/
27+
const comments = await github.paginate(github.rest.issues.listComments, {
28+
owner: context.repo.owner,
29+
repo: context.repo.repo,
30+
issue_number: context.issue.number
31+
});
32+
33+
const commits = await github.paginate(github.rest.pulls.listCommits, {
34+
owner: context.repo.owner,
35+
repo: context.repo.repo,
36+
pull_number: context.issue.number
37+
});
38+
39+
let checklist = {};
40+
let checklist_len = 0;
41+
let comment_id = -1;
42+
43+
const msg_prefix = "Thank you for taking the time to contribute to FreeBSD!\n";
44+
const addToChecklist = (msg, sha) => {
45+
if (!checklist[msg]) {
46+
checklist[msg] = [];
47+
checklist_len++;
48+
}
49+
checklist[msg].push(sha);
50+
}
51+
52+
for (const commit of commits) {
53+
const sob_lines = commit.commit.message.match(/^[^\S\r\n]*signed-off-by:.*/gim);
54+
55+
if (sob_lines == null && !commit.commit.author.email.toLowerCase().endsWith("freebsd.org"))
56+
addToChecklist("Missing Signed-off-by lines", commit.sha);
57+
else if (sob_lines != null) {
58+
let author_signed = false;
59+
for (const line of sob_lines) {
60+
if (!line.includes("Signed-off-by: "))
61+
/* Only display the part we care about. */
62+
addToChecklist("Expected `Signed-off-by: `, got `" + line.match(/^[^\S\r\n]*signed-off-by:./i) + "`", commit.sha);
63+
if (line.includes(commit.commit.author.email))
64+
author_signed = true;
65+
}
66+
67+
if (!author_signed)
68+
console.log("::warning title=Missing-Author-Signature::Missing Signed-off-by from author");
69+
}
70+
71+
if (commit.commit.author.email.toLowerCase().includes("noreply"))
72+
addToChecklist("Real email address is needed", commit.sha);
73+
}
74+
75+
/* Check if we've commented before. */
76+
for (const comment of comments) {
77+
if (comment.user.login == "github-actions[bot]") {
78+
comment_id = comment.id;
79+
break;
80+
}
81+
}
82+
83+
if (checklist_len != 0) {
84+
let msg = msg_prefix +
85+
"There " + (checklist_len > 1 ? "are a few issues that need " : "is an issue that needs ") +
86+
"to be fixed:\n";
87+
let comment_func = comment_id == -1 ? github.rest.issues.createComment : github.rest.issues.updateComment;
88+
89+
/* Loop for each key in "checklist". */
90+
for (const c in checklist)
91+
msg += "- " + c + "<sup>" + checklist[c].join(", ") + "</sup>\n";
92+
93+
comment_func({
94+
owner: context.repo.owner,
95+
repo: context.repo.repo,
96+
body: msg,
97+
...(comment_id == -1 ? {issue_number: context.issue.number} : {comment_id: comment_id})
98+
});
99+
} else if (comment_id != -1) {
100+
github.rest.issues.updateComment({
101+
owner: context.repo.owner,
102+
repo: context.repo.repo,
103+
comment_id: comment_id,
104+
body: msg_prefix + "All issues resolved."
105+
});
106+
}

0 commit comments

Comments
 (0)