feat: add rollback_on_failure feature #88
Reference in New Issue
Block a user
Delete Branch "feature/rollback-on-failure"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR adds the ability to download existing code before deployment and automatically roll back if the post-deployment monitor detects a failure.
Summary
api.code.setis called with theoldCode.shouldFailmanually duplicates logic that is partially handled byapplyOnAction. Also, ifrollback_on_failureis enabled but the initial code download fails, the action continues without a safety net; consider if it should fail early if a requested rollback capability cannot be guaranteed.GEMINI.mdregarding pre-commit hooks, which seems slightly out of scope for this feature but harmless.The PR correctly implements the requested functionality by backing up the existing code before deployment when the
rollback_on_failureflag is set, and restoring it if the console monitor detects a failure condition.The
api.authcall is now explicitly awaited outside the conditional block. This is cleaner than the previous.then()chain.@@ -183,0 +210,4 @@`Successfully downloaded existing code (modules: ${Object.keys(oldCode).join(", ")})`,);} else {core.warning(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.@@ -215,6 +248,28 @@ export async function postCode() {core.setOutput("saw_error_log", String(result.sawErrorLog));core.setOutput("saw_warning_log", String(result.sawWarningLog));let shouldFail = false;This block duplicates the logic found inside
applyOnAction. While necessary to determine if a rollback should occur before the finalsetFailedcall, it might be worth refactoring to avoid inconsistent behavior if more failure conditions are added in the future.Summary
The PR introduces a useful
rollback_on_failurefeature that automatically reverts to the previous code version if the log monitor detects issues (tracebacks, errors, or warnings) based on user configuration. The implementation is generally sound and well-tested, though there are minor improvements to be made regarding configuration consistency.__tests__/index.test.jsto cover the rollback logic and mock the Screeps API. This provides good coverage for the feature.index.js, the default values foron_traceback,on_error_log, andon_warning_logare hardcoded in thepostCodefunction. While these matchaction.yaml, it would be safer to rely on thecore.getInput({ default: '...' })or ensure the fallback logic is unified to prevent drifts.rollback_on_failurelogic correctly aborts the deployment if the "old code" cannot be downloaded, which addresses previous concerns about safety.GEMINI.mdwas updated with a specific note about pre-commit hook timing which seems specific to an LLM development workflow but doesn't hurt.Approval Policy: The code is well-structured, incorporates previous feedback (explicitly awaiting
auth), and includes necessary test cases.Summary
__tests__/index.test.js.action.yamlandindex.js.@@ -218,2 +255,2 @@applyOnAction(core.getInput("on_traceback"),const fail1 = applyOnAction(core.getInput("on_traceback") || "fail",Consider defining these defaults in a central place or ensuring they are strictly pulled from
action.yaml. Ifaction.yamldefaults change but these fallbacks don't, the behavior might become inconsistent.Summary
__tests__/index.test.jscovering the rollback logic, which is good.api.code.set(branch, oldCode), which effectively overwrites the "failed" deploy. However, if the "failed" deploy was intended for a specific branch, ensure thatoldCode(retrieved viaapi.code.get) doesn't accidentally revert to an even older version if multiple deploys happen in rapid succession, though this is likely out of scope for the action's current architecture.applyOnActionto return a boolean effectively addresses the previous reviewer's concern about logic duplication.index.js, therollbackOnFailureconstant is initialized inside atry-catchblock but then used outside. While functional,core.getBooleanInputis generally reliable if theaction.yamldefault is set correctly.The changes effectively implement a safety net for Screeps deployments by leveraging the console monitor to detect runtime failures immediately after push.
@@ -233,0 +284,4 @@`Successfully rolled back to previous code on branch ${branch}.`,);} catch (err) {core.error(`Rollback failed: ${err}`);Wait-for-ticks logic in
monitorConsolehandles the timing, but consider if a failed rollback should alsosetFailedthe action explicitly ifapi.code.setfails during the rollback phase. Currently, it only logs an error.