Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/patch-resolve-add-comment-temp-id.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 17 additions & 4 deletions actions/setup/js/add_comment.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

const { generateFooterWithMessages } = require("./messages_footer.cjs");
const { getRepositoryUrl } = require("./get_repository_url.cjs");
const { replaceTemporaryIdReferences } = require("./temporary_id.cjs");
const { replaceTemporaryIdReferences, loadTemporaryIdMapFromResolved, resolveRepoIssueTarget } = require("./temporary_id.cjs");
Comment thread
mnkiefer marked this conversation as resolved.
const { getTrackerID } = require("./get_tracker_id.cjs");
const { getErrorMessage } = require("./error_helpers.cjs");
const { resolveTarget } = require("./safe_output_helpers.cjs");
Expand Down Expand Up @@ -351,17 +351,30 @@ async function main(config = {}) {

// Check if item_number was explicitly provided in the message
if (item.item_number !== undefined && item.item_number !== null) {
// Use the explicitly provided item_number
itemNumber = typeof item.item_number === "number" ? item.item_number : parseInt(String(item.item_number), 10);
// Resolve temporary IDs if present
const resolvedTarget = resolveRepoIssueTarget(item.item_number, temporaryIdMap, repoParts.owner, repoParts.repo);

if (isNaN(itemNumber) || itemNumber <= 0) {
// Check if this is an unresolved temporary ID
if (resolvedTarget.wasTemporaryId && !resolvedTarget.resolved) {
core.info(`Deferring add_comment: unresolved temporary ID (${item.item_number})`);
return {
success: false,
deferred: true,
error: resolvedTarget.errorMessage || `Unresolved temporary ID: ${item.item_number}`,
};
}

// Check for other resolution errors (including null resolved)
if (resolvedTarget.errorMessage || !resolvedTarget.resolved) {
core.warning(`Invalid item_number specified: ${item.item_number}`);
return {
success: false,
error: `Invalid item_number specified: ${item.item_number}`,
};
Comment thread
mnkiefer marked this conversation as resolved.
}

// Use the resolved issue number (safe to access because we checked above)
itemNumber = resolvedTarget.resolved.number;
core.info(`Using explicitly provided item_number: #${itemNumber}`);
} else {
// Check if this is a discussion context
Expand Down
146 changes: 146 additions & 0 deletions actions/setup/js/add_comment.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -952,4 +952,150 @@ describe("add_comment", () => {
expect(graphqlCallCount).toBe(1);
});
});

describe("temporary ID resolution", () => {
it("should resolve temporary ID in item_number field", async () => {
const addCommentScript = fs.readFileSync(path.join(__dirname, "add_comment.cjs"), "utf8");

let capturedIssueNumber = null;
mockGithub.rest.issues.createComment = async params => {
capturedIssueNumber = params.issue_number;
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",
item_number: "aw_test01",
body: "Comment on issue created with temporary ID",
};

// Provide resolved temporary ID
const resolvedTemporaryIds = {
aw_test01: { repo: "owner/repo", number: 42 },
};

const result = await handler(message, resolvedTemporaryIds);

expect(result.success).toBe(true);
expect(capturedIssueNumber).toBe(42);
expect(result.itemNumber).toBe(42);
});

it("should defer when temporary ID is not yet resolved", async () => {
const addCommentScript = fs.readFileSync(path.join(__dirname, "add_comment.cjs"), "utf8");

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

const message = {
type: "add_comment",
item_number: "aw_test99",
body: "Comment on issue with unresolved temporary ID",
};

// Empty resolved map - temporary ID not yet resolved
const resolvedTemporaryIds = {};

const result = await handler(message, resolvedTemporaryIds);
Comment thread
mnkiefer marked this conversation as resolved.

expect(result.success).toBe(false);
expect(result.deferred).toBe(true);
expect(result.error).toContain("aw_test99");
});

it("should handle temporary ID with hash prefix", async () => {
const addCommentScript = fs.readFileSync(path.join(__dirname, "add_comment.cjs"), "utf8");

let capturedIssueNumber = null;
mockGithub.rest.issues.createComment = async params => {
capturedIssueNumber = params.issue_number;
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",
item_number: "#aw_test02",
body: "Comment with hash prefix",
};

// Provide resolved temporary ID
const resolvedTemporaryIds = {
aw_test02: { repo: "owner/repo", number: 100 },
};

const result = await handler(message, resolvedTemporaryIds);

expect(result.success).toBe(true);
expect(capturedIssueNumber).toBe(100);
});

it("should handle invalid temporary ID format", async () => {
const addCommentScript = fs.readFileSync(path.join(__dirname, "add_comment.cjs"), "utf8");

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

const message = {
type: "add_comment",
item_number: "aw_", // Invalid: too short
body: "Comment with invalid temporary ID",
};

const resolvedTemporaryIds = {};

const result = await handler(message, resolvedTemporaryIds);

expect(result.success).toBe(false);
expect(result.error).toContain("Invalid item_number specified");
});

it("should replace temporary IDs in comment body", async () => {
const addCommentScript = fs.readFileSync(path.join(__dirname, "add_comment.cjs"), "utf8");

let capturedBody = null;
mockGithub.rest.issues.createComment = async params => {
capturedBody = params.body;
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",
item_number: 42,
body: "References: #aw_test01 and #aw_test02",
};

// Provide resolved temporary IDs
const resolvedTemporaryIds = {
aw_test01: { repo: "owner/repo", number: 100 },
aw_test02: { repo: "owner/repo", number: 200 },
};

const result = await handler(message, resolvedTemporaryIds);

expect(result.success).toBe(true);
expect(capturedBody).toContain("#100");
expect(capturedBody).toContain("#200");
expect(capturedBody).not.toContain("aw_test01");
expect(capturedBody).not.toContain("aw_test02");
});
});
});