From 9c25094733c92b2bf758ff56de5063b01ffdd8a8 Mon Sep 17 00:00:00 2001 From: Rob Nester Date: Fri, 29 Sep 2023 14:54:31 -0400 Subject: [PATCH] Add action to validate PR & commit messages This commit adds a GitHub workflow action that validates the following: - The pull request body references an issue or ticket identifier - The commit messages for commits contained within the pull request all reference an issue or ticket identifier - The reference to an issue or ticket is in one of the following formats: - references: PROJ-1234 - references: #123 (for GitHub issues, specifically) - resolves: PROJ-1234 - resolves: #123 (for GitHub issues, specifically) references: HACBS-2653 Signed-off-by: Rob Nester --- CONTRIBUTING.md | 32 ++++++- .../check_commit_message_for_tickets.yml | 92 +++++++++++++++++++ 2 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 workflows/check_commit_message_for_tickets.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f34455..5a1dd29 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,7 +53,31 @@ Before contributing code or documentation to this project, make sure you read th ### Commit message standards -The commit message should contain an overall explanation about the change and the motivation behind it. Please note that mentioning a Jira ticket ID or a GitHub issue, isn't a replacement for that. +The commit message should contain an overall explanation about the change and the motivation behind it. + +In addition to an explanation about the change, please ensure that each commit contains a line similar to one of the following: + +|if your commit|use this keyword|value| +|-|-------|-----| +|resolves an issue/ticket|resolves, res, resolved| #123(only for GitHub Issues), PROJ-1234 (any other issue tracker)| +|only references an issue/ticket|ref, refs, references, refers to| #123(only for GitHub Issues), PROJ-1234 (any other issue tracker)| + +*Example git commit message*: +``` +Fixed the pesky bug. + +This commit fixed that pesky bug that we all hated. + +resolves: PROJ-1234 +Signed-off-by: John Doe + +# Please enter the commit message for your changes. Lines starting +# with '#' will be ignored, and an empty message aborts the commit. +# +# Date: Fri Jan 10 00:00:00 2025 -0400 +# +# On branch PROJ-1234 +``` ### Signing Commits @@ -64,7 +88,11 @@ All commits must be signed-off All changes must come from a pull request (PR) and cannot be directly committed. While anyone can engage in activity on a PR, pull requests are only approved by team members. Before a pull request can be merged: - +* The PR body should contain a line similar to one of the following: + |if your pull request|use this keyword|value| + |-|-------|-----| + |resolves an issue/ticket|resolves, res, resolved| #123(only for GitHub Issues), PROJ-1234 (any other issue tracker)| + |only references an issue/ticket|ref, refs, references, refers to| #123(only for GitHub Issues), PROJ-1234 (any other issue tracker)| * The content of the PR has to be relevant to the PR itself * The contribution must follow the style guidelines of this project * Multiple commits should be used if the PR is complex and clarity can be improved, but they should still relate to a single topic diff --git a/workflows/check_commit_message_for_tickets.yml b/workflows/check_commit_message_for_tickets.yml new file mode 100644 index 0000000..2ac526c --- /dev/null +++ b/workflows/check_commit_message_for_tickets.yml @@ -0,0 +1,92 @@ +name: Check Commit Message + +on: + pull_request: + types: [opened, synchronize, edited, reopened] + +jobs: + check-commit-message: + runs-on: ubuntu-latest + env: + REGEX_PATTERN: '^(?i)(ref|refs|reference|references|res|resolve|resolves)[ \t]*:[ \t]*(gh-|\#|\!|[A-Za-z]+-)\d+\s*$' + steps: + - name: Checkout code + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + + - name: Install jq + run: sudo apt-get install jq + + - name: Fetch PR data + id: pr_data + run: | + PR_DATA=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}") + echo "PR_DATA<> $GITHUB_ENV + echo "$PR_DATA" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Check PR body + run: | + # Extract the PR body from the PR_DATA environment variable + PR_BODY=$(echo "$PR_DATA" | jq -r '.body') + echo -e "$PR_BODY" > temp_message.txt + echo -e "PR Body:\n$PR_BODY" + if grep -Pq "$REGEX_PATTERN" temp_message.txt; then + echo -e "PR body meets the requirements.\n" + exit 0 + else + echo """ + PR body does not meet the requirements. + + If PR resolves an issue or ticket, amend the PR body to + include a reference to the issue or ticket like so: + + resolves: PROJ-1234 + or + resolves: #123 (if resolving a GitHub issue) + + If PR does not resolve an issue or ticket, but is part of + work done on an issue, amend the PR body to include a + reference to the issue or ticket like so: + + reference: PROJ-1234 + or + reference: #123 (if referencing a GitHub issue) + + """ + exit 1 + fi + + + - name: Check PR commit messages + run: | + COMMIT_DATA=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/commits") + echo "$COMMIT_DATA" | jq -c '.[]' | while read -r commit; do + COMMIT_MESSAGE=$(echo "$commit" | jq -r '.commit.message') + echo -e "$COMMIT_MESSAGE" > temp_commit_message.txt + echo -e "Evaluating commit message:\n$COMMIT_MESSAGE" + if grep -Pq "$REGEX_PATTERN" temp_commit_message.txt; then + echo -e "Commit message meets the requirements.\n" + else + echo -e """ + Commit message does not meet the requirements.\ + + If commit resolves an issue or ticket, amend the commit to + include a reference to the issue or ticket like so: + + resolves: PROJ-1234 + or + resolves: #123 (if resolving a GitHub issue) + + If commit does not resolve an issue or ticket, but was + done while working on an issue, amend the commit to include + a reference to the issue or ticket like so: + + reference: PROJ-1234 + or + reference: #123 (if referencing a GitHub issue) + """ + exit 1 + fi + done