Skip to content
Closed
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
47 changes: 40 additions & 7 deletions actions/setup/js/add_comment.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,38 @@ async function minimizeComment(github, nodeId, reason = "outdated") {
};
}

/**
* Check if a comment should be hidden by the hideOlderComments function
* @param {string} commentBody - The comment body text
* @param {string} workflowId - The workflow ID to match
* @returns {boolean} true if the comment should be hidden, false otherwise
*/
function shouldHideComment(commentBody, workflowId) {
if (!commentBody) {
return false;
}

// Comment must have the workflow-id marker
const hasWorkflowId = commentBody.includes(`<!-- gh-aw-workflow-id: ${workflowId} -->`);
if (!hasWorkflowId) {
return false;
}

// Exclude reaction comments (activation comments)
const isReactionComment = commentBody.includes(`<!-- gh-aw-comment-type: reaction -->`);
if (isReactionComment) {
return false;
}

// Exclude append-only comments (should persist across runs)
const isAppendOnlyComment = commentBody.includes(`<!-- gh-aw-comment-type: append-only -->`);
if (isAppendOnlyComment) {
return false;
}

return true;
}

/**
* Find comments on an issue/PR with a specific tracker-id
* @param {any} github - GitHub REST API instance
Expand Down Expand Up @@ -66,10 +98,8 @@ async function findCommentsWithTrackerId(github, owner, repo, issueNumber, workf
break;
}

// Filter comments that contain the workflow-id and are NOT reaction comments
const filteredComments = data
.filter(comment => comment.body?.includes(`<!-- gh-aw-workflow-id: ${workflowId} -->`) && !comment.body.includes(`<!-- gh-aw-comment-type: reaction -->`))
.map(({ id, node_id, body }) => ({ id, node_id, body }));
// Filter comments that should be hidden
const filteredComments = data.filter(comment => shouldHideComment(comment.body, workflowId)).map(({ id, node_id, body }) => ({ id, node_id, body }));

comments.push(...filteredComments);

Expand Down Expand Up @@ -122,9 +152,7 @@ async function findDiscussionCommentsWithTrackerId(github, owner, repo, discussi
break;
}

const filteredComments = result.repository.discussion.comments.nodes
.filter(comment => comment.body?.includes(`<!-- gh-aw-workflow-id: ${workflowId} -->`) && !comment.body.includes(`<!-- gh-aw-comment-type: reaction -->`))
.map(({ id, body }) => ({ id, body }));
const filteredComments = result.repository.discussion.comments.nodes.filter(comment => shouldHideComment(comment.body, workflowId)).map(({ id, body }) => ({ id, body }));

comments.push(...filteredComments);

Expand Down Expand Up @@ -414,6 +442,11 @@ async function main(config = {}) {
processedBody += "\n\n" + trackerIDComment;
}

// Add append-only marker if enabled to prevent hiding by future runs
if (appendOnlyComments) {
processedBody += "\n\n<!-- gh-aw-comment-type: append-only -->";
}

const workflowName = process.env.GH_AW_WORKFLOW_NAME || "Workflow";
const runId = context.runId;
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}`;
Expand Down
109 changes: 109 additions & 0 deletions actions/setup/js/add_comment.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -527,5 +527,114 @@ describe("add_comment", () => {
// Clean up
delete process.env.GITHUB_WORKFLOW;
});

it("should include append-only marker in comment body when append-only-comments is enabled", async () => {
const addCommentScript = fs.readFileSync(path.join(__dirname, "add_comment.cjs"), "utf8");

// Set up environment variable for append-only-comments
process.env.GH_AW_SAFE_OUTPUT_MESSAGES = JSON.stringify({
appendOnlyComments: true,
});
process.env.GITHUB_WORKFLOW = "test-workflow";

let capturedComment = null;
mockGithub.rest.issues.createComment = async params => {
capturedComment = params;
return {
data: {
id: 12345,
html_url: `https://github.com/owner/repo/issues/${params.issue_number}#issuecomment-12345`,
},
};
};

const handler = await eval(`(async () => { ${addCommentScript}; return await main({}); })()`);

const message = {
type: "add_comment",
body: "Append-only comment",
};

const result = await handler(message, {});

expect(result.success).toBe(true);
expect(capturedComment).toBeTruthy();
expect(capturedComment.body).toContain("<!-- gh-aw-comment-type: append-only -->");

// Clean up
delete process.env.GH_AW_SAFE_OUTPUT_MESSAGES;
delete process.env.GITHUB_WORKFLOW;
});

it("should not hide append-only comments from previous runs", async () => {
const addCommentScript = fs.readFileSync(path.join(__dirname, "add_comment.cjs"), "utf8");

// Set up environment WITHOUT append-only-comments (new run)
delete process.env.GH_AW_SAFE_OUTPUT_MESSAGES;
process.env.GITHUB_WORKFLOW = "test-workflow";

let hideCommentsWasCalled = false;
let hiddenCommentIds = [];

// Simulate finding an old append-only comment and a regular comment
mockGithub.rest.issues.listComments = async () => {
return {
data: [
{
id: 888,
node_id: "IC_kwDOTest888",
body: "Old append-only comment <!-- gh-aw-workflow-id: test-workflow --><!-- gh-aw-comment-type: append-only -->",
},
{
id: 999,
node_id: "IC_kwDOTest999",
body: "Old regular comment <!-- gh-aw-workflow-id: test-workflow -->",
},
],
};
};

mockGithub.graphql = async (query, variables) => {
if (query.includes("minimizeComment")) {
hideCommentsWasCalled = true;
hiddenCommentIds.push(variables.nodeId);
}
return {
minimizeComment: {
minimizedComment: {
isMinimized: true,
},
},
};
};

mockGithub.rest.issues.createComment = async params => {
return {
data: {
id: 12345,
html_url: `https://github.com/owner/repo/issues/${params.issue_number}#issuecomment-12345`,
},
};
};

// Execute with hide-older-comments enabled (but not append-only)
const handler = await eval(`(async () => { ${addCommentScript}; return await main({ hide_older_comments: true }); })()`);

const message = {
type: "add_comment",
body: "New comment",
};

const result = await handler(message, {});

expect(result.success).toBe(true);
expect(hideCommentsWasCalled).toBe(true);
// Should only hide the regular comment, not the append-only comment
expect(hiddenCommentIds).toEqual(["IC_kwDOTest999"]);
expect(hiddenCommentIds).not.toContain("IC_kwDOTest888");

// Clean up
delete process.env.GITHUB_WORKFLOW;
});
});
});