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/fix-report-incomplete-conclusion.md

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

3 changes: 3 additions & 0 deletions actions/setup/js/handle_agent_failure.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3577,6 +3577,9 @@ async function main() {
for (const item of reportIncompleteItems) {
core.info(` report_incomplete reason: ${item.reason}`);
}
// Continue after marking the step failed so optional issue reporting can still run.
// eslint-disable-next-line gh-aw-custom/require-return-after-core-setfailed
core.setFailed("Agent reported that it could not complete the task");
}
}
}
Expand Down
37 changes: 35 additions & 2 deletions actions/setup/js/handle_agent_failure.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4836,7 +4836,8 @@ describe("handle_agent_failure", () => {
expect(createCommentMock).not.toHaveBeenCalled();
});

it("still creates failure issue when terminal_reason: completed but report_incomplete is also present", async () => {
it("keeps the step failed when failure issue creation fails after a successful agent reports incomplete", async () => {
process.env.GH_AW_AGENT_CONCLUSION = "success";
// Agent produced both a non-noop item and a report_incomplete signal
fs.writeFileSync(
path.join(tmpDir, "agent_output.json"),
Expand All @@ -4849,7 +4850,9 @@ describe("handle_agent_failure", () => {
);
fs.writeFileSync(path.join(tmpDir, "agent-stdio.log"), '{"type":"result","subtype":"success","terminal_reason":"completed","num_turns":10}\n');

const createIssueMock = vi.fn(async () => ({ data: { number: 101, html_url: "https://github.com/owner/repo/issues/101", node_id: "I_123" } }));
const createIssueMock = vi.fn(async () => {
throw new Error("issue creation failed");
});
const createCommentMock = vi.fn(async () => ({ data: { id: 1001 } }));

global.github = {
Expand All @@ -4875,6 +4878,36 @@ describe("handle_agent_failure", () => {

// report_incomplete overrides the hasCompletedDespiteJobFailure exemption
expect(createIssueMock).toHaveBeenCalled();
expect(global.core.setFailed).toHaveBeenCalledWith("Agent reported that it could not complete the task");
expect(global.core.warning).toHaveBeenCalledWith("Failed to create or update failure tracking issue: issue creation failed");
});

it("marks the step failed when failure issue reporting is disabled", async () => {
process.env.GH_AW_AGENT_CONCLUSION = "success";
process.env.GH_AW_FAILURE_REPORT_AS_ISSUE = "false";
fs.writeFileSync(path.join(tmpDir, "agent_output.json"), JSON.stringify({ items: [{ type: "report_incomplete", reason: "mcp_crash" }] }));

const createIssueMock = vi.fn();
global.github = {
rest: {
search: {
issuesAndPullRequests: vi.fn(),
},
issues: {
create: createIssueMock,
createComment: vi.fn(),
},
pulls: { get: vi.fn() },
},
graphql: vi.fn(),
};

vi.resetModules();
const { main: mainFn } = require("./handle_agent_failure.cjs");
await mainFn();
Comment on lines +4905 to +4907

expect(global.core.setFailed).toHaveBeenCalledWith("Agent reported that it could not complete the task");
expect(createIssueMock).not.toHaveBeenCalled();
});

it("ignores report_incomplete when it only describes task_complete registration trouble after successful outputs", async () => {
Expand Down
Loading