From edc61c4d5a6ec4d67f304bbcbab5e6311aa42a63 Mon Sep 17 00:00:00 2001 From: Luc Perkins Date: Mon, 20 May 2024 09:20:03 -0300 Subject: [PATCH] Fix HTTP status code logic --- .github/workflows/ci.yml | 2 ++ dist/index.js | 21 +++++++++++++++------ dist/index.js.map | 2 +- src/index.ts | 29 ++++++++++++++++++----------- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2558a8..6c1f80a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,7 @@ jobs: - run: git diff --exit-code test-no-nix: + needs: build name: "Test: Nix not installed" runs-on: ubuntu-22.04 permissions: @@ -47,6 +48,7 @@ jobs: strict-mode: true run-x86_64-linux-untrusted: + needs: build name: Run x86_64 Linux, Untrusted runs-on: ubuntu-22.04 permissions: diff --git a/dist/index.js b/dist/index.js index 976fc00..b263bba 100644 --- a/dist/index.js +++ b/dist/index.js @@ -94996,8 +94996,15 @@ var MagicNixCacheAction = class { try { core.debug(`Indicating workflow start`); const hostAndPort = inputs_exports.getString("listen"); - const res = await this.client.post(`http://${hostAndPort}/api/workflow-start`).json(); - core.debug(`back from post: ${res}`); + const res = await this.client.post( + `http://${hostAndPort}/api/workflow-start` + ); + if (res.statusCode !== 200) { + this.failInStrictMode( + `Failed to trigger workflow start hook. Expected status 200 but got ${res.statusCode}` + ); + } + core.debug(`back from post: ${JSON.stringify(res)}`); } catch (e) { core.info(`Error marking the workflow as started:`); core.info((0,external_node_util_.inspect)(e)); @@ -95022,13 +95029,15 @@ var MagicNixCacheAction = class { try { core.debug(`about to post to localhost`); const hostAndPort = inputs_exports.getString("listen"); - const res = await this.client.post(`http://${hostAndPort}/api/workflow-finish`).json(); - if (res.status !== 200) { + const res = await this.client.post( + `http://${hostAndPort}/api/workflow-finish` + ); + if (res.statusCode !== 200) { this.failInStrictMode( - `Failed to trigger workflow finish hook. Response: ${JSON.stringify(res)}` + `Failed to trigger workflow finish hook. Expected status 200 but got ${res.statusCode}` ); } - core.debug(`back from post: ${res}`); + core.debug(`back from post: ${JSON.stringify(res.body)}`); } finally { core.debug(`unwatching the daemon log`); log.unwatch(); diff --git a/dist/index.js.map b/dist/index.js.map index aba3ac8..d33342c 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/helpers.ts","../src/index.ts"],"sourcesContent":["import * as actionsCore from \"@actions/core\";\nimport * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport path from \"node:path\";\nimport { Tail } from \"tail\";\n\nexport function tailLog(daemonDir: string): Tail {\n const log = new Tail(path.join(daemonDir, \"daemon.log\"));\n actionsCore.debug(`tailing daemon.log...`);\n log.on(\"line\", (line) => {\n actionsCore.info(line);\n });\n return log;\n}\n\nexport async function netrcPath(): Promise {\n const expectedNetrcPath = path.join(\n process.env[\"RUNNER_TEMP\"] || os.tmpdir(),\n \"determinate-nix-installer-netrc\",\n );\n try {\n await fs.access(expectedNetrcPath);\n return expectedNetrcPath;\n } catch {\n // `nix-installer` was not used, the user may be registered with FlakeHub though.\n const destinedNetrcPath = path.join(\n process.env[\"RUNNER_TEMP\"] || os.tmpdir(),\n \"magic-nix-cache-netrc\",\n );\n try {\n await flakeHubLogin(destinedNetrcPath);\n } catch (e) {\n actionsCore.info(\"FlakeHub cache disabled.\");\n actionsCore.debug(`Error while logging into FlakeHub: ${e}`);\n }\n return destinedNetrcPath;\n }\n}\n\nasync function flakeHubLogin(netrc: string): Promise {\n const jwt = await actionsCore.getIDToken(\"api.flakehub.com\");\n\n await fs.writeFile(\n netrc,\n [\n `machine api.flakehub.com login flakehub password ${jwt}`,\n `machine flakehub.com login flakehub password ${jwt}`,\n `machine cache.flakehub.com login flakehub password ${jwt}`,\n ].join(\"\\n\"),\n );\n\n actionsCore.info(\"Logged in to FlakeHub.\");\n}\n","import { netrcPath, tailLog } from \"./helpers.js\";\nimport * as actionsCore from \"@actions/core\";\nimport { IdsToolbox, inputs } from \"detsys-ts\";\nimport got, { Got } from \"got\";\nimport * as http from \"http\";\nimport { SpawnOptions, exec, spawn } from \"node:child_process\";\nimport { mkdirSync, openSync, readFileSync } from \"node:fs\";\nimport * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { inspect, promisify } from \"node:util\";\n\n// The ENV_DAEMON_DIR is intended to determine if we \"own\" the daemon or not,\n// in the case that a user has put the magic nix cache into their workflow\n// twice.\nconst ENV_DAEMON_DIR = \"MAGIC_NIX_CACHE_DAEMONDIR\";\n\nconst STATE_DAEMONDIR = \"MAGIC_NIX_CACHE_DAEMONDIR\";\nconst STATE_STARTED = \"MAGIC_NIX_CACHE_STARTED\";\nconst STARTED_HINT = \"true\";\n\nconst TEXT_NOOP =\n \"Magic Nix Cache is already running, this workflow job is in noop mode. Is the Magic Nix Cache in the workflow twice?\";\nconst TEXT_TRUST_UNTRUSTED =\n \"The Nix daemon does not consider the user running this workflow to be trusted. Magic Nix Cache is disabled.\";\nconst TEXT_TRUST_UNKNOWN =\n \"The Nix daemon may not consider the user running this workflow to be trusted. Magic Nix Cache may not start correctly.\";\n\nclass MagicNixCacheAction {\n idslib: IdsToolbox;\n private strictMode: boolean;\n private client: Got;\n\n noopMode: boolean;\n private daemonDir: string;\n private daemonStarted: boolean;\n\n constructor() {\n this.idslib = new IdsToolbox({\n name: \"magic-nix-cache\",\n fetchStyle: \"gh-env-style\",\n idsProjectName: \"magic-nix-cache-closure\",\n requireNix: \"warn\",\n });\n\n this.strictMode = inputs.getBool(\"strict-mode\");\n\n this.client = got.extend({\n retry: {\n limit: 1,\n methods: [\"POST\", \"GET\", \"PUT\", \"HEAD\", \"DELETE\", \"OPTIONS\", \"TRACE\"],\n },\n hooks: {\n beforeRetry: [\n (error, retryCount) => {\n actionsCore.info(\n `Retrying after error ${error.code}, retry #: ${retryCount}`,\n );\n },\n ],\n },\n });\n\n this.daemonStarted = actionsCore.getState(STATE_STARTED) === STARTED_HINT;\n\n if (actionsCore.getState(STATE_DAEMONDIR) !== \"\") {\n this.daemonDir = actionsCore.getState(STATE_DAEMONDIR);\n } else {\n this.daemonDir = this.idslib.getTemporaryName();\n mkdirSync(this.daemonDir);\n actionsCore.saveState(STATE_DAEMONDIR, this.daemonDir);\n }\n\n if (process.env[ENV_DAEMON_DIR] === undefined) {\n this.noopMode = false;\n actionsCore.exportVariable(ENV_DAEMON_DIR, this.daemonDir);\n } else {\n this.noopMode = process.env[ENV_DAEMON_DIR] !== this.daemonDir;\n }\n this.idslib.addFact(\"noop_mode\", this.noopMode);\n\n this.idslib.stapleFile(\n \"daemon.log\",\n path.join(this.daemonDir, \"daemon.log\"),\n );\n }\n\n async setUpAutoCache(): Promise {\n const requiredEnv = [\n \"ACTIONS_CACHE_URL\",\n \"ACTIONS_RUNTIME_URL\",\n \"ACTIONS_RUNTIME_TOKEN\",\n ];\n\n let anyMissing = false;\n for (const n of requiredEnv) {\n if (!process.env.hasOwnProperty(n)) {\n anyMissing = true;\n actionsCore.warning(\n `Disabling automatic caching since required environment ${n} isn't available`,\n );\n }\n }\n\n this.idslib.addFact(\"authenticated_env\", !anyMissing);\n if (anyMissing) {\n return;\n }\n\n if (this.daemonStarted) {\n actionsCore.debug(\"Already started.\");\n return;\n }\n\n actionsCore.debug(\n `GitHub Action Cache URL: ${process.env[\"ACTIONS_CACHE_URL\"]}`,\n );\n\n const sourceBinary = inputs.getStringOrNull(\"source-binary\");\n const daemonBin =\n sourceBinary !== null ? sourceBinary : await this.fetchAutoCacher();\n\n let runEnv;\n if (actionsCore.isDebug()) {\n runEnv = {\n RUST_LOG: \"trace,magic_nix_cache=debug,gha_cache=debug\",\n RUST_BACKTRACE: \"full\",\n ...process.env,\n };\n } else {\n runEnv = process.env;\n }\n\n const notifyPort = inputs.getString(\"startup-notification-port\");\n\n const notifyPromise = new Promise>((resolveListening) => {\n const promise = new Promise(async (resolveQuit) => {\n const notifyServer = http.createServer((req, res) => {\n if (req.method === \"POST\" && req.url === \"/\") {\n actionsCore.debug(`Notify server shutting down.`);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(\"{}\");\n notifyServer.close(() => {\n resolveQuit();\n });\n }\n });\n\n notifyServer.listen(notifyPort, () => {\n actionsCore.debug(`Notify server running.`);\n resolveListening(promise);\n });\n });\n });\n\n // Start tailing the daemon log.\n const outputPath = `${this.daemonDir}/daemon.log`;\n const output = openSync(outputPath, \"a\");\n const log = tailLog(this.daemonDir);\n const netrc = await netrcPath();\n const nixConfPath = `${process.env[\"HOME\"]}/.config/nix/nix.conf`;\n\n const hostAndPort = inputs.getString(\"listen\");\n const upstreamCache = inputs.getString(\"upstream-cache\");\n const diagnosticEndpoint = inputs.getString(\"diagnostic-endpoint\");\n const useFlakeHub = inputs.getBool(\"use-flakehub\");\n const flakeHubCacheServer = inputs.getString(\"flakehub-cache-server\");\n const flakeHubApiServer = inputs.getString(\"flakehub-api-server\");\n const flakeHubFlakeName = inputs.getString(\"flakehub-flake-name\");\n const useGhaCache = inputs.getBool(\"use-gha-cache\");\n\n const daemonCliFlags: string[] = [\n \"--startup-notification-url\",\n `http://127.0.0.1:${notifyPort}`,\n \"--listen\",\n hostAndPort,\n \"--upstream\",\n upstreamCache,\n \"--diagnostic-endpoint\",\n diagnosticEndpoint,\n \"--nix-conf\",\n nixConfPath,\n ]\n .concat(\n useFlakeHub\n ? [\n \"--use-flakehub\",\n \"--flakehub-cache-server\",\n flakeHubCacheServer,\n \"--flakehub-api-server\",\n flakeHubApiServer,\n \"--flakehub-api-server-netrc\",\n netrc,\n \"--flakehub-flake-name\",\n flakeHubFlakeName,\n ]\n : [],\n )\n .concat(useGhaCache ? [\"--use-gha-cache\"] : []);\n\n const opts: SpawnOptions = {\n stdio: [\"ignore\", output, output],\n env: runEnv,\n detached: true,\n };\n\n // Display the final command for debugging purposes\n actionsCore.debug(\"Full daemon start command:\");\n actionsCore.debug(`${daemonBin} ${daemonCliFlags.join(\" \")}`);\n\n // Start the server. Once it is ready, it will notify us via the notification server.\n const daemon = spawn(daemonBin, daemonCliFlags, opts);\n\n this.daemonStarted = true;\n actionsCore.saveState(STATE_STARTED, STARTED_HINT);\n\n const pidFile = path.join(this.daemonDir, \"daemon.pid\");\n await fs.writeFile(pidFile, `${daemon.pid}`);\n\n actionsCore.info(\"Waiting for magic-nix-cache to start...\");\n\n await new Promise((resolve, reject) => {\n notifyPromise\n // eslint-disable-next-line github/no-then\n .then((_value) => {\n resolve();\n })\n // eslint-disable-next-line github/no-then\n .catch((err) => {\n const msg = `error in notifyPromise: ${err}`;\n reject(new Error(msg));\n this.failInStrictMode(msg);\n });\n daemon.on(\"exit\", async (code, signal) => {\n let msg: string;\n if (signal) {\n msg = `Daemon was killed by signal ${signal}`;\n } else if (code) {\n msg = `Daemon exited with code ${code}`;\n } else {\n msg = \"Daemon unexpectedly exited\";\n }\n reject(new Error(msg));\n this.failInStrictMode(msg);\n });\n });\n\n daemon.unref();\n\n actionsCore.info(\"Launched Magic Nix Cache\");\n\n log.unwatch();\n }\n\n private async fetchAutoCacher(): Promise {\n const closurePath = await this.idslib.fetch();\n this.idslib.recordEvent(\"load_closure\");\n const { stdout } = await promisify(exec)(\n `cat \"${closurePath}\" | xz -d | nix-store --import`,\n );\n\n const paths = stdout.split(os.EOL);\n // Since the export is in reverse topologically sorted order, magic-nix-cache is always the penultimate entry in the list (the empty string left by split being the last).\n const lastPath = paths.at(-2);\n return `${lastPath}/bin/magic-nix-cache`;\n }\n\n async notifyAutoCache(): Promise {\n if (!this.daemonStarted) {\n actionsCore.debug(\"magic-nix-cache not started - Skipping\");\n return;\n }\n\n try {\n actionsCore.debug(`Indicating workflow start`);\n const hostAndPort = inputs.getString(\"listen\");\n const res: Response = await this.client\n .post(`http://${hostAndPort}/api/workflow-start`)\n .json();\n actionsCore.debug(`back from post: ${res}`);\n } catch (e) {\n actionsCore.info(`Error marking the workflow as started:`);\n actionsCore.info(inspect(e));\n actionsCore.info(`Magic Nix Cache may not be running for this workflow.`);\n\n this.failInStrictMode(`Magic Nix Cache failed to start: ${inspect(e)}`);\n }\n }\n\n async tearDownAutoCache(): Promise {\n if (!this.daemonStarted) {\n actionsCore.debug(\"magic-nix-cache not started - Skipping\");\n return;\n }\n\n const pidFile = path.join(this.daemonDir, \"daemon.pid\");\n const pid = parseInt(await fs.readFile(pidFile, { encoding: \"ascii\" }));\n actionsCore.debug(`found daemon pid: ${pid}`);\n if (!pid) {\n const msg = \"magic-nix-cache did not start successfully\";\n this.failInStrictMode(msg);\n throw new Error(msg);\n }\n\n const log = tailLog(this.daemonDir);\n\n try {\n actionsCore.debug(`about to post to localhost`);\n const hostAndPort = inputs.getString(\"listen\");\n const res: Response = await this.client\n .post(`http://${hostAndPort}/api/workflow-finish`)\n .json();\n\n if (res.status !== 200) {\n this.failInStrictMode(\n `Failed to trigger workflow finish hook. Response: ${JSON.stringify(res)}`,\n );\n }\n\n actionsCore.debug(`back from post: ${res}`);\n } finally {\n actionsCore.debug(`unwatching the daemon log`);\n log.unwatch();\n }\n\n actionsCore.debug(`killing`);\n try {\n process.kill(pid, \"SIGTERM\");\n } catch (e) {\n if (typeof e === \"object\" && e && \"code\" in e && e.code !== \"ESRCH\") {\n this.failInStrictMode(e.toString());\n throw e;\n }\n } finally {\n if (actionsCore.isDebug()) {\n actionsCore.info(\"Entire log:\");\n const entireLog = readFileSync(path.join(this.daemonDir, \"daemon.log\"));\n actionsCore.info(entireLog.toString());\n }\n }\n }\n\n private failInStrictMode(msg: string): void {\n if (this.strictMode) {\n actionsCore.setFailed(`strict mode error: ${msg}`);\n }\n }\n}\n\nfunction main(): void {\n const cacheAction = new MagicNixCacheAction();\n\n cacheAction.idslib.onMain(async () => {\n if (cacheAction.noopMode) {\n actionsCore.warning(TEXT_NOOP);\n return;\n }\n\n if (cacheAction.idslib.nixStoreTrust === \"untrusted\") {\n actionsCore.warning(TEXT_TRUST_UNTRUSTED);\n return;\n } else if (cacheAction.idslib.nixStoreTrust === \"unknown\") {\n actionsCore.info(TEXT_TRUST_UNKNOWN);\n }\n\n await cacheAction.setUpAutoCache();\n await cacheAction.notifyAutoCache();\n });\n cacheAction.idslib.onPost(async () => {\n if (cacheAction.noopMode) {\n actionsCore.debug(TEXT_NOOP);\n return;\n }\n\n if (cacheAction.idslib.nixStoreTrust === \"untrusted\") {\n actionsCore.debug(TEXT_TRUST_UNTRUSTED);\n return;\n } else if (cacheAction.idslib.nixStoreTrust === \"unknown\") {\n actionsCore.debug(TEXT_TRUST_UNKNOWN);\n }\n\n await cacheAction.tearDownAutoCache();\n });\n\n cacheAction.idslib.execute();\n}\n\nmain();\n"],"mappings":"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","names":["actionsCore","fs","os","path"]} \ No newline at end of file +{"version":3,"sources":["../src/helpers.ts","../src/index.ts"],"sourcesContent":["import * as actionsCore from \"@actions/core\";\nimport * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport path from \"node:path\";\nimport { Tail } from \"tail\";\n\nexport function tailLog(daemonDir: string): Tail {\n const log = new Tail(path.join(daemonDir, \"daemon.log\"));\n actionsCore.debug(`tailing daemon.log...`);\n log.on(\"line\", (line) => {\n actionsCore.info(line);\n });\n return log;\n}\n\nexport async function netrcPath(): Promise {\n const expectedNetrcPath = path.join(\n process.env[\"RUNNER_TEMP\"] || os.tmpdir(),\n \"determinate-nix-installer-netrc\",\n );\n try {\n await fs.access(expectedNetrcPath);\n return expectedNetrcPath;\n } catch {\n // `nix-installer` was not used, the user may be registered with FlakeHub though.\n const destinedNetrcPath = path.join(\n process.env[\"RUNNER_TEMP\"] || os.tmpdir(),\n \"magic-nix-cache-netrc\",\n );\n try {\n await flakeHubLogin(destinedNetrcPath);\n } catch (e) {\n actionsCore.info(\"FlakeHub cache disabled.\");\n actionsCore.debug(`Error while logging into FlakeHub: ${e}`);\n }\n return destinedNetrcPath;\n }\n}\n\nasync function flakeHubLogin(netrc: string): Promise {\n const jwt = await actionsCore.getIDToken(\"api.flakehub.com\");\n\n await fs.writeFile(\n netrc,\n [\n `machine api.flakehub.com login flakehub password ${jwt}`,\n `machine flakehub.com login flakehub password ${jwt}`,\n `machine cache.flakehub.com login flakehub password ${jwt}`,\n ].join(\"\\n\"),\n );\n\n actionsCore.info(\"Logged in to FlakeHub.\");\n}\n","import { netrcPath, tailLog } from \"./helpers.js\";\nimport * as actionsCore from \"@actions/core\";\nimport { IdsToolbox, inputs } from \"detsys-ts\";\nimport got, { Got, Response } from \"got\";\nimport * as http from \"http\";\nimport { SpawnOptions, exec, spawn } from \"node:child_process\";\nimport { mkdirSync, openSync, readFileSync } from \"node:fs\";\nimport * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { inspect, promisify } from \"node:util\";\n\n// The ENV_DAEMON_DIR is intended to determine if we \"own\" the daemon or not,\n// in the case that a user has put the magic nix cache into their workflow\n// twice.\nconst ENV_DAEMON_DIR = \"MAGIC_NIX_CACHE_DAEMONDIR\";\n\nconst STATE_DAEMONDIR = \"MAGIC_NIX_CACHE_DAEMONDIR\";\nconst STATE_STARTED = \"MAGIC_NIX_CACHE_STARTED\";\nconst STARTED_HINT = \"true\";\n\nconst TEXT_NOOP =\n \"Magic Nix Cache is already running, this workflow job is in noop mode. Is the Magic Nix Cache in the workflow twice?\";\nconst TEXT_TRUST_UNTRUSTED =\n \"The Nix daemon does not consider the user running this workflow to be trusted. Magic Nix Cache is disabled.\";\nconst TEXT_TRUST_UNKNOWN =\n \"The Nix daemon may not consider the user running this workflow to be trusted. Magic Nix Cache may not start correctly.\";\n\nclass MagicNixCacheAction {\n idslib: IdsToolbox;\n private strictMode: boolean;\n private client: Got;\n\n noopMode: boolean;\n private daemonDir: string;\n private daemonStarted: boolean;\n\n constructor() {\n this.idslib = new IdsToolbox({\n name: \"magic-nix-cache\",\n fetchStyle: \"gh-env-style\",\n idsProjectName: \"magic-nix-cache-closure\",\n requireNix: \"warn\",\n });\n\n this.strictMode = inputs.getBool(\"strict-mode\");\n\n this.client = got.extend({\n retry: {\n limit: 1,\n methods: [\"POST\", \"GET\", \"PUT\", \"HEAD\", \"DELETE\", \"OPTIONS\", \"TRACE\"],\n },\n hooks: {\n beforeRetry: [\n (error, retryCount) => {\n actionsCore.info(\n `Retrying after error ${error.code}, retry #: ${retryCount}`,\n );\n },\n ],\n },\n });\n\n this.daemonStarted = actionsCore.getState(STATE_STARTED) === STARTED_HINT;\n\n if (actionsCore.getState(STATE_DAEMONDIR) !== \"\") {\n this.daemonDir = actionsCore.getState(STATE_DAEMONDIR);\n } else {\n this.daemonDir = this.idslib.getTemporaryName();\n mkdirSync(this.daemonDir);\n actionsCore.saveState(STATE_DAEMONDIR, this.daemonDir);\n }\n\n if (process.env[ENV_DAEMON_DIR] === undefined) {\n this.noopMode = false;\n actionsCore.exportVariable(ENV_DAEMON_DIR, this.daemonDir);\n } else {\n this.noopMode = process.env[ENV_DAEMON_DIR] !== this.daemonDir;\n }\n this.idslib.addFact(\"noop_mode\", this.noopMode);\n\n this.idslib.stapleFile(\n \"daemon.log\",\n path.join(this.daemonDir, \"daemon.log\"),\n );\n }\n\n async setUpAutoCache(): Promise {\n const requiredEnv = [\n \"ACTIONS_CACHE_URL\",\n \"ACTIONS_RUNTIME_URL\",\n \"ACTIONS_RUNTIME_TOKEN\",\n ];\n\n let anyMissing = false;\n for (const n of requiredEnv) {\n if (!process.env.hasOwnProperty(n)) {\n anyMissing = true;\n actionsCore.warning(\n `Disabling automatic caching since required environment ${n} isn't available`,\n );\n }\n }\n\n this.idslib.addFact(\"authenticated_env\", !anyMissing);\n if (anyMissing) {\n return;\n }\n\n if (this.daemonStarted) {\n actionsCore.debug(\"Already started.\");\n return;\n }\n\n actionsCore.debug(\n `GitHub Action Cache URL: ${process.env[\"ACTIONS_CACHE_URL\"]}`,\n );\n\n const sourceBinary = inputs.getStringOrNull(\"source-binary\");\n const daemonBin =\n sourceBinary !== null ? sourceBinary : await this.fetchAutoCacher();\n\n let runEnv;\n if (actionsCore.isDebug()) {\n runEnv = {\n RUST_LOG: \"trace,magic_nix_cache=debug,gha_cache=debug\",\n RUST_BACKTRACE: \"full\",\n ...process.env,\n };\n } else {\n runEnv = process.env;\n }\n\n const notifyPort = inputs.getString(\"startup-notification-port\");\n\n const notifyPromise = new Promise>((resolveListening) => {\n const promise = new Promise(async (resolveQuit) => {\n const notifyServer = http.createServer((req, res) => {\n if (req.method === \"POST\" && req.url === \"/\") {\n actionsCore.debug(`Notify server shutting down.`);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(\"{}\");\n notifyServer.close(() => {\n resolveQuit();\n });\n }\n });\n\n notifyServer.listen(notifyPort, () => {\n actionsCore.debug(`Notify server running.`);\n resolveListening(promise);\n });\n });\n });\n\n // Start tailing the daemon log.\n const outputPath = `${this.daemonDir}/daemon.log`;\n const output = openSync(outputPath, \"a\");\n const log = tailLog(this.daemonDir);\n const netrc = await netrcPath();\n const nixConfPath = `${process.env[\"HOME\"]}/.config/nix/nix.conf`;\n\n const hostAndPort = inputs.getString(\"listen\");\n const upstreamCache = inputs.getString(\"upstream-cache\");\n const diagnosticEndpoint = inputs.getString(\"diagnostic-endpoint\");\n const useFlakeHub = inputs.getBool(\"use-flakehub\");\n const flakeHubCacheServer = inputs.getString(\"flakehub-cache-server\");\n const flakeHubApiServer = inputs.getString(\"flakehub-api-server\");\n const flakeHubFlakeName = inputs.getString(\"flakehub-flake-name\");\n const useGhaCache = inputs.getBool(\"use-gha-cache\");\n\n const daemonCliFlags: string[] = [\n \"--startup-notification-url\",\n `http://127.0.0.1:${notifyPort}`,\n \"--listen\",\n hostAndPort,\n \"--upstream\",\n upstreamCache,\n \"--diagnostic-endpoint\",\n diagnosticEndpoint,\n \"--nix-conf\",\n nixConfPath,\n ]\n .concat(\n useFlakeHub\n ? [\n \"--use-flakehub\",\n \"--flakehub-cache-server\",\n flakeHubCacheServer,\n \"--flakehub-api-server\",\n flakeHubApiServer,\n \"--flakehub-api-server-netrc\",\n netrc,\n \"--flakehub-flake-name\",\n flakeHubFlakeName,\n ]\n : [],\n )\n .concat(useGhaCache ? [\"--use-gha-cache\"] : []);\n\n const opts: SpawnOptions = {\n stdio: [\"ignore\", output, output],\n env: runEnv,\n detached: true,\n };\n\n // Display the final command for debugging purposes\n actionsCore.debug(\"Full daemon start command:\");\n actionsCore.debug(`${daemonBin} ${daemonCliFlags.join(\" \")}`);\n\n // Start the server. Once it is ready, it will notify us via the notification server.\n const daemon = spawn(daemonBin, daemonCliFlags, opts);\n\n this.daemonStarted = true;\n actionsCore.saveState(STATE_STARTED, STARTED_HINT);\n\n const pidFile = path.join(this.daemonDir, \"daemon.pid\");\n await fs.writeFile(pidFile, `${daemon.pid}`);\n\n actionsCore.info(\"Waiting for magic-nix-cache to start...\");\n\n await new Promise((resolve, reject) => {\n notifyPromise\n // eslint-disable-next-line github/no-then\n .then((_value) => {\n resolve();\n })\n // eslint-disable-next-line github/no-then\n .catch((err) => {\n const msg = `error in notifyPromise: ${err}`;\n reject(new Error(msg));\n this.failInStrictMode(msg);\n });\n daemon.on(\"exit\", async (code, signal) => {\n let msg: string;\n if (signal) {\n msg = `Daemon was killed by signal ${signal}`;\n } else if (code) {\n msg = `Daemon exited with code ${code}`;\n } else {\n msg = \"Daemon unexpectedly exited\";\n }\n reject(new Error(msg));\n this.failInStrictMode(msg);\n });\n });\n\n daemon.unref();\n\n actionsCore.info(\"Launched Magic Nix Cache\");\n\n log.unwatch();\n }\n\n private async fetchAutoCacher(): Promise {\n const closurePath = await this.idslib.fetch();\n this.idslib.recordEvent(\"load_closure\");\n const { stdout } = await promisify(exec)(\n `cat \"${closurePath}\" | xz -d | nix-store --import`,\n );\n\n const paths = stdout.split(os.EOL);\n // Since the export is in reverse topologically sorted order, magic-nix-cache is always the penultimate entry in the list (the empty string left by split being the last).\n const lastPath = paths.at(-2);\n return `${lastPath}/bin/magic-nix-cache`;\n }\n\n async notifyAutoCache(): Promise {\n if (!this.daemonStarted) {\n actionsCore.debug(\"magic-nix-cache not started - Skipping\");\n return;\n }\n\n try {\n actionsCore.debug(`Indicating workflow start`);\n const hostAndPort = inputs.getString(\"listen\");\n const res: Response = await this.client.post(\n `http://${hostAndPort}/api/workflow-start`,\n );\n\n if (res.statusCode !== 200) {\n this.failInStrictMode(\n `Failed to trigger workflow start hook. Expected status 200 but got ${res.statusCode}`,\n );\n }\n\n actionsCore.debug(`back from post: ${JSON.stringify(res)}`);\n } catch (e) {\n actionsCore.info(`Error marking the workflow as started:`);\n actionsCore.info(inspect(e));\n actionsCore.info(`Magic Nix Cache may not be running for this workflow.`);\n\n this.failInStrictMode(`Magic Nix Cache failed to start: ${inspect(e)}`);\n }\n }\n\n async tearDownAutoCache(): Promise {\n if (!this.daemonStarted) {\n actionsCore.debug(\"magic-nix-cache not started - Skipping\");\n return;\n }\n\n const pidFile = path.join(this.daemonDir, \"daemon.pid\");\n const pid = parseInt(await fs.readFile(pidFile, { encoding: \"ascii\" }));\n actionsCore.debug(`found daemon pid: ${pid}`);\n if (!pid) {\n const msg = \"magic-nix-cache did not start successfully\";\n this.failInStrictMode(msg);\n throw new Error(msg);\n }\n\n const log = tailLog(this.daemonDir);\n\n try {\n actionsCore.debug(`about to post to localhost`);\n const hostAndPort = inputs.getString(\"listen\");\n const res: Response = await this.client.post(\n `http://${hostAndPort}/api/workflow-finish`,\n );\n\n if (res.statusCode !== 200) {\n this.failInStrictMode(\n `Failed to trigger workflow finish hook. Expected status 200 but got ${res.statusCode}`,\n );\n }\n\n actionsCore.debug(`back from post: ${JSON.stringify(res.body)}`);\n } finally {\n actionsCore.debug(`unwatching the daemon log`);\n log.unwatch();\n }\n\n actionsCore.debug(`killing`);\n try {\n process.kill(pid, \"SIGTERM\");\n } catch (e) {\n if (typeof e === \"object\" && e && \"code\" in e && e.code !== \"ESRCH\") {\n this.failInStrictMode(e.toString());\n throw e;\n }\n } finally {\n if (actionsCore.isDebug()) {\n actionsCore.info(\"Entire log:\");\n const entireLog = readFileSync(path.join(this.daemonDir, \"daemon.log\"));\n actionsCore.info(entireLog.toString());\n }\n }\n }\n\n private failInStrictMode(msg: string): void {\n if (this.strictMode) {\n actionsCore.setFailed(`strict mode error: ${msg}`);\n }\n }\n}\n\nfunction main(): void {\n const cacheAction = new MagicNixCacheAction();\n\n cacheAction.idslib.onMain(async () => {\n if (cacheAction.noopMode) {\n actionsCore.warning(TEXT_NOOP);\n return;\n }\n\n if (cacheAction.idslib.nixStoreTrust === \"untrusted\") {\n actionsCore.warning(TEXT_TRUST_UNTRUSTED);\n return;\n } else if (cacheAction.idslib.nixStoreTrust === \"unknown\") {\n actionsCore.info(TEXT_TRUST_UNKNOWN);\n }\n\n await cacheAction.setUpAutoCache();\n await cacheAction.notifyAutoCache();\n });\n cacheAction.idslib.onPost(async () => {\n if (cacheAction.noopMode) {\n actionsCore.debug(TEXT_NOOP);\n return;\n }\n\n if (cacheAction.idslib.nixStoreTrust === \"untrusted\") {\n actionsCore.debug(TEXT_TRUST_UNTRUSTED);\n return;\n } else if (cacheAction.idslib.nixStoreTrust === \"unknown\") {\n actionsCore.debug(TEXT_TRUST_UNKNOWN);\n }\n\n await cacheAction.tearDownAutoCache();\n });\n\n cacheAction.idslib.execute();\n}\n\nmain();\n"],"mappings":"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","names":["actionsCore","fs","os","path"]} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index d518755..16a141e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import { netrcPath, tailLog } from "./helpers.js"; import * as actionsCore from "@actions/core"; import { IdsToolbox, inputs } from "detsys-ts"; -import got, { Got } from "got"; +import got, { Got, Response } from "got"; import * as http from "http"; import { SpawnOptions, exec, spawn } from "node:child_process"; import { mkdirSync, openSync, readFileSync } from "node:fs"; @@ -274,10 +274,17 @@ class MagicNixCacheAction { try { actionsCore.debug(`Indicating workflow start`); const hostAndPort = inputs.getString("listen"); - const res: Response = await this.client - .post(`http://${hostAndPort}/api/workflow-start`) - .json(); - actionsCore.debug(`back from post: ${res}`); + const res: Response = await this.client.post( + `http://${hostAndPort}/api/workflow-start`, + ); + + if (res.statusCode !== 200) { + this.failInStrictMode( + `Failed to trigger workflow start hook. Expected status 200 but got ${res.statusCode}`, + ); + } + + actionsCore.debug(`back from post: ${JSON.stringify(res)}`); } catch (e) { actionsCore.info(`Error marking the workflow as started:`); actionsCore.info(inspect(e)); @@ -307,17 +314,17 @@ class MagicNixCacheAction { try { actionsCore.debug(`about to post to localhost`); const hostAndPort = inputs.getString("listen"); - const res: Response = await this.client - .post(`http://${hostAndPort}/api/workflow-finish`) - .json(); + const res: Response = await this.client.post( + `http://${hostAndPort}/api/workflow-finish`, + ); - if (res.status !== 200) { + if (res.statusCode !== 200) { this.failInStrictMode( - `Failed to trigger workflow finish hook. Response: ${JSON.stringify(res)}`, + `Failed to trigger workflow finish hook. Expected status 200 but got ${res.statusCode}`, ); } - actionsCore.debug(`back from post: ${res}`); + actionsCore.debug(`back from post: ${JSON.stringify(res.body)}`); } finally { actionsCore.debug(`unwatching the daemon log`); log.unwatch();