Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(github): add knob/flag to manually override CI skip #3574

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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/ci-skip-for-maintainers.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
Expand All @@ -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 }}
Expand Down Expand Up @@ -164,6 +175,7 @@ jobs:
# - './.github/workflows/ci.yaml'

build-dev:
needs: check-ci-skip
continue-on-error: false
env:
DEV_BUILD_DISABLED: false
Expand Down Expand Up @@ -2627,6 +2639,7 @@ jobs:
ignore-unfixed: false
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH'

name: Cactus_CI
'on':
pull_request:
Expand All @@ -2637,4 +2650,5 @@ name: Cactus_CI
push:
branches:
- main
- dev
- dev

103 changes: 103 additions & 0 deletions tools/ci-skip-for-maintainers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { readFileSync } from "fs";

//A new tag exclusively for MAINTAINERS that allows skipping the CI check
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*/;
const MAINTAINERS_REGEX = new RegExp(
NAMES_REGEX.source + LINKS_REGEX.source + TAGS_REGEX.source,
"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 and change it for local machine testing purposes:
//const pullReqUrl = "https://api.github.com/repos/<username>/cactus/pulls/<number>";
//const committerLogin = "<username>";

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("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();

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
}
} else {
console.log("No skip requested. Proceeding with CI.");
process.exit(0); // Exit successfully to run CI
}
};

// Run the main function
main();
Loading