foundationdb/.github/workflows/codebuild-cleanup.yml

126 lines
4.9 KiB
YAML

name: CodeBuild Comment Cleanup
on:
issue_comment:
types: [created]
permissions:
issues: write
pull-requests: write
jobs:
cleanup:
if: >
github.event.issue.pull_request &&
github.event.comment.user.login == 'foundationdb-ci'
runs-on: ubuntu-latest
steps:
- name: Minimize Outdated Comments
uses: actions/github-script@v7
with:
script: |
// Example header: ### Result of foundationdb-pr-clang on Linux RHEL 9
// Check if header is at beginning of trimmed body
const commentBody = context.payload.comment.body.trimStart();
const match = commentBody.match(/^### Result of (.*) on (.*)$/m);
if (!match || commentBody.indexOf(match[0]) !== 0) {
console.log("Comment does not start with the expected header format. Skipping.");
return;
}
const header = match[0].trim();
// Get PR info to find the head SHA
const { data: pullRequest } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});
const headSha = pullRequest.head.sha;
console.log(`Current PR head SHA: ${headSha}`);
const allOldComments = [];
const commentsToMinimize = [];
let oldCommentAtHead = null;
console.log(`Searching for previous comments with header: "${header}"`);
for await (const { data: comments } of github.paginate.iterator(
github.rest.issues.listComments,
{
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
}
)) {
for (const comment of comments) {
if (
comment.user.login === 'foundationdb-ci' &&
comment.id !== context.payload.comment.id &&
comment.body.trimStart().startsWith(header)
) {
allOldComments.push(comment);
// Check for older comment matching PR head commit, in case reports came out-of-order.
// Default sort by created ascending, newest matching head commit wins.
const m = comment.body.match(/^\* Commit ID: ([a-f0-9]+)/m);
if (m && m[1] === headSha) {
oldCommentAtHead = comment;
}
}
}
}
const newCommentM = commentBody.match(/^\* Commit ID: ([a-f0-9]+)/m);
const newCommentSha = newCommentM ? newCommentM[1] : null;
if (newCommentSha && newCommentSha !== headSha && oldCommentAtHead) {
console.log(`New comment is for old commit (${newCommentSha}), but an older comment exists for the head commit (${headSha})`);
commentsToMinimize.push(context.payload.comment);
for (const old of allOldComments) {
if (old.id !== oldCommentAtHead.id) {
commentsToMinimize.push(old);
}
}
} else {
commentsToMinimize.push(...allOldComments);
}
console.log(`Found ${commentsToMinimize.length} comments to minimize.`);
for (const comment of commentsToMinimize) {
const checkQuery = `
query($id: ID!) {
node(id: $id) {
... on Minimizable {
isMinimized
}
}
}
`;
try {
const checkResult = await github.graphql(checkQuery, { id: comment.node_id });
if (checkResult.node.isMinimized) {
console.log(`Comment ${comment.id} is already minimized.`);
continue;
}
} catch (error) {
console.error(`Failed to check minimization status for comment ${comment.id}:`, error);
continue;
}
console.log(`Minimizing comment ${comment.id}`);
const minimizeMutation = `
mutation($id: ID!, $classifier: ReportedContentClassifiers!) {
minimizeComment(input: { subjectId: $id, classifier: $classifier }) {
minimizedComment {
isMinimized
}
}
}
`;
try {
await github.graphql(minimizeMutation, {
id: comment.node_id,
classifier: 'OUTDATED'
});
} catch (error) {
console.error(`Failed to minimize comment ${comment.id}:`, error);
}
}