-
Notifications
You must be signed in to change notification settings - Fork 287
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
ci(check-ci-skip): fix commitMessagesMetadata.forEach is not a function #3618
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
import { readFileSync } from "fs"; | ||
|
||
//A new tag exclusively for MAINTAINERS that allows skipping the CI check | ||
import { execSync } from "child_process"; | ||
import fs from "fs"; | ||
// 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,83 @@ 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/<username>/cactus/pulls/<number>"; | ||
//const committerLogin = "<username>"; | ||
// Function to get the latest commit message | ||
const getLatestCommitMessage = () => { | ||
const commitMsgBuffer = execSync("git log -1 --pretty=%B"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @petermetz to answer your question, this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @zondervancalvez I'll post a screenshot here with the question(s). Maybe you posted the answers somewhere else and I just couldn't find it? Pull request comments/reviews get confusing quick. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @petermetz I added There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @zondervancalvez OK, but would that then mean that the skip CI marker does not work anymore? What I mean is that the .js script currently exists with a job failure when it is trying to indicate that the CI should be skipped. But with So I'm thinking you need to refactor the .js script to use a different signaling mechanism where it succeeds as long as there was no crash in it, and it places the information about the CI being skipped or not into some other context variable (which must not be writeable by pull request code because then people could just hack it by writing to this place where we store the information about the CI being skipped or not) if (isMaintainer) {
console.log(
"CI skipped as per request. Exit with an error to PAUSE dependent workflows.",
);
process.exit(1);
} else {
process.exit(0);
} |
||
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; | ||
}; | ||
|
||
commitMessagesMetadata.forEach((commitMessageMetadata) => { | ||
// get commit message body | ||
commitMessageList.push(commitMessageMetadata["commit"]["message"]); | ||
}); | ||
// 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; | ||
}; | ||
|
||
// 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; | ||
} | ||
}; | ||
// Main function to determine whether to skip CI or proceed | ||
const main = async () => { | ||
const markdownContent = getMaintainersFileContent(); | ||
const committerLogin = getCommitterLogin(); | ||
const commitMessage = getLatestCommitMessage(); | ||
const outputPath = process.env.GITHUB_OUTPUT; | ||
const shouldSkipCI = checkSkipCI(commitMessage); | ||
fs.appendFileSync(outputPath, `should_skip=${shouldSkipCI}\n`); | ||
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(); | ||
|
||
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 | ||
} | ||
const isMaintainer = checkCommitterIsMaintainer( | ||
committerLogin, | ||
activeMaintainers, | ||
); | ||
fs.appendFileSync(outputPath, `should_skip=${isMaintainer}\n`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see |
||
if (isMaintainer) { | ||
console.log( | ||
"CI skipped as per request. Exit with an error to PAUSE dependent workflows.", | ||
); | ||
process.exit(0); | ||
} else { | ||
console.log("No skip requested. Proceeding with CI."); | ||
process.exit(0); // Exit successfully to run CI | ||
process.exit(0); | ||
} | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please refactor this terminology everywhere. Instead of calling it
commiterLogin
call it something which is more easily understandable (likecommitAuthor
)