mirror of
https://github.com/DeterminateSystems/magic-nix-cache-action.git
synced 2024-12-23 13:32:03 +01:00
Revamp exit logic
This commit is contained in:
parent
7286978530
commit
d4fd993185
3 changed files with 53 additions and 94 deletions
64
dist/index.js
generated
vendored
64
dist/index.js
generated
vendored
|
@ -95463,13 +95463,12 @@ async function flakeHubLogin(netrc) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var ENV_DAEMON_DIR = "MAGIC_NIX_CACHE_DAEMONDIR";
|
var ENV_DAEMON_DIR = "MAGIC_NIX_CACHE_DAEMONDIR";
|
||||||
var FACT_ENV_VARS_PRESENT = "required_env_vars_present";
|
var FACT_ENV_VARS_PRESENT = "required_env_vars_present";
|
||||||
var FACT_DIFF_STORE_ENABLED = "diff_store";
|
var FACT_DIFF_STORE_ENABLED = "diff_store";
|
||||||
var FACT_NOOP_MODE = "noop_mode";
|
var FACT_NOOP_MODE = "noop_mode";
|
||||||
var STATE_ERROR_IN_MAIN = "ERROR_IN_MAIN";
|
|
||||||
var STATE_DAEMONDIR = "MAGIC_NIX_CACHE_DAEMONDIR";
|
var STATE_DAEMONDIR = "MAGIC_NIX_CACHE_DAEMONDIR";
|
||||||
|
var STATE_ERROR_IN_MAIN = "ERROR_IN_MAIN";
|
||||||
var STATE_STARTED = "MAGIC_NIX_CACHE_STARTED";
|
var STATE_STARTED = "MAGIC_NIX_CACHE_STARTED";
|
||||||
var STARTED_HINT = "true";
|
var STARTED_HINT = "true";
|
||||||
var TEXT_NOOP = "Magic Nix Cache is already running, this workflow job is in noop mode. Is the Magic Nix Cache in the workflow twice?";
|
var TEXT_NOOP = "Magic Nix Cache is already running, this workflow job is in noop mode. Is the Magic Nix Cache in the workflow twice?";
|
||||||
|
@ -95534,8 +95533,11 @@ var MagicNixCacheAction = class extends DetSysAction {
|
||||||
await this.notifyAutoCache();
|
await this.notifyAutoCache();
|
||||||
}
|
}
|
||||||
async post() {
|
async post() {
|
||||||
if (!this.strictMode && this.mainError !== void 0) {
|
if (!this.strictMode && this.errorInMain) {
|
||||||
this.exitWithWarning(this.mainError);
|
core.warning(
|
||||||
|
`skipping post phase due to error in main phase: ${this.errorInMain}`
|
||||||
|
);
|
||||||
|
process.exit(0);
|
||||||
}
|
}
|
||||||
if (this.noopMode) {
|
if (this.noopMode) {
|
||||||
core.debug(TEXT_NOOP);
|
core.debug(TEXT_NOOP);
|
||||||
|
@ -95654,17 +95656,11 @@ var MagicNixCacheAction = class extends DetSysAction {
|
||||||
const pidFile = external_node_path_namespaceObject.join(this.daemonDir, "daemon.pid");
|
const pidFile = external_node_path_namespaceObject.join(this.daemonDir, "daemon.pid");
|
||||||
await promises_namespaceObject.writeFile(pidFile, `${daemon.pid}`);
|
await promises_namespaceObject.writeFile(pidFile, `${daemon.pid}`);
|
||||||
core.info("Waiting for magic-nix-cache to start...");
|
core.info("Waiting for magic-nix-cache to start...");
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, _reject) => {
|
||||||
notifyPromise.then((_value) => {
|
notifyPromise.then((_value) => {
|
||||||
resolve();
|
resolve();
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
const msg = stringifyError(e);
|
this.exitMain(`Error in notifyPromise: ${stringifyError(e)}`);
|
||||||
if (this.strictMode) {
|
|
||||||
reject(new Error(`error in notifyPromise: ${msg}`));
|
|
||||||
} else {
|
|
||||||
this.setMainError(msg);
|
|
||||||
this.exitWithWarning(`failed to start daemon: ${msg}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
daemon.on("exit", async (code, signal) => {
|
daemon.on("exit", async (code, signal) => {
|
||||||
let msg;
|
let msg;
|
||||||
|
@ -95675,12 +95671,7 @@ var MagicNixCacheAction = class extends DetSysAction {
|
||||||
} else {
|
} else {
|
||||||
msg = "Daemon unexpectedly exited";
|
msg = "Daemon unexpectedly exited";
|
||||||
}
|
}
|
||||||
if (this.strictMode) {
|
this.exitMain(msg);
|
||||||
reject(new Error(msg));
|
|
||||||
} else {
|
|
||||||
this.setMainError(msg);
|
|
||||||
this.exitWithWarning(`Failed to kill daemon: ${msg}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
daemon.unref();
|
daemon.unref();
|
||||||
|
@ -95707,18 +95698,7 @@ var MagicNixCacheAction = class extends DetSysAction {
|
||||||
}
|
}
|
||||||
core.debug(`back from post: ${res.body}`);
|
core.debug(`back from post: ${res.body}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (this.strictMode) {
|
this.exitMain(`Error starting the Magic Nix Cache: ${stringifyError(e)}`);
|
||||||
core.setFailed(`Magic Nix Cache failed to start: ${(0,external_node_util_.inspect)(e)}`);
|
|
||||||
} else {
|
|
||||||
core.warning(`Error marking the workflow as started:`);
|
|
||||||
core.warning((0,external_node_util_.inspect)(e));
|
|
||||||
core.warning(
|
|
||||||
`Magic Nix Cache may not be running for this workflow.`
|
|
||||||
);
|
|
||||||
this.setMainError(
|
|
||||||
`Error starting the Magic Nix Cache: ${stringifyError(e)}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async tearDownAutoCache() {
|
async tearDownAutoCache() {
|
||||||
|
@ -95750,15 +95730,13 @@ var MagicNixCacheAction = class extends DetSysAction {
|
||||||
core.debug(`unwatching the daemon log`);
|
core.debug(`unwatching the daemon log`);
|
||||||
log.unwatch();
|
log.unwatch();
|
||||||
}
|
}
|
||||||
core.debug(`killing`);
|
core.debug(`killing daemon process ${pid}`);
|
||||||
try {
|
try {
|
||||||
process.kill(pid, "SIGTERM");
|
process.kill(pid, "SIGTERM");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (typeof e === "object" && e && "code" in e && e.code !== "ESRCH") {
|
if (typeof e === "object" && e && "code" in e && e.code !== "ESRCH") {
|
||||||
if (this.strictMode) {
|
if (this.strictMode) {
|
||||||
throw e;
|
throw e;
|
||||||
} else {
|
|
||||||
this.exitWithWarning(`couldn't kill daemon: ${stringifyError(e)}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -95769,19 +95747,19 @@ var MagicNixCacheAction = class extends DetSysAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exitWithWarning(msg) {
|
// Exit the workflow during the main phase. If strict mode is set, fail; if not, save the error
|
||||||
core.warning(msg);
|
// message to the workflow's state and exit successfully.
|
||||||
core.warning(`strict mode not enabled; exiting`);
|
exitMain(msg) {
|
||||||
|
if (this.strictMode) {
|
||||||
|
core.setFailed(msg);
|
||||||
|
} else {
|
||||||
|
core.saveState(STATE_ERROR_IN_MAIN, msg);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
// If the main phase errors, save the state for use in post.
|
|
||||||
// This matters only when strict mode is NOT set.
|
|
||||||
setMainError(msg) {
|
|
||||||
core.saveState(STATE_ERROR_IN_MAIN, msg);
|
|
||||||
}
|
}
|
||||||
// In the post phase, if the main phase errored, return `true` so that the
|
// If the main phase threw an error (not in strict mode), this will be a non-empty
|
||||||
// phase can be skipped (with a warning).
|
// string available in the post phase.
|
||||||
get mainError() {
|
get errorInMain() {
|
||||||
const state = core.getState(STATE_ERROR_IN_MAIN);
|
const state = core.getState(STATE_ERROR_IN_MAIN);
|
||||||
return state !== "" ? state : void 0;
|
return state !== "" ? state : void 0;
|
||||||
}
|
}
|
||||||
|
|
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
73
src/index.ts
73
src/index.ts
|
@ -7,7 +7,6 @@ import { SpawnOptions, spawn } from "node:child_process";
|
||||||
import { mkdirSync, openSync, readFileSync } from "node:fs";
|
import { mkdirSync, openSync, readFileSync } from "node:fs";
|
||||||
import * as fs from "node:fs/promises";
|
import * as fs from "node:fs/promises";
|
||||||
import * as path from "node:path";
|
import * as path from "node:path";
|
||||||
import { inspect } from "node:util";
|
|
||||||
|
|
||||||
// The ENV_DAEMON_DIR is intended to determine if we "own" the daemon or not,
|
// The ENV_DAEMON_DIR is intended to determine if we "own" the daemon or not,
|
||||||
// in the case that a user has put the magic nix cache into their workflow
|
// in the case that a user has put the magic nix cache into their workflow
|
||||||
|
@ -18,8 +17,8 @@ const FACT_ENV_VARS_PRESENT = "required_env_vars_present";
|
||||||
const FACT_DIFF_STORE_ENABLED = "diff_store";
|
const FACT_DIFF_STORE_ENABLED = "diff_store";
|
||||||
const FACT_NOOP_MODE = "noop_mode";
|
const FACT_NOOP_MODE = "noop_mode";
|
||||||
|
|
||||||
const STATE_ERROR_IN_MAIN = "ERROR_IN_MAIN";
|
|
||||||
const STATE_DAEMONDIR = "MAGIC_NIX_CACHE_DAEMONDIR";
|
const STATE_DAEMONDIR = "MAGIC_NIX_CACHE_DAEMONDIR";
|
||||||
|
const STATE_ERROR_IN_MAIN = "ERROR_IN_MAIN";
|
||||||
const STATE_STARTED = "MAGIC_NIX_CACHE_STARTED";
|
const STATE_STARTED = "MAGIC_NIX_CACHE_STARTED";
|
||||||
const STARTED_HINT = "true";
|
const STARTED_HINT = "true";
|
||||||
|
|
||||||
|
@ -34,10 +33,13 @@ class MagicNixCacheAction extends DetSysAction {
|
||||||
private hostAndPort: string;
|
private hostAndPort: string;
|
||||||
private diffStore: boolean;
|
private diffStore: boolean;
|
||||||
private httpClient: Got;
|
private httpClient: Got;
|
||||||
private noopMode: boolean;
|
|
||||||
private daemonDir: string;
|
private daemonDir: string;
|
||||||
private daemonStarted: boolean;
|
private daemonStarted: boolean;
|
||||||
|
|
||||||
|
// No-op mode is set to `true` if the MNC is already running, in which case
|
||||||
|
// the workflow will use the existing process rather than starting a new one.
|
||||||
|
private noopMode: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
name: "magic-nix-cache",
|
name: "magic-nix-cache",
|
||||||
|
@ -109,8 +111,11 @@ class MagicNixCacheAction extends DetSysAction {
|
||||||
async post(): Promise<void> {
|
async post(): Promise<void> {
|
||||||
// If strict mode is off and there was an error in main, such as the daemon not starting,
|
// If strict mode is off and there was an error in main, such as the daemon not starting,
|
||||||
// then the post phase is skipped with a warning.
|
// then the post phase is skipped with a warning.
|
||||||
if (!this.strictMode && this.mainError !== undefined) {
|
if (!this.strictMode && this.errorInMain) {
|
||||||
this.exitWithWarning(this.mainError);
|
actionsCore.warning(
|
||||||
|
`skipping post phase due to error in main phase: ${this.errorInMain}`,
|
||||||
|
);
|
||||||
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.noopMode) {
|
if (this.noopMode) {
|
||||||
|
@ -259,7 +264,7 @@ class MagicNixCacheAction extends DetSysAction {
|
||||||
|
|
||||||
actionsCore.info("Waiting for magic-nix-cache to start...");
|
actionsCore.info("Waiting for magic-nix-cache to start...");
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, _reject) => {
|
||||||
notifyPromise
|
notifyPromise
|
||||||
// eslint-disable-next-line github/no-then
|
// eslint-disable-next-line github/no-then
|
||||||
.then((_value) => {
|
.then((_value) => {
|
||||||
|
@ -267,14 +272,7 @@ class MagicNixCacheAction extends DetSysAction {
|
||||||
})
|
})
|
||||||
// eslint-disable-next-line github/no-then
|
// eslint-disable-next-line github/no-then
|
||||||
.catch((e: unknown) => {
|
.catch((e: unknown) => {
|
||||||
const msg = stringifyError(e);
|
this.exitMain(`Error in notifyPromise: ${stringifyError(e)}`);
|
||||||
|
|
||||||
if (this.strictMode) {
|
|
||||||
reject(new Error(`error in notifyPromise: ${msg}`));
|
|
||||||
} else {
|
|
||||||
this.setMainError(msg);
|
|
||||||
this.exitWithWarning(`failed to start daemon: ${msg}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
daemon.on("exit", async (code, signal) => {
|
daemon.on("exit", async (code, signal) => {
|
||||||
|
@ -287,12 +285,7 @@ class MagicNixCacheAction extends DetSysAction {
|
||||||
msg = "Daemon unexpectedly exited";
|
msg = "Daemon unexpectedly exited";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.strictMode) {
|
this.exitMain(msg);
|
||||||
reject(new Error(msg));
|
|
||||||
} else {
|
|
||||||
this.setMainError(msg);
|
|
||||||
this.exitWithWarning(`Failed to kill daemon: ${msg}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -327,18 +320,7 @@ class MagicNixCacheAction extends DetSysAction {
|
||||||
|
|
||||||
actionsCore.debug(`back from post: ${res.body}`);
|
actionsCore.debug(`back from post: ${res.body}`);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
if (this.strictMode) {
|
this.exitMain(`Error starting the Magic Nix Cache: ${stringifyError(e)}`);
|
||||||
actionsCore.setFailed(`Magic Nix Cache failed to start: ${inspect(e)}`);
|
|
||||||
} else {
|
|
||||||
actionsCore.warning(`Error marking the workflow as started:`);
|
|
||||||
actionsCore.warning(inspect(e));
|
|
||||||
actionsCore.warning(
|
|
||||||
`Magic Nix Cache may not be running for this workflow.`,
|
|
||||||
);
|
|
||||||
this.setMainError(
|
|
||||||
`Error starting the Magic Nix Cache: ${stringifyError(e)}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,16 +359,16 @@ class MagicNixCacheAction extends DetSysAction {
|
||||||
log.unwatch();
|
log.unwatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsCore.debug(`killing`);
|
actionsCore.debug(`killing daemon process ${pid}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
process.kill(pid, "SIGTERM");
|
process.kill(pid, "SIGTERM");
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
if (typeof e === "object" && e && "code" in e && e.code !== "ESRCH") {
|
if (typeof e === "object" && e && "code" in e && e.code !== "ESRCH") {
|
||||||
|
// Throw an error only in strict mode, otherwise ignore because
|
||||||
|
// we're in the post phase and shutting down after this anyway
|
||||||
if (this.strictMode) {
|
if (this.strictMode) {
|
||||||
throw e;
|
throw e;
|
||||||
} else {
|
|
||||||
this.exitWithWarning(`couldn't kill daemon: ${stringifyError(e)}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -398,21 +380,20 @@ class MagicNixCacheAction extends DetSysAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private exitWithWarning(msg: string): void {
|
// Exit the workflow during the main phase. If strict mode is set, fail; if not, save the error
|
||||||
actionsCore.warning(msg);
|
// message to the workflow's state and exit successfully.
|
||||||
actionsCore.warning(`strict mode not enabled; exiting`);
|
private exitMain(msg: string): void {
|
||||||
|
if (this.strictMode) {
|
||||||
|
actionsCore.setFailed(msg);
|
||||||
|
} else {
|
||||||
|
actionsCore.saveState(STATE_ERROR_IN_MAIN, msg);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the main phase errors, save the state for use in post.
|
|
||||||
// This matters only when strict mode is NOT set.
|
|
||||||
private setMainError(msg: string): void {
|
|
||||||
actionsCore.saveState(STATE_ERROR_IN_MAIN, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the post phase, if the main phase errored, return `true` so that the
|
// If the main phase threw an error (not in strict mode), this will be a non-empty
|
||||||
// phase can be skipped (with a warning).
|
// string available in the post phase.
|
||||||
private get mainError(): string | undefined {
|
private get errorInMain(): string | undefined {
|
||||||
const state = actionsCore.getState(STATE_ERROR_IN_MAIN);
|
const state = actionsCore.getState(STATE_ERROR_IN_MAIN);
|
||||||
return state !== "" ? state : undefined;
|
return state !== "" ? state : undefined;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue