diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5f3c1e4eff..175196c61b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -36,7 +36,7 @@ jobs: steps: - uses: actions/checkout@v4.1.7 - name: Check CI Skip - run: node tools/ci-skip-for-maintainers.js ${{ github.event.pull_request.url }} ${{ github.event.pull_request.user.login }} + run: node tools/ci-skip-for-maintainers.js ${{ github.event.pull_request.user.login }} check-coverage: needs: check-ci-skip diff --git a/tools/ci-skip-for-maintainers.js b/tools/ci-skip-for-maintainers.js index 911c637ca4..197b4f1082 100644 --- a/tools/ci-skip-for-maintainers.js +++ b/tools/ci-skip-for-maintainers.js @@ -1,9 +1,9 @@ import { readFileSync } from "fs"; +import { execSync } from "child_process"; -//A new tag exclusively for MAINTAINERS that allows skipping the CI check +// Constants const SKIP_CACTI = "skip-cacti-ci"; const MaintainersFile = "MAINTAINERS.md"; -//regular expression to get the maintainers in MAINTAINERS.md const NAMES_REGEX = /\|\s*([A-Za-z\s]+)\s*/; const LINKS_REGEX = /\|\s*\[([^\]]+)\]\[[^\]]+\]\s*/; const TAGS_REGEX = /\|\s*([A-Za-z0-9_-]+|-)*\s*/; @@ -12,90 +12,82 @@ const MAINTAINERS_REGEX = new RegExp( "g", ); -const main = async () => { - const markdownContent = readFileSync(MaintainersFile, "utf-8"); +const getMaintainersFileContent = () => readFileSync(MaintainersFile, "utf-8"); - const args = process.argv.slice(2); - const pullReqUrl = args[0]; - const committerLogin = args[1]; +// Function to get the latest commit message author +const getCommitterLogin = () => { + const authorBuffer = execSync("git log -1 | grep Author | cut -d' ' -f2"); + const authorString = authorBuffer.toString(); + const authorStringTrim = authorString.trim(); + return authorStringTrim; +}; - //Uncomment these lines and change it for local machine testing purposes: - //const pullReqUrl = "https://api.github.com/repos//cactus/pulls/"; - //const committerLogin = ""; +// Function to get the latest commit message +const getLatestCommitMessage = () => { + const commitMsgBuffer = execSync("git log -1 --pretty=%B"); + const commitMsgString = commitMsgBuffer.toString(); + const commitMsgTrim = commitMsgString.trim(); + return commitMsgTrim; +}; - const fetchJsonFromUrl = async (url) => { - const fetchResponse = await fetch(url); - return fetchResponse.json(); - }; +// Function to check if SKIP_CACTI tag is in the commit message +const checkSkipCI = (commitMessage) => { + if (commitMessage.includes(SKIP_CACTI)) { + console.log("Skip requested in commit message."); + return true; + } + console.log("No skip request found."); + return false; +}; - let commitMessageList = []; - const commitMessagesMetadata = await fetchJsonFromUrl( - pullReqUrl + "/commits", +// Function to extract maintainers from the MAINTAINERS.md file content +const extractMaintainers = (maintainerMetaData) => { + let match; + const maintainers = []; + while ((match = MAINTAINERS_REGEX.exec(maintainerMetaData)) !== null) { + const github = match[2]; + maintainers.push(github); + } + return maintainers; +}; + +// Function to check if committer is an active maintainer +const checkCommitterIsMaintainer = (committerLogin, activeMaintainers) => { + if (activeMaintainers.includes(committerLogin)) { + console.log("The author of this PR is an active maintainer."); + return true; + } + console.log( + "CI will not be skipped. \nThe author of this PR is not an active maintainer.\nPlease refer to https://github.com/hyperledger/cacti/blob/main/MAINTAINERS.md for the list of active maintainers.", ); + return false; +}; - commitMessagesMetadata.forEach((commitMessageMetadata) => { - // get commit message body - commitMessageList.push(commitMessageMetadata["commit"]["message"]); - }); +// Main function to determine whether to skip CI or proceed +const main = async () => { + const markdownContent = getMaintainersFileContent(); + const committerLogin = getCommitterLogin(); + const commitMessage = getLatestCommitMessage(); - // Check if skip-ci is found in commit message - const checkSkipCI = () => { - for (let commitMessageListIndex in commitMessageList) { - let commitMessage = commitMessageList[commitMessageListIndex]; - if (commitMessage.includes(SKIP_CACTI)) { - console.log("Skip requested in commit message."); - return true; - } else { - console.log("No skip request found."); - } - return false; - } - }; + const shouldSkipCI = checkSkipCI(commitMessage); + if (!shouldSkipCI) { + console.log("No skip requested. Proceeding with CI."); + process.exit(0); + } - // Function to extract active maintainers - const extractMaintainers = (maintainerMetaData) => { - let match; - const maintainers = []; - while ((match = MAINTAINERS_REGEX.exec(maintainerMetaData)) !== null) { - const github = match[2]; - maintainers.push(github); - } - return maintainers; - }; - // Get the maintainers const activeMaintainers = extractMaintainers(markdownContent); - activeMaintainers.forEach((maintainers) => { - maintainers; - }); - - // Check if committer is a trusted maintainer - const checkCommitterIsMaintainer = () => { - if (activeMaintainers.includes(committerLogin)) { - console.log("The author of this PR is an active maintainer."); - return true; - } else { - console.log( - "CI will not be skipped. \nThe author of this PR is not an active maintainer.\nPlease refer to https://github.com/hyperledger/cacti/blob/main/MAINTAINERS.md for the list of active maintainers.", - ); - return false; - } - }; - - // Main logic - - const shouldSkipCI = checkSkipCI(); + const isMaintainer = checkCommitterIsMaintainer( + committerLogin, + activeMaintainers, + ); - if (shouldSkipCI) { - const isMaintainer = checkCommitterIsMaintainer(); - if (isMaintainer) { - console.log( - "Exit with an error code so as to pause the dependent workflows. CI skipped as per request.", - ); - process.exit(1); // Exit successfully to skip CI - } + if (isMaintainer) { + console.log( + "CI skipped as per request. Exit with an error to PAUSE dependent workflows.", + ); + process.exit(1); } else { - console.log("No skip requested. Proceeding with CI."); - process.exit(0); // Exit successfully to run CI + process.exit(0); } };