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
4 changes: 1 addition & 3 deletions actions/setup/js/parse_threat_detection_results.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,6 @@ async function main() {
const runDetection = process.env.RUN_DETECTION;
const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== "false";
const detectionExecutionOutcome = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME || "";
Comment thread
pelikhan marked this conversation as resolved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

detectionExecutionOutcome is now read but has no behavioral effect — it only appears in a core.info log statement after this change.

💡 Suggested clarification

Without a comment, a future reader may wonder whether detectionExecutionFailed was accidentally dropped, or whether this variable can be removed entirely. A short note prevents that confusion:

// retained for diagnostic logging only; no longer gates conclusion (see setDetectionFailure)
const detectionExecutionOutcome = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME || "";

Downstream consumers can still distinguish the failure type via reason=agent_failure and success=false outputs, so nothing is lost behaviorally — this is purely a readability concern.

const detectionExecutionFailed = detectionExecutionOutcome === "failure";
const isWarnMode = continueOnError;

/**
Expand All @@ -464,10 +463,9 @@ async function main() {
* @param {string} message - Human-readable error message
*/
function setDetectionFailure(reason, message) {
const mustFail = detectionExecutionFailed && (reason === "agent_failure" || reason === "parse_error");
core.setOutput("reason", reason);
core.exportVariable("GH_AW_DETECTION_REASON", reason);
if (isWarnMode && !mustFail) {
if (isWarnMode) {
core.warning(`⚠️ ${message}`);
core.setOutput("conclusion", "warning");
core.exportVariable("GH_AW_DETECTION_CONCLUSION", "warning");
Expand Down
8 changes: 4 additions & 4 deletions actions/setup/js/parse_threat_detection_results.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -830,18 +830,18 @@ describe("main", () => {
expect(mockCore.setFailed).toHaveBeenCalledWith(expect.stringContaining("Detection log file not found"));
});

it("should fail when detection execution failed even in warn mode", async () => {
it("should warn when detection execution failed in warn mode", async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] The updated test covers warn mode + execution failure → warning, but there is no symmetric test for error mode (GH_AW_DETECTION_CONTINUE_ON_ERROR=false) combined with DETECTION_AGENTIC_EXECUTION_OUTCOME=failure. Adding it would document that the fix is bounded to warn mode and that strict mode still produces failure.

💡 Suggested test to add
it("should fail when detection execution failed in error mode", async () => {
  process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR = "false";
  process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME = "failure";
  mockExistsSync.mockReturnValue(false);

  await mod.main();

  expect(mockCore.setOutput).toHaveBeenCalledWith("conclusion", "failure");
  expect(mockCore.setOutput).toHaveBeenCalledWith("success", "false");
  expect(mockCore.setOutput).toHaveBeenCalledWith("reason", "agent_failure");
  expect(mockCore.exportVariable).toHaveBeenCalledWith("GH_AW_DETECTION_CONCLUSION", "failure");
  expect(mockCore.setFailed).toHaveBeenCalledWith(expect.stringContaining("Detection log file not found"));
});

This pins that DETECTION_AGENTIC_EXECUTION_OUTCOME no longer overrides warn mode and confirms strict mode is unchanged — a regression guard for both sides of the logic.

process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME = "failure";
mockExistsSync.mockReturnValue(false);

await mod.main();

expect(mockCore.setOutput).toHaveBeenCalledWith("conclusion", "failure");
expect(mockCore.setOutput).toHaveBeenCalledWith("conclusion", "warning");
expect(mockCore.setOutput).toHaveBeenCalledWith("success", "false");
expect(mockCore.setOutput).toHaveBeenCalledWith("reason", "agent_failure");
expect(mockCore.exportVariable).toHaveBeenCalledWith("GH_AW_DETECTION_CONCLUSION", "failure");
expect(mockCore.exportVariable).toHaveBeenCalledWith("GH_AW_DETECTION_CONCLUSION", "warning");
expect(mockCore.exportVariable).toHaveBeenCalledWith("GH_AW_DETECTION_REASON", "agent_failure");
expect(mockCore.setFailed).toHaveBeenCalledWith(expect.stringContaining("Detection log file not found"));
expect(mockCore.setFailed).not.toHaveBeenCalled();
});

// Note: The following tests are skipped because mocking fs for CJS modules
Expand Down
Loading