From f540f8e4089a16310c9017894c05c2f18a087b2f Mon Sep 17 00:00:00 2001 From: jagpreetsinghsasan Date: Tue, 23 Jul 2024 18:58:57 +0530 Subject: [PATCH] ci(github): workflow to ensure PR commit parity Primary Changes --------------- 1. Added a script which ensures PR body and commit message parity Changes needed to incorporate 1) -------------------------------- 2. Added a new workflow to enable the same Fixes #2214 Signed-off-by: jagpreetsinghsasan --- .github/workflows/pr-commit-parity.yaml | 28 ++++++++++++ tools/pr-commit-parity.js | 61 +++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 .github/workflows/pr-commit-parity.yaml create mode 100644 tools/pr-commit-parity.js diff --git a/.github/workflows/pr-commit-parity.yaml b/.github/workflows/pr-commit-parity.yaml new file mode 100644 index 00000000000..4ebab64da54 --- /dev/null +++ b/.github/workflows/pr-commit-parity.yaml @@ -0,0 +1,28 @@ +--- +name: PR - Commit Parity +'on': + pull_request: + branches: + - main + - dev + - petermetz/** + push: + branches: + - main + - dev + +jobs: + pr-commit-parity: + name: PR and Commit messages Parity + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3.1.0 + - name: Use Node.js v18.18.2 + uses: actions/setup-node@v4.0.2 + with: + node-version: v18.19.0 + - name: Execute script + id: execute-script + run: | + PR_COMMIT_PARITY_OUTPUT=$(node tools/pr-commit-parity.js ${{ github.event.pull_request.url }}) + echo "PR_COMMIT_PARITY_OUTPUT=$PR_COMMIT_PARITY_OUTPUT" >> "$GITHUB_OUTPUT" \ No newline at end of file diff --git a/tools/pr-commit-parity.js b/tools/pr-commit-parity.js new file mode 100644 index 00000000000..a61611157fd --- /dev/null +++ b/tools/pr-commit-parity.js @@ -0,0 +1,61 @@ +export async function fetchJsonFromUrl(url) { + const fetchResponse = await fetch(url); + return fetchResponse.json(); +} + +//regex expressions +const PULL_REQ_REQUIREMENTS_REGEX = /\*\*Pull\sRequest\sRequirements(.|\n)*/gim; +const FIXES_OR_DEPENDS_REGEX = /(Fixes|Depends)(.|\n)*/gim; +const SIGNED_OFF_REGEX = /(")*Signed-off-by:(.|\s)*/gim; +const HYPHEN_REGEX = /(-)+/gm; +const BACKTICK_REGEX = /`+/gm; +const SPACE_REGEX = / +/gm; +const COMMIT_TO_BE_REVIEWED_REGEX = /("#*\s*Commit\sto\sbe\sreviewed)/gim; +const WHITESPACES_HARDCODED_REGEX = /(\r\n|\n|\r|\\r|\\n)/gm; + +const args = process.argv.slice(2); +const pullReqUrl = args[0]; + +const prMetadata = await fetchJsonFromUrl(pullReqUrl); +const prBodyRaw = JSON.stringify(prMetadata.body); + +let commitMessageList = []; +const commitMessagesMetadata = await fetchJsonFromUrl(pullReqUrl + "/commits"); + +commitMessagesMetadata.forEach((commitMessageMetadata) => { + commitMessageList.push( + commitMessageMetadata["commit"]["message"] + .replace(SIGNED_OFF_REGEX, "") + .replace(HYPHEN_REGEX, "") + .replace(BACKTICK_REGEX, ""), + ); +}); + +let prBodyStriped = prBodyRaw + .replace(PULL_REQ_REQUIREMENTS_REGEX, "") + .replace(FIXES_OR_DEPENDS_REGEX, "") + .replace(WHITESPACES_HARDCODED_REGEX, "") + .replace(SIGNED_OFF_REGEX, "") + .replace(HYPHEN_REGEX, "") + .replace(BACKTICK_REGEX, "") + .replace(COMMIT_TO_BE_REVIEWED_REGEX, "") + .replace(SPACE_REGEX, " "); + +let PR_BODY_IN_COMMIT_MESSAGES = false; +for (let commitMessageListIndex in commitMessageList) { + let commitMessage = commitMessageList[commitMessageListIndex] + .replace(WHITESPACES_HARDCODED_REGEX, "") + .replace(FIXES_OR_DEPENDS_REGEX, "") + .replace(SPACE_REGEX, " "); + if (commitMessage == prBodyStriped) PR_BODY_IN_COMMIT_MESSAGES = true; +} + +if (!PR_BODY_IN_COMMIT_MESSAGES) { + console.error( + "PR Body does not match any existing commit message\n" + + "Please make sure that the PR Body matches to minimum one of the commit messages\n" + + "Please refer the following PR for reference: https://github.com/hyperledger/cacti/pull/3338\n" + + "And the commit message here: https://github.com/hyperledger/cacti/pull/3338/commits/47ebdec442d30fa48c8518b876c47c38097cf028\n", + ); + process.exit(-1); +}