Re: git: a9a6a51edac1 - main - github: Add new checklist workflow
- In reply to: Ed Maste : "git: a9a6a51edac1 - main - github: Add new checklist workflow"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 24 Jan 2025 20:50:51 UTC
On 24 Jan 2025, at 20:27, Ed Maste <emaste@FreeBSD.org> wrote:
>
> The branch main has been updated by emaste:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=a9a6a51edac13aaff5517dd602272152efa6d7bd
>
> commit a9a6a51edac13aaff5517dd602272152efa6d7bd
> Author: Ahmad Khalifa <ahmadkhalifa570@gmail.com>
> AuthorDate: 2025-01-05 05:01:07 +0000
> Commit: Ed Maste <emaste@FreeBSD.org>
> CommitDate: 2025-01-24 20:27:08 +0000
>
> 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: https://github.com/freebsd/freebsd-src/pull/1570
>
> Signed-off-by: Ahmad Khalifa <ahmadkhalifa570@gmail.com>
> ---
> .github/workflows/checklist.yml | 106 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 106 insertions(+)
>
> diff --git a/.github/workflows/checklist.yml b/.github/workflows/checklist.yml
> new file mode 100644
> index 000000000000..9734af4a1a1d
> --- /dev/null
> +++ b/.github/workflows/checklist.yml
> @@ -0,0 +1,106 @@
> +name: Checklist
> +
> +# Produce a list of things that need to be changed
> +# for the submission to align with CONTRIBUTING.md
> +
> +on:
> + pull_request:
> + types: [ opened, reopened, edited, synchronize ]
> +
> +permissions:
> + pull-requests: write
> +
> +jobs:
> + checklist:
> + name: commit
> + runs-on: ubuntu-latest
Please be careful to restrict these kinds of jobs with
if: github.repository_owner == 'freebsd'
or
if: github.repository == 'freebsd/freebsd-src'
otherwise it’s a pain for forks.
Jess
> + steps:
> + - uses: actions/github-script@v7
> + with:
> + # An asynchronous javascript function
> + script: |
> + /*
> + * Github's API returns the results in pages of 30, so
> + * pass the function we want, along with it's arguments,
> + * to paginate() which will handle gathering all the results.
> + */
> + const comments = await github.paginate(github.rest.issues.listComments, {
> + owner: context.repo.owner,
> + repo: context.repo.repo,
> + issue_number: context.issue.number
> + });
> +
> + const commits = await github.paginate(github.rest.pulls.listCommits, {
> + owner: context.repo.owner,
> + repo: context.repo.repo,
> + pull_number: context.issue.number
> + });
> +
> + let checklist = {};
> + let checklist_len = 0;
> + let comment_id = -1;
> +
> + const msg_prefix = "Thank you for taking the time to contribute to FreeBSD!\n";
> + const addToChecklist = (msg, sha) => {
> + if (!checklist[msg]) {
> + checklist[msg] = [];
> + checklist_len++;
> + }
> + checklist[msg].push(sha);
> + }
> +
> + for (const commit of commits) {
> + const sob_lines = commit.commit.message.match(/^[^\S\r\n]*signed-off-by:.*/gim);
> +
> + if (sob_lines == null && !commit.commit.author.email.toLowerCase().endsWith("freebsd.org"))
> + addToChecklist("Missing Signed-off-by lines", commit.sha);
> + else if (sob_lines != null) {
> + let author_signed = false;
> + for (const line of sob_lines) {
> + if (!line.includes("Signed-off-by: "))
> + /* Only display the part we care about. */
> + addToChecklist("Expected `Signed-off-by: `, got `" + line.match(/^[^\S\r\n]*signed-off-by:./i) + "`", commit.sha);
> + if (line.includes(commit.commit.author.email))
> + author_signed = true;
> + }
> +
> + if (!author_signed)
> + console.log("::warning title=Missing-Author-Signature::Missing Signed-off-by from author");
> + }
> +
> + if (commit.commit.author.email.toLowerCase().includes("noreply"))
> + addToChecklist("Real email address is needed", commit.sha);
> + }
> +
> + /* Check if we've commented before. */
> + for (const comment of comments) {
> + if (comment.user.login == "github-actions[bot]") {
> + comment_id = comment.id;
> + break;
> + }
> + }
> +
> + if (checklist_len != 0) {
> + let msg = msg_prefix +
> + "There " + (checklist_len > 1 ? "are a few issues that need " : "is an issue that needs ") +
> + "to be fixed:\n";
> + let comment_func = comment_id == -1 ? github.rest.issues.createComment : github.rest.issues.updateComment;
> +
> + /* Loop for each key in "checklist". */
> + for (const c in checklist)
> + msg += "- " + c + "<sup>" + checklist[c].join(", ") + "</sup>\n";
> +
> + comment_func({
> + owner: context.repo.owner,
> + repo: context.repo.repo,
> + body: msg,
> + ...(comment_id == -1 ? {issue_number: context.issue.number} : {comment_id: comment_id})
> + });
> + } else if (comment_id != -1) {
> + github.rest.issues.updateComment({
> + owner: context.repo.owner,
> + repo: context.repo.repo,
> + comment_id: comment_id,
> + body: msg_prefix + "All issues resolved."
> + });
> + }