diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c87fe815255..c90ef382ad5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,9 +16,11 @@ env: RUN_CODE_COVERAGE: true jobs: ActionLint: + needs: check-ci-skip uses: ./.github/workflows/actionlint.yaml DCI-Lint: name: DCI-Lint + needs: check-ci-skip runs-on: ubuntu-22.04 steps: - id: lint-git-repo @@ -29,7 +31,15 @@ jobs: - name: Get the output response run: echo "${{ steps.lint-git-repo.outputs.lint-git-repo-response }}" + check-ci-skip: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4.1.7 + - name: Check CI Skip + run: node tools/should-skip-ci.js ${{ github.event.pull_request.url }} ${{ github.event.pull_request.user.login }} + check-coverage: + needs: check-ci-skip outputs: run-coverage: ${{ steps.set-output.outputs.run-coverage }} runs-on: ubuntu-22.04 @@ -40,6 +50,7 @@ jobs: run: echo "run-coverage=${{ env.RUN_CODE_COVERAGE }}" >> "$GITHUB_OUTPUT" compute_changed_packages: + needs: check-ci-skip outputs: cmd-api-server-changed: ${{ steps.changes.outputs.cmd-api-server-changed }} plugin-ledger-connector-polkadot-changed: ${{ steps.changes.outputs.plugin-ledger-connector-polkadot-changed }} @@ -164,6 +175,7 @@ jobs: # - './.github/workflows/ci.yaml' build-dev: + needs: check-ci-skip continue-on-error: false env: DEV_BUILD_DISABLED: false @@ -2627,6 +2639,7 @@ jobs: ignore-unfixed: false vuln-type: 'os,library' severity: 'CRITICAL,HIGH' + name: Cactus_CI 'on': pull_request: @@ -2637,4 +2650,5 @@ name: Cactus_CI push: branches: - main - - dev \ No newline at end of file + - dev + \ No newline at end of file diff --git a/tools/should-skip-ci.js b/tools/should-skip-ci.js new file mode 100644 index 00000000000..9a7d24cbad3 --- /dev/null +++ b/tools/should-skip-ci.js @@ -0,0 +1,95 @@ +import { readFileSync } from "fs"; + +const SKIP_CACTI = "skip-cacti-ci"; +const MaintainersFile = "MAINTAINERS.md"; +//regular expression to get the maintainers in MAINTAINERS.md +const MAINTAINERS_REGEX = + /\|\s*([A-Za-z\s]+)\s*\|\s*\[([^\]]+)\]\[[^\]]+\]\s*\|\s*([A-Za-z0-9_-]+|-)*/g; + +const main = async () => { + const markdownContent = readFileSync(MaintainersFile, "utf-8"); + + const args = process.argv.slice(2); + const pullReqUrl = args[0]; + const committerLogin = args[1]; + + //Uncomment these lines for local machine testing purposes: + //const pullReqUrl = "https://api.github.com/repos/zondervancalvez/cactus/pulls/7"; + //const committerLogin = "zondervancalvez"; + + const fetchJsonFromUrl = async (url) => { + const fetchResponse = await fetch(url); + return fetchResponse.json(); + }; + + let commitMessageList = []; + const commitMessagesMetadata = await fetchJsonFromUrl( + pullReqUrl + "/commits", + ); + + commitMessagesMetadata.forEach((commitMessageMetadata) => { + // get commit message body + commitMessageList.push(commitMessageMetadata["commit"]["message"]); + }); + + // 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; + } + }; + + // 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("Committer is a trusted Maintainer."); + return true; + } else { + console.log("Committer is not a Maintainer."); + return false; + } + }; + + // Main logic + + const shouldSkipCI = checkSkipCI(); + + if (shouldSkipCI) { + const isMaintainer = checkCommitterIsMaintainer(); + if (isMaintainer) { + console.log("CI skipped as per request."); + process.exit(1); // Exit successfully to skip CI + } else { + console.log("CI will not be skipped."); // Continue run CI + } + } else { + console.log("No skip requested. Proceeding with CI."); + process.exit(0); // Exit successfully to run CI + } +}; + +// Run the main function +main();