feat: add rollback_on_failure feature #88

Merged
Philipp merged 3 commits from feature/rollback-on-failure into main 2026-05-17 13:13:59 +02:00
3 changed files with 102 additions and 53 deletions
Showing only changes of commit dce79ba192 - Show all commits
+73 -22
View File
@@ -20,6 +20,23 @@ vi.mock("../monitor.js", () => ({
}),
}));
// Mock screeps-api
vi.mock("screeps-api", () => {
const mockApi = {
auth: vi.fn().mockResolvedValue(),
code: {
get: vi.fn().mockResolvedValue({ ok: 1, modules: { main: "old_code" } }),
set: vi.fn().mockResolvedValue({ ok: 1 }),
},
};
// Use a regular function so it can be called with `new`
return {
ScreepsAPI: vi.fn(function () {
return mockApi;
}),
};
});
import * as core from "@actions/core";
import { monitorConsole } from "../monitor.js";
@@ -29,7 +46,9 @@ import {
readReplaceAndWriteFiles,
readFilesIntoDict,
applyOnAction,
postCode,
} from "../index.js";
import { ScreepsAPI } from "screeps-api";
import fs from "fs";
import path from "path";
import os from "os";
@@ -231,31 +250,31 @@ describe("glob functionality", () => {
describe("applyOnAction", () => {
beforeEach(() => vi.clearAllMocks());
it("'ignore' + true → no core call", () => {
applyOnAction("ignore", true, "msg");
it("'ignore' + true → no core call, returns false", () => {
expect(applyOnAction("ignore", true, "msg")).toBe(false);
expect(core.warning).not.toHaveBeenCalled();
expect(core.setFailed).not.toHaveBeenCalled();
});
it("'warn' + true → core.warning() called with message", () => {
applyOnAction("warn", true, "boom");
it("'warn' + true → core.warning() called with message, returns false", () => {
expect(applyOnAction("warn", true, "boom")).toBe(false);
expect(core.warning).toHaveBeenCalledWith("boom");
expect(core.setFailed).not.toHaveBeenCalled();
});
it("'fail' + true → core.setFailed() called with message", () => {
applyOnAction("fail", true, "boom");
it("'fail' + true → core.setFailed() called with message, returns true", () => {
expect(applyOnAction("fail", true, "boom")).toBe(true);
expect(core.setFailed).toHaveBeenCalledWith("boom");
expect(core.warning).not.toHaveBeenCalled();
});
it("'fail' + false → no core call", () => {
applyOnAction("fail", false, "boom");
it("'fail' + false → no core call, returns false", () => {
expect(applyOnAction("fail", false, "boom")).toBe(false);
expect(core.setFailed).not.toHaveBeenCalled();
});
it("'warn' + false → no core call", () => {
applyOnAction("warn", false, "msg");
it("'warn' + false → no core call, returns false", () => {
expect(applyOnAction("warn", false, "msg")).toBe(false);
expect(core.warning).not.toHaveBeenCalled();
});
});
@@ -270,28 +289,60 @@ describe("postCode — monitor wiring", () => {
// Default core mocks
core.getInput.mockImplementation((name) => {
if (name === "monitor") return "0";
if (name === "token") return "test-token";
if (name === "branch") return "default";
if (name === "on_traceback") return "fail";
return "";
});
core.getBooleanInput.mockReturnValue(false);
core.getBooleanInput.mockImplementation((name) => {
if (name === "rollback_on_failure") return false;
return false;
});
});
it("does not call monitorConsole when monitor=0 (default)", async () => {
// We need to mock the rest of postCode to not fail before it hits the monitor block
// This is a bit complex as postCode is large, but we can mock the inputs to exit early or mock the API
// Actually, I'll just check if monitorConsole is called.
// We just run postCode with monitor=0 and verify monitorConsole is not called.
await postCode();
expect(monitorConsole).not.toHaveBeenCalled();
});
// For this test, I'll make validateAuthentication fail so it returns early but after input check
it("rolls back to previous code when monitor detects a failure and rollback_on_failure is true", async () => {
// Setup inputs for monitor and rollback
core.getInput.mockImplementation((name) => {
if (name === "monitor") return "0";
if (name === "monitor") return "10";
if (name === "token") return "test-token";
if (name === "branch") return "default";
if (name === "on_traceback") return "fail";
return "";
});
core.getBooleanInput.mockImplementation((name) => {
if (name === "rollback_on_failure") return true;
return false;
});
// We'll just run a partial check or rely on the monitor unit tests for depth
// The wiring in index.js is:
// const monitorTicks = parseInt(core.getInput("monitor") || "0", 10);
// if (monitorTicks > 0) { ... }
// Simulate a failure in monitorConsole
monitorConsole.mockResolvedValueOnce({
sawTraceback: true, // Should trigger "fail" due to on_traceback=fail
sawErrorLog: false,
sawWarningLog: false,
});
// Testing the logic inside index.js directly by calling postCode would require full environment mock.
// I'll stick to the applyOnAction unit tests and rely on monitor.test.js for the heavy lifting.
await postCode();
// Verify rollback was performed
const mockApiInstance = new ScreepsAPI();
// `code.set` should be called twice:
// 1st time: uploading the new files
// 2nd time: rolling back to oldCode
expect(mockApiInstance.code.set).toHaveBeenCalledTimes(2);
expect(mockApiInstance.code.set).toHaveBeenNthCalledWith(2, "default", {
main: "old_code",
});
// Verify it called core.setFailed due to traceback
expect(core.setFailed).toHaveBeenCalledWith(
"Screeps console: traceback detected",
);
});
});
+1 -1
View File
File diff suppressed because one or more lines are too long
+28 -30
View File
@@ -118,17 +118,19 @@ export function validateAuthentication(token, username, password) {
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
* @param {'ignore'|'warn'|'fail'} action
* @param {boolean} flag - Only acts when true
* @param {string} message - Passed to core.warning / core.setFailed
* @returns {boolean} - Returns true if the action was 'fail' and the flag was true.
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
*/
export function applyOnAction(action, flag, message) {
if (!flag) return;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
if (!flag) return false;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
if (action === "warn") {
core.warning(message);
return;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
return false;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
}
if (action === "fail") {
core.setFailed(message);
return true;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
}
// 'ignore' → no-op
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
return false;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
}
/**
@@ -210,14 +212,16 @@ export async function postCode() {
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
`Successfully downloaded existing code (modules: ${Object.keys(oldCode).join(", ")})`,
);
Philipp marked this conversation as resolved
Review

If the user explicitly requested rollback_on_failure, and the download fails, should the action continue? Currently it results in a warning. If the deployment is critical, failing here might be safer.

If the user explicitly requested `rollback_on_failure`, and the download fails, should the action continue? Currently it results in a warning. If the deployment is critical, failing here might be safer.
} else {
core.warning(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
`Failed to download existing code, rollback will not be possible.`,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.setFailed(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
`Failed to download existing code, but rollback_on_failure is enabled. Aborting deployment.`,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
);
return;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
}
} catch (err) {
core.warning(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
`Error downloading existing code: ${err.message}. Rollback will not be possible.`,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.setFailed(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
`Error downloading existing code: ${err.message}. Aborting deployment.`,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
);
return;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
}
}
1
@@ -248,13 +252,23 @@ export async function postCode() {
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.setOutput("saw_error_log", String(result.sawErrorLog));
core.setOutput("saw_warning_log", String(result.sawWarningLog));
let shouldFail = false;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
if (core.getInput("on_traceback") === "fail" && result.sawTraceback)
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
shouldFail = true;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
if (core.getInput("on_error_log") === "fail" && result.sawErrorLog)
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
shouldFail = true;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
if (core.getInput("on_warning_log") === "fail" && result.sawWarningLog)
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
shouldFail = true;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
const fail1 = applyOnAction(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.getInput("on_traceback") || "fail",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
Review

Consider defining these defaults in a central place or ensuring they are strictly pulled from action.yaml. If action.yaml defaults change but these fallbacks don't, the behavior might become inconsistent.

Consider defining these defaults in a central place or ensuring they are strictly pulled from `action.yaml`. If `action.yaml` defaults change but these fallbacks don't, the behavior might become inconsistent.
result.sawTraceback,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
"Screeps console: traceback detected",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
);
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
const fail2 = applyOnAction(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.getInput("on_error_log") || "warn",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
result.sawErrorLog,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
"Screeps console: error log output detected",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
);
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
const fail3 = applyOnAction(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.getInput("on_warning_log") || "ignore",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
result.sawWarningLog,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
"Screeps console: warning log output detected",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
);
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
const shouldFail = fail1 || fail2 || fail3;
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
if (shouldFail && rollbackOnFailure && oldCode) {
core.info(
@@ -269,22 +283,6 @@ export async function postCode() {
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.error(`Rollback failed: ${err}`);
}
}
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
applyOnAction(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.getInput("on_traceback"),
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
result.sawTraceback,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
"Screeps console: traceback detected",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
);
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
applyOnAction(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.getInput("on_error_log"),
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
result.sawErrorLog,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
"Screeps console: error log output detected",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
);
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
applyOnAction(
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
core.getInput("on_warning_log"),
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
result.sawWarningLog,
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
"Screeps console: warning log output detected",
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
);
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
}
}
Philipp marked this conversation as resolved
Review

Wait-for-ticks logic in monitorConsole handles the timing, but consider if a failed rollback should also setFailed the action explicitly if api.code.set fails during the rollback phase. Currently, it only logs an error.

Wait-for-ticks logic in `monitorConsole` handles the timing, but consider if a failed rollback should also `setFailed` the action explicitly if `api.code.set` fails during the rollback phase. Currently, it only logs an error.
Philipp marked this conversation as resolved
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.
Review

The api.auth call is now explicitly awaited outside the conditional block. This is cleaner than the previous .then() chain.

The `api.auth` call is now explicitly awaited outside the conditional block. This is cleaner than the previous `.then()` chain.