diff --git a/dist/index.d.ts b/dist/index.d.ts index 01adf5c..6a0cd97 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -70,7 +70,7 @@ declare class IdsHost { private prioritizedURLs?; private client?; constructor(idsProjectName: string, diagnosticsSuffix: string | undefined, runtimeDiagnosticsUrl: string | undefined); - getGot(recordFailoverCallback?: (incitingError: unknown, prevUrl: URL, nextUrl: URL) => void): Promise; + getGot(recordFailoverCallback?: (incitingError: unknown, prevUrl: URL, nextUrl: URL) => void, timeout?: number): Promise; markCurrentHostBroken(): void; setPrioritizedUrls(urls: URL[]): void; isUrlSubjectToDynamicUrls(url: URL): boolean; @@ -262,11 +262,11 @@ declare abstract class DetSysAction { * Fetches the executable at the URL determined by the `source-*` inputs and * other facts, `chmod`s it, and returns the path to the executable on disk. */ - fetchExecutable(): Promise; + fetchExecutable(timeout?: number): Promise; private get isMain(); private get isPost(); private executeAsync; - getClient(): Promise; + getClient(timeout?: number): Promise; private checkIn; getFeature(name: string): Feature | undefined; /** diff --git a/dist/index.js b/dist/index.js index 3ee1b7a..da52b58 100644 --- a/dist/index.js +++ b/dist/index.js @@ -266,8 +266,7 @@ async function collectBacktracesMacOS(prefixes, programNameDenyList, startTimest const doGzip = promisify(gzip); for (const fileName of fileNames) try { if ((await stat(`${dir}/${fileName}`)).ctimeMs >= startTimestampMs) { - const logText = await readFile(`${dir}/${fileName}`); - const buf = await doGzip(logText); + const buf = await doGzip(await readFile(`${dir}/${fileName}`)); backtraces.set(`backtrace_value_${source}_${fileName}`, buf.toString("base64")); } } catch (innerError) { @@ -421,9 +420,9 @@ var IdsHost = class { this.runtimeDiagnosticsUrl = runtimeDiagnosticsUrl; this.client = void 0; } - async getGot(recordFailoverCallback) { + async getGot(recordFailoverCallback, timeout) { if (this.client === void 0) this.client = got.extend({ - timeout: { request: DEFAULT_TIMEOUT }, + timeout: { request: timeout ?? DEFAULT_TIMEOUT }, retry: { limit: Math.max((await this.getUrlsByPreference()).length, 3), methods: ["GET", "HEAD"] @@ -567,7 +566,7 @@ function weightedRandom(records) { //#endregion //#region src/inputs.ts -var inputs_exports = __export({ +var inputs_exports = /* @__PURE__ */ __export({ getArrayOfStrings: () => getArrayOfStrings, getArrayOfStringsOrNull: () => getArrayOfStringsOrNull, getBool: () => getBool, @@ -597,8 +596,7 @@ const getBoolOrUndefined = (name) => { * all whitespace is removed from the string before converting to an array. */ const getArrayOfStrings = (name, separator) => { - const original = getString(name); - return handleString(original, separator); + return handleString(getString(name), separator); }; /** * Convert a string input into an array of strings or `null` if no value is set. @@ -655,7 +653,7 @@ const getStringOrUndefined = (name) => { //#endregion //#region src/platform.ts -var platform_exports = __export({ +var platform_exports = /* @__PURE__ */ __export({ getArchOs: () => getArchOs, getNixPlatform: () => getNixPlatform }); @@ -808,14 +806,13 @@ var DetSysAction = class { project: this.actionOptions.name, ids_project: this.actionOptions.idsProjectName }; - const params = [ + for (const [target, env] of [ ["github_action_ref", "GITHUB_ACTION_REF"], ["github_action_repository", "GITHUB_ACTION_REPOSITORY"], ["github_event_name", "GITHUB_EVENT_NAME"], ["$os", "RUNNER_OS"], ["arch", "RUNNER_ARCH"] - ]; - for (const [target, env] of params) { + ]) { const value = process.env[env]; if (value) this.facts[target] = value; } @@ -913,8 +910,8 @@ var DetSysAction = class { * Fetches the executable at the URL determined by the `source-*` inputs and * other facts, `chmod`s it, and returns the path to the executable on disk. */ - async fetchExecutable() { - const binaryPath = await this.fetchArtifact(); + async fetchExecutable(timeout) { + const binaryPath = await this.fetchArtifact(timeout); await chmod(binaryPath, constants.S_IXUSR | constants.S_IXGRP); return binaryPath; } @@ -956,8 +953,7 @@ var DetSysAction = class { const doGzip = promisify(gzip); const exceptionContext = /* @__PURE__ */ new Map(); for (const [attachmentLabel, filePath] of this.exceptionAttachments) try { - const logText = readFileSync(filePath); - const buf = await doGzip(logText); + const buf = await doGzip(readFileSync(filePath)); exceptionContext.set(`staple_value_${attachmentLabel}`, buf.toString("base64")); } catch (innerError) { exceptionContext.set(`staple_failure_${attachmentLabel}`, stringifyError$1(innerError)); @@ -968,14 +964,14 @@ var DetSysAction = class { await this.complete(); } } - async getClient() { + async getClient(timeout) { return await this.idsHost.getGot((incitingError, prevUrl, nextUrl) => { this.recordPlausibleTimeout(incitingError); this.recordEvent("ids-failover", { previousUrl: prevUrl.toString(), nextUrl: nextUrl.toString() }); - }); + }, timeout); } async checkIn() { const checkin = await this.requestCheckIn(); @@ -1063,7 +1059,7 @@ var DetSysAction = class { * URL determined by the other `source-*` inputs (`source-url`, `source-pr`, * etc.). */ - async fetchArtifact() { + async fetchArtifact(timeout) { const sourceBinary = getStringOrNull("source-binary"); if (sourceBinary !== null && sourceBinary !== "") { actionsCore.debug(`Using the provided source binary at ${sourceBinary}`); @@ -1075,7 +1071,7 @@ var DetSysAction = class { const correlatedUrl = await this.getSourceUrl(); correlatedUrl.searchParams.set("ci", "github"); correlatedUrl.searchParams.set("correlation", JSON.stringify(this.identity)); - const versionCheckup = await (await this.getClient()).head(correlatedUrl); + const versionCheckup = await (await this.getClient(timeout)).head(correlatedUrl); if (versionCheckup.headers.etag) { const v = versionCheckup.headers.etag; this.addFact(FACT_SOURCE_URL_ETAG, v); @@ -1090,7 +1086,7 @@ var DetSysAction = class { this.facts[FACT_ARTIFACT_FETCHED_FROM_CACHE] = false; actionsCore.debug(`No match from the cache, re-fetching from the redirect: ${versionCheckup.url}`); const destFile = this.getTemporaryName(); - const fetchStream = await this.downloadFile(new URL(versionCheckup.url), destFile); + const fetchStream = await this.downloadFile(new URL(versionCheckup.url), destFile, timeout); if (fetchStream.response?.headers.etag) { const v = fetchStream.response.headers.etag; try { @@ -1114,8 +1110,8 @@ var DetSysAction = class { failOnError(msg) { if (this.strictMode) actionsCore.setFailed(`strict mode failure: ${msg}`); } - async downloadFile(url, destination) { - const client = await this.getClient(); + async downloadFile(url, destination, timeout) { + const client = await this.getClient(timeout); return new Promise((resolve, reject) => { let writeStream; let failed = false; diff --git a/dist/index.js.map b/dist/index.js.map index 6e6b0a6..e87b2da 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","names":["fs","linuxReleaseInfoOptionsDefaults: LinuxReleaseInfoOptions","searchOsReleaseFileList: string[]","os","lines: string[]","exec","data: object","ret: T","backtraces: Map","exec","sussyArray: unknown","innerError: unknown","coredumps: SystemdCoreDumpInfo[]","ident: AnonymizedCorrelationHashes","currentUrl: URL","newUrl: URL","err: unknown","url: URL | undefined","defaultFallback: Promise","records: SrvRecord[]","reason: unknown","byPriorityWeight: Map","prioritizedRecords: SrvRecord[]","keys: number[]","scratchRecords: SrvRecord[]","result: SrvRecord[]","weights: number[]","os","actionsExec","correlation.identify","platform.getArchOs","platform.getNixPlatform","stringifyError","fsConstants","e: unknown","exceptionContext: Map","innerError: unknown","impactSymbol: Map","summaries: string[]","reportContext: {\n [index: string]: string | number | undefined;\n }","writeStream: WriteStream | undefined","nixLocation: string | undefined","options: actionsExec.ExecOptions","err: unknown","finalOpts: ConfidentActionOptions"],"sources":["../src/linux-release-info.ts","../src/actions-core-platform.ts","../src/errors.ts","../src/backtrace.ts","../src/correlation.ts","../src/ids-host.ts","../src/inputs.ts","../src/platform.ts","../src/sourcedef.ts","../src/index.ts"],"sourcesContent":["/*!\n * linux-release-info\n * Get Linux release info (distribution name, version, arch, release, etc.)\n * from '/etc/os-release' or '/usr/lib/os-release' files and from native os\n * module. On Windows and Darwin platforms it only returns common node os module\n * info (platform, hostname, release, and arch)\n *\n * Licensed under MIT\n * Copyright (c) 2018-2020 [Samuel Carreira]\n */\n// NOTE: we depend on this directly to get around some un-fun issues with mixing CommonJS\n// and ESM in the bundle. We've modified the original logic to improve things like typing\n// and fixing ESLint issues. Originally drawn from:\n// https://github.com/samuelcarreira/linux-release-info/blob/84a91aa5442b47900da03020c590507545d3dc74/src/index.ts\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport { promisify } from \"node:util\";\n\nconst readFileAsync = promisify(fs.readFile);\n\nexport interface LinuxReleaseInfoOptions {\n /**\n * read mode, possible values: 'async' and 'sync'\n *\n * @default 'async'\n */\n mode?: \"async\" | \"sync\";\n /**\n * custom complete file path with os info default null/none\n * if not provided the system will search on the '/etc/os-release'\n * and '/usr/lib/os-release' files\n *\n * @default null\n */\n customFile?: string | null | undefined;\n /**\n * if true, show console debug messages\n *\n * @default false\n */\n debug?: boolean;\n}\n\nconst linuxReleaseInfoOptionsDefaults: LinuxReleaseInfoOptions = {\n mode: \"async\",\n customFile: null,\n debug: false,\n};\n\n/**\n * Get OS release info from 'os-release' file and from native os module\n * on Windows or Darwin it only returns common os module info\n * (uses native fs module)\n * @returns {object} info from the current os\n */\nexport function releaseInfo(infoOptions: LinuxReleaseInfoOptions): object {\n const options = { ...linuxReleaseInfoOptionsDefaults, ...infoOptions };\n\n const searchOsReleaseFileList: string[] = osReleaseFileList(\n options.customFile,\n );\n\n if (os.type() !== \"Linux\") {\n if (options.mode === \"sync\") {\n return getOsInfo();\n } else {\n return Promise.resolve(getOsInfo());\n }\n }\n\n if (options.mode === \"sync\") {\n return readSyncOsreleaseFile(searchOsReleaseFileList, options);\n } else {\n return Promise.resolve(\n readAsyncOsReleaseFile(searchOsReleaseFileList, options),\n );\n }\n}\n\n/**\n * Format file data: convert data to object keys/values\n *\n * @param {object} sourceData Source object to be appended\n * @param {string} srcParseData Input file data to be parsed\n * @returns {object} Formated object\n */\nfunction formatFileData(sourceData: OsInfo, srcParseData: string): OsInfo {\n const lines: string[] = srcParseData.split(\"\\n\");\n\n for (const line of lines) {\n const lineData = line.split(\"=\");\n\n if (lineData.length === 2) {\n lineData[1] = lineData[1].replace(/[\"'\\r]/gi, \"\"); // remove quotes and return character\n\n Object.defineProperty(sourceData, lineData[0].toLowerCase(), {\n value: lineData[1],\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n }\n\n return sourceData;\n}\n\n/**\n * Export a list of os-release files\n *\n * @param {string} customFile optional custom complete filepath\n * @returns {array} list of os-release files\n */\nfunction osReleaseFileList(customFile: string | null | undefined): string[] {\n const DEFAULT_OS_RELEASE_FILES = [\"/etc/os-release\", \"/usr/lib/os-release\"];\n\n if (!customFile) {\n return DEFAULT_OS_RELEASE_FILES;\n } else {\n return Array(customFile);\n }\n}\n\n/**\n * Operating system info.\n */\ntype OsInfo = {\n type: string;\n platform: string;\n hostname: string;\n arch: string;\n release: string;\n};\n\n/**\n * Get OS Basic Info\n * (uses node 'os' native module)\n *\n * @returns {OsInfo} os basic info\n */\nfunction getOsInfo(): OsInfo {\n return {\n type: os.type(),\n platform: os.platform(),\n hostname: os.hostname(),\n arch: os.arch(),\n release: os.release(),\n };\n}\n\n/* Helper functions */\n\nasync function readAsyncOsReleaseFile(\n fileList: string[],\n options: LinuxReleaseInfoOptions,\n): Promise {\n let fileData = null;\n\n for (const osReleaseFile of fileList) {\n try {\n if (options.debug) {\n /* eslint-disable no-console */\n console.log(`Trying to read '${osReleaseFile}'...`);\n }\n\n fileData = await readFileAsync(osReleaseFile, \"binary\");\n\n if (options.debug) {\n console.log(`Read data:\\n${fileData}`);\n }\n\n break;\n } catch (error) {\n if (options.debug) {\n console.error(error);\n }\n }\n }\n\n if (fileData === null) {\n throw new Error(\"Cannot read os-release file!\");\n //return getOsInfo();\n }\n\n return formatFileData(getOsInfo(), fileData);\n}\n\nfunction readSyncOsreleaseFile(\n releaseFileList: string[],\n options: LinuxReleaseInfoOptions,\n): OsInfo {\n let fileData = null;\n\n for (const osReleaseFile of releaseFileList) {\n try {\n if (options.debug) {\n console.log(`Trying to read '${osReleaseFile}'...`);\n }\n\n fileData = fs.readFileSync(osReleaseFile, \"binary\");\n\n if (options.debug) {\n console.log(`Read data:\\n${fileData}`);\n }\n\n break;\n } catch (error) {\n if (options.debug) {\n console.error(error);\n }\n }\n }\n\n if (fileData === null) {\n throw new Error(\"Cannot read os-release file!\");\n //return getOsInfo();\n }\n\n return formatFileData(getOsInfo(), fileData);\n}\n","// MIT, mostly lifted from https://github.com/actions/toolkit/blob/5a736647a123ecf8582376bdaee833fbae5b3847/packages/core/src/platform.ts\n// since it isn't in @actions/core 1.10.1 which is their current release as 2024-04-19.\n// Changes: Replaced the lsb_release call in Linux with `linux-release-info` to parse the os-release file directly.\nimport { releaseInfo } from \"./linux-release-info.js\";\nimport * as actionsCore from \"@actions/core\";\nimport * as exec from \"@actions/exec\";\nimport os from \"os\";\n\n/**\n * The name and version of the Action runner's system.\n */\ntype SystemInfo = {\n name: string;\n version: string;\n};\n\n/**\n * Get the name and version of the current Windows system.\n */\nconst getWindowsInfo = async (): Promise => {\n const { stdout: version } = await exec.getExecOutput(\n 'powershell -command \"(Get-CimInstance -ClassName Win32_OperatingSystem).Version\"',\n undefined,\n {\n silent: true,\n },\n );\n\n const { stdout: name } = await exec.getExecOutput(\n 'powershell -command \"(Get-CimInstance -ClassName Win32_OperatingSystem).Caption\"',\n undefined,\n {\n silent: true,\n },\n );\n\n return {\n name: name.trim(),\n version: version.trim(),\n };\n};\n\n/**\n * Get the name and version of the current macOS system.\n */\nconst getMacOsInfo = async (): Promise => {\n const { stdout } = await exec.getExecOutput(\"sw_vers\", undefined, {\n silent: true,\n });\n\n const version = stdout.match(/ProductVersion:\\s*(.+)/)?.[1] ?? \"\";\n const name = stdout.match(/ProductName:\\s*(.+)/)?.[1] ?? \"\";\n\n return {\n name,\n version,\n };\n};\n\n/**\n * Get the name and version of the current Linux system.\n */\nconst getLinuxInfo = async (): Promise => {\n let data: object = {};\n\n try {\n data = releaseInfo({ mode: \"sync\" });\n actionsCore.debug(`Identified release info: ${JSON.stringify(data)}`);\n } catch (e) {\n actionsCore.debug(`Error collecting release info: ${e}`);\n }\n\n return {\n name: getPropertyViaWithDefault(\n data,\n [\"id\", \"name\", \"pretty_name\", \"id_like\"],\n \"unknown\",\n ),\n version: getPropertyViaWithDefault(\n data,\n [\"version_id\", \"version\", \"version_codename\"],\n \"unknown\",\n ),\n };\n};\n\nfunction getPropertyViaWithDefault(\n data: object,\n names: Property[],\n defaultValue: T,\n): T {\n for (const name of names) {\n const ret: T = getPropertyWithDefault(data, name, defaultValue);\n\n if (ret !== defaultValue) {\n return ret;\n }\n }\n\n return defaultValue;\n}\n\nfunction getPropertyWithDefault(\n data: object,\n name: Property,\n defaultValue: T,\n): T {\n if (!data.hasOwnProperty(name)) {\n return defaultValue;\n }\n\n const value = (data as { [K in Property]: T })[name];\n\n // NB. this check won't work for object instances\n if (typeof value !== typeof defaultValue) {\n return defaultValue;\n }\n\n return value;\n}\n\n/**\n * The Action runner's platform.\n */\nexport const platform = os.platform();\n\n/**\n * The Action runner's architecture.\n */\nexport const arch = os.arch();\n\n/**\n * Whether the Action runner is a Windows system.\n */\nexport const isWindows = platform === \"win32\";\n\n/**\n * Whether the Action runner is a macOS system.\n */\nexport const isMacOS = platform === \"darwin\";\n\n/**\n * Whether the Action runner is a Linux system.\n */\nexport const isLinux = platform === \"linux\";\n\n/**\n * System-level information about the current host (platform, architecture, etc.).\n */\ntype SystemDetails = {\n name: string;\n platform: string;\n arch: string;\n version: string;\n isWindows: boolean;\n isMacOS: boolean;\n isLinux: boolean;\n};\n\n/**\n * Get system-level information about the current host (platform, architecture, etc.).\n */\nexport async function getDetails(): Promise {\n return {\n ...(await (isWindows\n ? getWindowsInfo()\n : isMacOS\n ? getMacOsInfo()\n : getLinuxInfo())),\n platform,\n arch,\n isWindows,\n isMacOS,\n isLinux,\n };\n}\n","/**\n * Coerce a value of type `unknown` into a string.\n */\nexport function stringifyError(e: unknown): string {\n if (e instanceof Error) {\n return e.message;\n } else if (typeof e === \"string\") {\n return e;\n } else {\n return JSON.stringify(e);\n }\n}\n","/**\n * @packageDocumentation\n * Collects backtraces for executables for diagnostics\n */\nimport { isLinux, isMacOS } from \"./actions-core-platform.js\";\nimport { stringifyError } from \"./errors.js\";\nimport * as actionsCore from \"@actions/core\";\nimport * as exec from \"@actions/exec\";\nimport { readFile, readdir, stat } from \"node:fs/promises\";\nimport { promisify } from \"node:util\";\nimport { gzip } from \"node:zlib\";\n\n// Give a few seconds buffer, capturing traces that happened a few seconds earlier.\nconst START_SLOP_SECONDS = 5;\n\nexport async function collectBacktraces(\n prefixes: string[],\n programNameDenyList: string[],\n startTimestampMs: number,\n): Promise> {\n if (isMacOS) {\n return await collectBacktracesMacOS(\n prefixes,\n programNameDenyList,\n startTimestampMs,\n );\n }\n if (isLinux) {\n return await collectBacktracesSystemd(\n prefixes,\n programNameDenyList,\n startTimestampMs,\n );\n }\n\n return new Map();\n}\n\nexport async function collectBacktracesMacOS(\n prefixes: string[],\n programNameDenyList: string[],\n startTimestampMs: number,\n): Promise> {\n const backtraces: Map = new Map();\n\n try {\n const { stdout: logJson } = await exec.getExecOutput(\n \"log\",\n [\n \"show\",\n \"--style\",\n \"json\",\n \"--last\",\n // Note we collect the last 1m only, because it should only take a few seconds to write the crash log.\n // Therefore, any crashes before this 1m should be long done by now.\n \"1m\",\n \"--no-info\",\n \"--predicate\",\n \"sender = 'ReportCrash'\",\n ],\n {\n silent: true,\n },\n );\n\n const sussyArray: unknown = JSON.parse(logJson);\n if (!Array.isArray(sussyArray)) {\n throw new Error(`Log json isn't an array: ${logJson}`);\n }\n\n if (sussyArray.length > 0) {\n actionsCore.info(`Collecting crash data...`);\n const delay = async (ms: number): Promise =>\n new Promise((resolve) => setTimeout(resolve, ms));\n await delay(5000);\n }\n } catch {\n actionsCore.debug(\n \"Failed to check logs for in-progress crash dumps; now proceeding with the assumption that all crash dumps completed.\",\n );\n }\n\n const dirs = [\n [\"system\", \"/Library/Logs/DiagnosticReports/\"],\n [\"user\", `${process.env[\"HOME\"]}/Library/Logs/DiagnosticReports/`],\n ];\n\n for (const [source, dir] of dirs) {\n const fileNames = (await readdir(dir))\n .filter((fileName) => {\n return prefixes.some((prefix) => fileName.startsWith(prefix));\n })\n .filter((fileName) => {\n return !programNameDenyList.some((programName) =>\n fileName.startsWith(programName),\n );\n })\n .filter((fileName) => {\n // macOS creates .diag files periodically, which are called \"microstackshots\".\n // We don't necessarily want those, and they're definitely not crashes.\n // See: https://patents.google.com/patent/US20140237219A1/en\n return !fileName.endsWith(\".diag\");\n });\n\n const doGzip = promisify(gzip);\n for (const fileName of fileNames) {\n try {\n if ((await stat(`${dir}/${fileName}`)).ctimeMs >= startTimestampMs) {\n const logText = await readFile(`${dir}/${fileName}`);\n const buf = await doGzip(logText);\n backtraces.set(\n `backtrace_value_${source}_${fileName}`,\n buf.toString(\"base64\"),\n );\n }\n } catch (innerError: unknown) {\n backtraces.set(\n `backtrace_failure_${source}_${fileName}`,\n stringifyError(innerError),\n );\n }\n }\n }\n\n return backtraces;\n}\n\ntype SystemdCoreDumpInfo = {\n exe: string;\n pid: number;\n};\n\nexport async function collectBacktracesSystemd(\n prefixes: string[],\n programNameDenyList: string[],\n startTimestampMs: number,\n): Promise> {\n const sinceSeconds =\n Math.ceil((Date.now() - startTimestampMs) / 1000) + START_SLOP_SECONDS;\n const backtraces: Map = new Map();\n\n const coredumps: SystemdCoreDumpInfo[] = [];\n\n try {\n const { stdout: coredumpjson } = await exec.getExecOutput(\n \"coredumpctl\",\n [\"--json=pretty\", \"list\", \"--since\", `${sinceSeconds} seconds ago`],\n {\n silent: true,\n },\n );\n\n const sussyArray: unknown = JSON.parse(coredumpjson);\n if (!Array.isArray(sussyArray)) {\n throw new Error(`Coredump isn't an array: ${coredumpjson}`);\n }\n\n for (const sussyObject of sussyArray) {\n const keys = Object.keys(sussyObject);\n\n if (keys.includes(\"exe\") && keys.includes(\"pid\")) {\n if (\n typeof sussyObject.exe == \"string\" &&\n typeof sussyObject.pid == \"number\"\n ) {\n const execParts = sussyObject.exe.split(\"/\");\n const binaryName = execParts[execParts.length - 1];\n\n if (\n prefixes.some((prefix) => binaryName.startsWith(prefix)) &&\n !programNameDenyList.includes(binaryName)\n ) {\n coredumps.push({\n exe: sussyObject.exe,\n pid: sussyObject.pid,\n });\n }\n } else {\n actionsCore.debug(\n `Mysterious coredump entry missing exe string and/or pid number: ${JSON.stringify(sussyObject)}`,\n );\n }\n } else {\n actionsCore.debug(\n `Mysterious coredump entry missing exe value and/or pid value: ${JSON.stringify(sussyObject)}`,\n );\n }\n }\n } catch (innerError: unknown) {\n actionsCore.debug(\n `Cannot collect backtraces: ${stringifyError(innerError)}`,\n );\n\n return backtraces;\n }\n\n const doGzip = promisify(gzip);\n for (const coredump of coredumps) {\n try {\n const { stdout: logText } = await exec.getExecOutput(\n \"coredumpctl\",\n [\"info\", `${coredump.pid}`],\n {\n silent: true,\n },\n );\n\n const buf = await doGzip(logText);\n backtraces.set(`backtrace_value_${coredump.pid}`, buf.toString(\"base64\"));\n } catch (innerError: unknown) {\n backtraces.set(\n `backtrace_failure_${coredump.pid}`,\n stringifyError(innerError),\n );\n }\n }\n\n return backtraces;\n}\n","import * as actionsCore from \"@actions/core\";\nimport { createHash, randomUUID } from \"node:crypto\";\n\nconst OPTIONAL_VARIABLES = [\"INVOCATION_ID\"];\n\n/* eslint-disable camelcase */\n/**\n * JSON sent to server.\n */\nexport type AnonymizedCorrelationHashes = {\n $anon_distinct_id: string;\n $groups: Record;\n $session_id?: string;\n correlation_source: string;\n github_repository_hash?: string;\n github_workflow_hash?: string;\n github_workflow_job_hash?: string;\n github_workflow_run_differentiator_hash?: string;\n github_workflow_run_hash?: string;\n is_ci: boolean;\n};\n\nexport function identify(): AnonymizedCorrelationHashes {\n const repository = hashEnvironmentVariables(\"GHR\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n ]);\n\n const run_differentiator = hashEnvironmentVariables(\"GHWJA\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n \"GITHUB_WORKFLOW\",\n \"GITHUB_JOB\",\n \"GITHUB_RUN_ID\",\n \"GITHUB_RUN_NUMBER\",\n \"GITHUB_RUN_ATTEMPT\",\n \"INVOCATION_ID\",\n ]);\n\n const ident: AnonymizedCorrelationHashes = {\n $anon_distinct_id: process.env[\"RUNNER_TRACKING_ID\"] || randomUUID(),\n\n correlation_source: \"github-actions\",\n\n github_repository_hash: repository,\n github_workflow_hash: hashEnvironmentVariables(\"GHW\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n \"GITHUB_WORKFLOW\",\n ]),\n github_workflow_job_hash: hashEnvironmentVariables(\"GHWJ\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n \"GITHUB_WORKFLOW\",\n \"GITHUB_JOB\",\n ]),\n github_workflow_run_hash: hashEnvironmentVariables(\"GHWJR\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n \"GITHUB_WORKFLOW\",\n \"GITHUB_JOB\",\n \"GITHUB_RUN_ID\",\n ]),\n github_workflow_run_differentiator_hash: run_differentiator,\n $session_id: run_differentiator,\n $groups: {\n github_repository: repository,\n github_organization: hashEnvironmentVariables(\"GHO\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n ]),\n },\n is_ci: true,\n };\n\n actionsCore.debug(\"Correlation data:\");\n actionsCore.debug(JSON.stringify(ident, null, 2));\n\n return ident;\n}\n\nfunction hashEnvironmentVariables(\n prefix: string,\n variables: string[],\n): undefined | string {\n const hash = createHash(\"sha256\");\n\n for (const varName of variables) {\n let value = process.env[varName];\n\n if (value === undefined) {\n if (OPTIONAL_VARIABLES.includes(varName)) {\n actionsCore.debug(\n `Optional environment variable not set: ${varName} -- substituting with the variable name`,\n );\n value = varName;\n } else {\n actionsCore.debug(\n `Environment variable not set: ${varName} -- can't generate the requested identity`,\n );\n return undefined;\n }\n }\n\n hash.update(value);\n hash.update(\"\\0\");\n }\n\n return `${prefix}-${hash.digest(\"hex\")}`;\n}\n","/**\n * @packageDocumentation\n * Identifies and discovers backend servers for install.determinate.systems\n */\nimport { stringifyError } from \"./errors.js\";\nimport * as actionsCore from \"@actions/core\";\nimport { Got, got } from \"got\";\nimport type { SrvRecord } from \"node:dns\";\nimport { resolveSrv } from \"node:dns/promises\";\n\nconst DEFAULT_LOOKUP = \"_detsys_ids._tcp.install.determinate.systems.\";\nconst ALLOWED_SUFFIXES = [\n \".install.determinate.systems\",\n \".install.detsys.dev\",\n];\n\nconst DEFAULT_IDS_HOST = \"https://install.determinate.systems\";\nconst LOOKUP = process.env[\"IDS_LOOKUP\"] ?? DEFAULT_LOOKUP;\n\nconst DEFAULT_TIMEOUT = 10_000; // 10 seconds in ms\n\n/**\n * Host information for install.determinate.systems.\n */\nexport class IdsHost {\n private idsProjectName: string;\n private diagnosticsSuffix?: string;\n private runtimeDiagnosticsUrl?: string;\n private prioritizedURLs?: URL[];\n private client?: Got;\n\n constructor(\n idsProjectName: string,\n diagnosticsSuffix: string | undefined,\n runtimeDiagnosticsUrl: string | undefined,\n ) {\n this.idsProjectName = idsProjectName;\n this.diagnosticsSuffix = diagnosticsSuffix;\n this.runtimeDiagnosticsUrl = runtimeDiagnosticsUrl;\n this.client = undefined;\n }\n\n async getGot(\n recordFailoverCallback?: (\n incitingError: unknown,\n prevUrl: URL,\n nextUrl: URL,\n ) => void,\n ): Promise {\n if (this.client === undefined) {\n this.client = got.extend({\n timeout: {\n request: DEFAULT_TIMEOUT,\n },\n\n retry: {\n limit: Math.max((await this.getUrlsByPreference()).length, 3),\n methods: [\"GET\", \"HEAD\"],\n },\n\n hooks: {\n beforeRetry: [\n async (error, retryCount) => {\n const prevUrl = await this.getRootUrl();\n this.markCurrentHostBroken();\n const nextUrl = await this.getRootUrl();\n\n if (recordFailoverCallback !== undefined) {\n recordFailoverCallback(error, prevUrl, nextUrl);\n }\n\n actionsCore.info(\n `Retrying after error ${error.code}, retry #: ${retryCount}`,\n );\n },\n ],\n\n beforeRequest: [\n async (options) => {\n // The getter always returns a URL, even though the setter accepts a string\n const currentUrl: URL = options.url as URL;\n\n if (this.isUrlSubjectToDynamicUrls(currentUrl)) {\n const newUrl: URL = new URL(currentUrl);\n\n const url: URL = await this.getRootUrl();\n newUrl.host = url.host;\n\n options.url = newUrl;\n actionsCore.debug(`Transmuted ${currentUrl} into ${newUrl}`);\n } else {\n actionsCore.debug(`No transmutations on ${currentUrl}`);\n }\n },\n ],\n },\n });\n }\n\n return this.client;\n }\n\n markCurrentHostBroken(): void {\n this.prioritizedURLs?.shift();\n }\n\n setPrioritizedUrls(urls: URL[]): void {\n this.prioritizedURLs = urls;\n }\n\n isUrlSubjectToDynamicUrls(url: URL): boolean {\n if (url.origin === DEFAULT_IDS_HOST) {\n return true;\n }\n\n for (const suffix of ALLOWED_SUFFIXES) {\n if (url.host.endsWith(suffix)) {\n return true;\n }\n }\n\n return false;\n }\n\n async getDynamicRootUrl(): Promise {\n const idsHost = process.env[\"IDS_HOST\"];\n if (idsHost !== undefined) {\n try {\n return new URL(idsHost);\n } catch (err: unknown) {\n actionsCore.error(\n `IDS_HOST environment variable is not a valid URL. Ignoring. ${stringifyError(err)}`,\n );\n }\n }\n\n let url: URL | undefined = undefined;\n try {\n const urls = await this.getUrlsByPreference();\n url = urls[0];\n } catch (err: unknown) {\n actionsCore.error(\n `Error collecting IDS URLs by preference: ${stringifyError(err)}`,\n );\n }\n\n if (url === undefined) {\n return undefined;\n } else {\n // This is a load-bearing `new URL(url)` so that callers can't mutate\n // getRootUrl's return value.\n return new URL(url);\n }\n }\n\n async getRootUrl(): Promise {\n const url = await this.getDynamicRootUrl();\n\n if (url === undefined) {\n return new URL(DEFAULT_IDS_HOST);\n }\n\n return url;\n }\n\n async getDiagnosticsUrl(): Promise {\n if (this.runtimeDiagnosticsUrl === \"\") {\n // User specifically set the diagnostics URL to an empty string\n // so disable diagnostics\n return undefined;\n }\n\n if (\n this.runtimeDiagnosticsUrl !== \"-\" &&\n this.runtimeDiagnosticsUrl !== undefined\n ) {\n try {\n // Caller specified a specific diagnostics URL\n return new URL(this.runtimeDiagnosticsUrl);\n } catch (err: unknown) {\n actionsCore.info(\n `User-provided diagnostic endpoint ignored: not a valid URL: ${stringifyError(err)}`,\n );\n }\n }\n\n try {\n const diagnosticUrl = await this.getRootUrl();\n diagnosticUrl.pathname += \"events/batch\";\n return diagnosticUrl;\n } catch (err: unknown) {\n actionsCore.info(\n `Generated diagnostic endpoint ignored, and diagnostics are disabled: not a valid URL: ${stringifyError(err)}`,\n );\n return undefined;\n }\n }\n\n private async getUrlsByPreference(): Promise {\n if (this.prioritizedURLs === undefined) {\n this.prioritizedURLs = orderRecordsByPriorityWeight(\n await discoverServiceRecords(),\n ).flatMap((record) => recordToUrl(record) || []);\n }\n\n return this.prioritizedURLs;\n }\n}\n\nexport function recordToUrl(record: SrvRecord): URL | undefined {\n const urlStr = `https://${record.name}:${record.port}`;\n try {\n return new URL(urlStr);\n } catch (err: unknown) {\n actionsCore.debug(\n `Record ${JSON.stringify(record)} produced an invalid URL: ${urlStr} (${err})`,\n );\n return undefined;\n }\n}\n\nasync function discoverServiceRecords(): Promise {\n return await discoverServicesStub(resolveSrv(LOOKUP), 1_000);\n}\n\nexport async function discoverServicesStub(\n lookup: Promise,\n timeout: number,\n): Promise {\n const defaultFallback: Promise = new Promise(\n (resolve, _reject) => {\n setTimeout(resolve, timeout, []);\n },\n );\n\n let records: SrvRecord[];\n\n try {\n records = await Promise.race([lookup, defaultFallback]);\n } catch (reason: unknown) {\n actionsCore.debug(`Error resolving SRV records: ${stringifyError(reason)}`);\n records = [];\n }\n\n const acceptableRecords = records.filter((record: SrvRecord): boolean => {\n for (const suffix of ALLOWED_SUFFIXES) {\n if (record.name.endsWith(suffix)) {\n return true;\n }\n }\n\n actionsCore.debug(\n `Unacceptable domain due to an invalid suffix: ${record.name}`,\n );\n\n return false;\n });\n\n if (acceptableRecords.length === 0) {\n actionsCore.debug(`No records found for ${LOOKUP}`);\n } else {\n actionsCore.debug(\n `Resolved ${LOOKUP} to ${JSON.stringify(acceptableRecords)}`,\n );\n }\n\n return acceptableRecords;\n}\n\nexport function orderRecordsByPriorityWeight(\n records: SrvRecord[],\n): SrvRecord[] {\n const byPriorityWeight: Map = new Map();\n for (const record of records) {\n const existing = byPriorityWeight.get(record.priority);\n if (existing) {\n existing.push(record);\n } else {\n byPriorityWeight.set(record.priority, [record]);\n }\n }\n\n const prioritizedRecords: SrvRecord[] = [];\n const keys: number[] = Array.from(byPriorityWeight.keys()).sort(\n (a, b) => a - b,\n );\n\n for (const priority of keys) {\n const recordsByPrio = byPriorityWeight.get(priority);\n if (recordsByPrio === undefined) {\n continue;\n }\n\n prioritizedRecords.push(...weightedRandom(recordsByPrio));\n }\n\n return prioritizedRecords;\n}\n\nexport function weightedRandom(records: SrvRecord[]): SrvRecord[] {\n // Duplicate records so we don't accidentally change our caller's data\n const scratchRecords: SrvRecord[] = records.slice();\n const result: SrvRecord[] = [];\n\n while (scratchRecords.length > 0) {\n const weights: number[] = [];\n\n {\n for (let i = 0; i < scratchRecords.length; i++) {\n weights.push(\n scratchRecords[i].weight + (i > 0 ? scratchRecords[i - 1].weight : 0),\n );\n }\n }\n\n const point = Math.random() * weights[weights.length - 1];\n\n for (\n let selectedIndex = 0;\n selectedIndex < weights.length;\n selectedIndex++\n ) {\n if (weights[selectedIndex] > point) {\n // Remove our selected record and add it to the result\n result.push(scratchRecords.splice(selectedIndex, 1)[0]);\n break;\n }\n }\n }\n\n return result;\n}\n","/**\n * @packageDocumentation\n * Helpers for getting values from an Action's configuration.\n */\nimport * as actionsCore from \"@actions/core\";\n\n/**\n * Get a Boolean input from the Action's configuration by name.\n */\nconst getBool = (name: string): boolean => {\n return actionsCore.getBooleanInput(name);\n};\n\n/**\n * Get a Boolean input from the Action's configuration by name, or undefined if it is unset.\n */\nconst getBoolOrUndefined = (name: string): boolean | undefined => {\n if (getStringOrUndefined(name) === undefined) {\n return undefined;\n }\n\n return actionsCore.getBooleanInput(name);\n};\n\n/**\n * The character used to separate values in the input string.\n */\nexport type Separator = \"space\" | \"comma\";\n\n/**\n * Convert a comma-separated string input into an array of strings. If `comma` is selected,\n * all whitespace is removed from the string before converting to an array.\n */\nconst getArrayOfStrings = (name: string, separator: Separator): string[] => {\n const original = getString(name);\n return handleString(original, separator);\n};\n\n/**\n * Convert a string input into an array of strings or `null` if no value is set.\n */\nconst getArrayOfStringsOrNull = (\n name: string,\n separator: Separator,\n): string[] | null => {\n const original = getStringOrNull(name);\n if (original === null) {\n return null;\n } else {\n return handleString(original, separator);\n }\n};\n\n// Split out this function for use in testing\nexport const handleString = (input: string, separator: Separator): string[] => {\n const sepChar = separator === \"comma\" ? \",\" : /\\s+/;\n const trimmed = input.trim(); // Remove whitespace at the beginning and end\n if (trimmed === \"\") {\n return [];\n }\n\n return trimmed.split(sepChar).map((s: string) => s.trim());\n};\n\n/**\n * Get a multi-line string input from the Action's configuration by name or return `null` if not set.\n */\nconst getMultilineStringOrNull = (name: string): string[] | null => {\n const value = actionsCore.getMultilineInput(name);\n if (value.length === 0) {\n return null;\n } else {\n return value;\n }\n};\n\n/**\n * Get a number input from the Action's configuration by name or return `null` if not set.\n */\nconst getNumberOrNull = (name: string): number | null => {\n const value = actionsCore.getInput(name);\n if (value === \"\") {\n return null;\n } else {\n return Number(value);\n }\n};\n\n/**\n * Get a string input from the Action's configuration.\n */\nconst getString = (name: string): string => {\n return actionsCore.getInput(name);\n};\n\n/**\n * Get a string input from the Action's configuration by name or return `null` if not set.\n */\nconst getStringOrNull = (name: string): string | null => {\n const value = actionsCore.getInput(name);\n if (value === \"\") {\n return null;\n } else {\n return value;\n }\n};\n\n/**\n * Get a string input from the Action's configuration by name or return `undefined` if not set.\n */\nconst getStringOrUndefined = (name: string): string | undefined => {\n const value = actionsCore.getInput(name);\n if (value === \"\") {\n return undefined;\n } else {\n return value;\n }\n};\n\nexport {\n getBool,\n getBoolOrUndefined,\n getArrayOfStrings,\n getArrayOfStringsOrNull,\n getMultilineStringOrNull,\n getNumberOrNull,\n getString,\n getStringOrNull,\n getStringOrUndefined,\n};\n","/**\n * @packageDocumentation\n * Helpers for determining system attributes of the current runner.\n */\nimport * as actionsCore from \"@actions/core\";\n\n/**\n * Get the current architecture plus OS. Examples include `X64-Linux` and `ARM64-macOS`.\n */\nexport function getArchOs(): string {\n const envArch = process.env.RUNNER_ARCH;\n const envOs = process.env.RUNNER_OS;\n\n if (envArch && envOs) {\n return `${envArch}-${envOs}`;\n } else {\n actionsCore.error(\n `Can't identify the platform: RUNNER_ARCH or RUNNER_OS undefined (${envArch}-${envOs})`,\n );\n throw new Error(\"RUNNER_ARCH and/or RUNNER_OS is not defined\");\n }\n}\n\n/**\n * Get the current Nix system. Examples include `x86_64-linux` and `aarch64-darwin`.\n */\nexport function getNixPlatform(archOs: string): string {\n const archOsMap: Map = new Map([\n [\"X64-macOS\", \"x86_64-darwin\"],\n [\"ARM64-macOS\", \"aarch64-darwin\"],\n [\"X64-Linux\", \"x86_64-linux\"],\n [\"ARM64-Linux\", \"aarch64-linux\"],\n ]);\n\n const mappedTo = archOsMap.get(archOs);\n if (mappedTo) {\n return mappedTo;\n } else {\n actionsCore.error(\n `ArchOs (${archOs}) doesn't map to a supported Nix platform.`,\n );\n throw new Error(\n `Cannot convert ArchOs (${archOs}) to a supported Nix platform.`,\n );\n }\n}\n","import { getStringOrUndefined } from \"./inputs.js\";\nimport * as actionsCore from \"@actions/core\";\n\nexport type SourceDef = {\n path?: string;\n url?: string;\n tag?: string;\n pr?: string;\n branch?: string;\n revision?: string;\n};\n\nexport function constructSourceParameters(legacyPrefix?: string): SourceDef {\n return {\n path: noisilyGetInput(\"path\", legacyPrefix),\n url: noisilyGetInput(\"url\", legacyPrefix),\n tag: noisilyGetInput(\"tag\", legacyPrefix),\n pr: noisilyGetInput(\"pr\", legacyPrefix),\n branch: noisilyGetInput(\"branch\", legacyPrefix),\n revision: noisilyGetInput(\"revision\", legacyPrefix),\n };\n}\n\nfunction noisilyGetInput(\n suffix: string,\n legacyPrefix: string | undefined,\n): string | undefined {\n const preferredInput = getStringOrUndefined(`source-${suffix}`);\n\n if (!legacyPrefix) {\n return preferredInput;\n }\n\n // Remaining is for handling cases where the legacy prefix\n // should be examined.\n const legacyInput = getStringOrUndefined(`${legacyPrefix}-${suffix}`);\n\n if (preferredInput && legacyInput) {\n actionsCore.warning(\n `The supported option source-${suffix} and the legacy option ${legacyPrefix}-${suffix} are both set. Preferring source-${suffix}. Please stop setting ${legacyPrefix}-${suffix}.`,\n );\n return preferredInput;\n } else if (legacyInput) {\n actionsCore.warning(\n `The legacy option ${legacyPrefix}-${suffix} is set. Please migrate to source-${suffix}.`,\n );\n return legacyInput;\n } else {\n return preferredInput;\n }\n}\n","/**\n * @packageDocumentation\n * Determinate Systems' TypeScript library for creating GitHub Actions logic.\n */\n// import { version as pkgVersion } from \"../package.json\";\nimport * as ghActionsCorePlatform from \"./actions-core-platform.js\";\nimport { collectBacktraces } from \"./backtrace.js\";\nimport type { CheckIn, Feature } from \"./check-in.js\";\nimport * as correlation from \"./correlation.js\";\nimport { IdsHost } from \"./ids-host.js\";\nimport { getBool, getBoolOrUndefined, getStringOrNull } from \"./inputs.js\";\nimport * as platform from \"./platform.js\";\nimport type { SourceDef } from \"./sourcedef.js\";\nimport { constructSourceParameters } from \"./sourcedef.js\";\nimport * as actionsCache from \"@actions/cache\";\nimport * as actionsCore from \"@actions/core\";\nimport * as actionsExec from \"@actions/exec\";\nimport { type Got, type Request, TimeoutError } from \"got\";\nimport { exec } from \"node:child_process\";\nimport type { UUID } from \"node:crypto\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n PathLike,\n WriteStream,\n createWriteStream,\n constants as fsConstants,\n readFileSync,\n} from \"node:fs\";\nimport fs, { chmod, copyFile, mkdir } from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport { tmpdir } from \"node:os\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { gzip } from \"node:zlib\";\n\nconst pkgVersion = \"1.0\";\n\nconst EVENT_BACKTRACES = \"backtrace\";\nconst EVENT_EXCEPTION = \"exception\";\nconst EVENT_ARTIFACT_CACHE_HIT = \"artifact_cache_hit\";\nconst EVENT_ARTIFACT_CACHE_MISS = \"artifact_cache_miss\";\nconst EVENT_ARTIFACT_CACHE_PERSIST = \"artifact_cache_persist\";\nconst EVENT_PREFLIGHT_REQUIRE_NIX_DENIED = \"preflight-require-nix-denied\";\nconst EVENT_STORE_IDENTITY_FAILED = \"store_identity_failed\";\n\nconst FACT_ARTIFACT_FETCHED_FROM_CACHE = \"artifact_fetched_from_cache\";\nconst FACT_ENDED_WITH_EXCEPTION = \"ended_with_exception\";\nconst FACT_FINAL_EXCEPTION = \"final_exception\";\nconst FACT_OS = \"$os\";\nconst FACT_OS_VERSION = \"$os_version\";\nconst FACT_SOURCE_URL = \"source_url\";\nconst FACT_SOURCE_URL_ETAG = \"source_url_etag\";\nconst FACT_NIX_VERSION = \"nix_version\";\n\nconst FACT_NIX_LOCATION = \"nix_location\";\nconst FACT_NIX_STORE_TRUST = \"nix_store_trusted\";\nconst FACT_NIX_STORE_VERSION = \"nix_store_version\";\nconst FACT_NIX_STORE_CHECK_METHOD = \"nix_store_check_method\";\nconst FACT_NIX_STORE_CHECK_ERROR = \"nix_store_check_error\";\n\nconst STATE_KEY_EXECUTION_PHASE = \"detsys_action_execution_phase\";\nconst STATE_KEY_NIX_NOT_FOUND = \"detsys_action_nix_not_found\";\nconst STATE_NOT_FOUND = \"not-found\";\nconst STATE_KEY_CROSS_PHASE_ID = \"detsys_cross_phase_id\";\nconst STATE_BACKTRACE_START_TIMESTAMP = \"detsys_backtrace_start_timestamp\";\n\nconst DIAGNOSTIC_ENDPOINT_TIMEOUT_MS = 10_000; // 10 seconds in ms\nconst CHECK_IN_ENDPOINT_TIMEOUT_MS = 1_000; // 1 second in ms\nconst PROGRAM_NAME_CRASH_DENY_LIST = [\n \"nix-expr-tests\",\n \"nix-store-tests\",\n \"nix-util-tests\",\n];\n\n/**\n * An enum for describing different \"fetch suffixes\" for i.d.s.\n *\n * - `nix-style` means that system names like `x86_64-linux` and `aarch64-darwin` are used\n * - `gh-env-style` means that names like `X64-Linux` and `ARM64-macOS` are used\n * - `universal` means that the suffix is the static `universal` (for non-system-specific things)\n */\nexport type FetchSuffixStyle = \"nix-style\" | \"gh-env-style\" | \"universal\";\n\n/**\n * GitHub Actions has two possible execution phases: `main` and `post`.\n */\nexport type ExecutionPhase = \"main\" | \"post\";\n\n/**\n * How to handle whether Nix is currently installed on the runner.\n *\n * - `fail` means that the workflow fails if Nix isn't installed\n * - `warn` means that a warning is logged if Nix isn't installed\n * - `ignore` means that Nix will not be checked\n */\nexport type NixRequirementHandling = \"fail\" | \"warn\" | \"ignore\";\n\n/**\n * Whether the Nix store on the runner is trusted.\n *\n * - `trusted` means yes\n * - `untrusted` means no\n * - `unknown` means that the status couldn't be determined\n *\n * This is determined via the output of `nix store info --json`.\n */\nexport type NixStoreTrust = \"trusted\" | \"untrusted\" | \"unknown\";\n\nexport type ActionOptions = {\n // Name of the project generally, and the name of the binary on disk.\n name: string;\n\n // Defaults to `name`, Corresponds to the ProjectHost entry on i.d.s.\n idsProjectName?: string;\n\n // Defaults to `action:`\n eventPrefix?: string;\n\n // The \"architecture\" URL component expected by I.D.S. for the ProjectHost.\n fetchStyle: FetchSuffixStyle;\n\n // IdsToolbox assumes the GitHub Action exposes source overrides, like branch/pr/etc. to be named `source-*`.\n // This prefix adds a fallback name, prefixed by `${legacySourcePrefix}-`.\n // Users who configure legacySourcePrefix will get warnings asking them to change to `source-*`.\n legacySourcePrefix?: string;\n\n // Check if Nix is installed before running this action.\n // If Nix isn't installed, this action will not fail, and will instead do nothing.\n // The action will emit a user-visible warning instructing them to install Nix.\n requireNix: NixRequirementHandling;\n\n // The URL suffix to send diagnostics events to.\n //\n // The final URL is constructed via IDS_HOST/idsProjectName/diagnosticsSuffix.\n //\n // Default: `diagnostics`.\n diagnosticsSuffix?: string;\n\n // Collect backtraces from segfaults and other failures from binaries that start with these names.\n //\n // Default: `[ \"nix\", \"determinate-nixd\", ActionOptions.name ]`.\n binaryNamePrefixes?: string[];\n\n // Do NOT collect backtraces from segfaults and other failures from binaries with exact these names.\n //\n // Default: `[ \"nix-expr-tests\" ]`.\n binaryNamesDenyList?: string[];\n};\n\n/**\n * A confident version of Options, where defaults have been resolved into final values.\n */\nexport type ConfidentActionOptions = {\n name: string;\n idsProjectName: string;\n eventPrefix: string;\n fetchStyle: FetchSuffixStyle;\n legacySourcePrefix?: string;\n requireNix: NixRequirementHandling;\n providedDiagnosticsUrl?: URL;\n binaryNamePrefixes: string[];\n binaryNamesDenyList: string[];\n};\n\n/**\n * An event to send to the diagnostic endpoint of i.d.s.\n */\nexport type DiagnosticEvent = {\n // Note: putting a Map in here won't serialize to json properly.\n // It'll just be {} on serialization.\n name: string;\n distinct_id?: string;\n uuid: UUID;\n timestamp: Date;\n\n properties: Record;\n};\n\nconst determinateStateDir = \"/var/lib/determinate\";\nconst determinateIdentityFile = path.join(determinateStateDir, \"identity.json\");\n\nconst isRoot = os.userInfo().uid === 0;\n\n/** Create the Determinate state directory by escalating via sudo */\nasync function sudoEnsureDeterminateStateDir(): Promise {\n const code = await actionsExec.exec(\"sudo\", [\n \"mkdir\",\n \"-p\",\n determinateStateDir,\n ]);\n\n if (code !== 0) {\n throw new Error(`sudo mkdir -p exit: ${code}`);\n }\n}\n\n/** Ensures the Determinate state directory exists, escalating if necessary */\nasync function ensureDeterminateStateDir(): Promise {\n if (isRoot) {\n await mkdir(determinateStateDir, { recursive: true });\n } else {\n return sudoEnsureDeterminateStateDir();\n }\n}\n\n/** Writes correlation hashes to the Determinate state directory by writing to a `sudo tee` pipe */\nasync function sudoWriteCorrelationHashes(hashes: string): Promise {\n const buffer = Buffer.from(hashes);\n\n const code = await actionsExec.exec(\n \"sudo\",\n [\"tee\", determinateIdentityFile],\n {\n input: buffer,\n\n // Ignore output from tee\n outStream: createWriteStream(\"/dev/null\"),\n },\n );\n\n if (code !== 0) {\n throw new Error(`sudo tee exit: ${code}`);\n }\n}\n\n/** Writes correlation hashes to the Determinate state directory, escalating if necessary */\nasync function writeCorrelationHashes(hashes: string): Promise {\n await ensureDeterminateStateDir();\n\n if (isRoot) {\n await fs.writeFile(determinateIdentityFile, hashes, \"utf-8\");\n } else {\n return sudoWriteCorrelationHashes(hashes);\n }\n}\n\nexport abstract class DetSysAction {\n nixStoreTrust: NixStoreTrust;\n strictMode: boolean;\n\n private actionOptions: ConfidentActionOptions;\n private exceptionAttachments: Map;\n private archOs: string;\n private executionPhase: ExecutionPhase;\n private nixSystem: string;\n private architectureFetchSuffix: string;\n private sourceParameters: SourceDef;\n private facts: Record;\n private events: DiagnosticEvent[];\n private identity: correlation.AnonymizedCorrelationHashes;\n private idsHost: IdsHost;\n private features: { [k: string]: Feature };\n private featureEventMetadata: { [k: string]: string | boolean };\n\n private determineExecutionPhase(): ExecutionPhase {\n const currentPhase = actionsCore.getState(STATE_KEY_EXECUTION_PHASE);\n if (currentPhase === \"\") {\n actionsCore.saveState(STATE_KEY_EXECUTION_PHASE, \"post\");\n return \"main\";\n } else {\n return \"post\";\n }\n }\n\n constructor(actionOptions: ActionOptions) {\n this.actionOptions = makeOptionsConfident(actionOptions);\n this.idsHost = new IdsHost(\n this.actionOptions.idsProjectName,\n actionOptions.diagnosticsSuffix,\n // Note: we don't use actionsCore.getInput('diagnostic-endpoint') on purpose:\n // getInput silently converts absent data to an empty string.\n process.env[\"INPUT_DIAGNOSTIC-ENDPOINT\"],\n );\n this.exceptionAttachments = new Map();\n this.nixStoreTrust = \"unknown\";\n this.strictMode = getBool(\"_internal-strict-mode\");\n\n if (\n getBoolOrUndefined(\n \"_internal-obliterate-actions-id-token-request-variables\",\n ) === true\n ) {\n process.env[\"ACTIONS_ID_TOKEN_REQUEST_URL\"] = undefined;\n process.env[\"ACTIONS_ID_TOKEN_REQUEST_TOKEN\"] = undefined;\n }\n\n this.features = {};\n this.featureEventMetadata = {};\n this.events = [];\n\n this.getCrossPhaseId();\n this.collectBacktraceSetup();\n\n // JSON sent to server\n /* eslint-disable camelcase */\n this.facts = {\n $lib: \"idslib\",\n $lib_version: pkgVersion,\n project: this.actionOptions.name,\n ids_project: this.actionOptions.idsProjectName,\n };\n\n const params = [\n [\"github_action_ref\", \"GITHUB_ACTION_REF\"],\n [\"github_action_repository\", \"GITHUB_ACTION_REPOSITORY\"],\n [\"github_event_name\", \"GITHUB_EVENT_NAME\"],\n [\"$os\", \"RUNNER_OS\"],\n [\"arch\", \"RUNNER_ARCH\"],\n ];\n for (const [target, env] of params) {\n const value = process.env[env];\n if (value) {\n this.facts[target] = value;\n }\n }\n\n this.identity = correlation.identify();\n this.archOs = platform.getArchOs();\n this.nixSystem = platform.getNixPlatform(this.archOs);\n\n this.facts.$app_name = `${this.actionOptions.name}/action`;\n this.facts.arch_os = this.archOs;\n this.facts.nix_system = this.nixSystem;\n\n {\n ghActionsCorePlatform\n .getDetails()\n // eslint-disable-next-line github/no-then\n .then((details) => {\n if (details.name !== \"unknown\") {\n this.addFact(FACT_OS, details.name);\n }\n if (details.version !== \"unknown\") {\n this.addFact(FACT_OS_VERSION, details.version);\n }\n })\n // eslint-disable-next-line github/no-then\n .catch((e: unknown) => {\n actionsCore.debug(\n `Failure getting platform details: ${stringifyError(e)}`,\n );\n });\n }\n\n this.executionPhase = this.determineExecutionPhase();\n this.facts.execution_phase = this.executionPhase;\n\n if (this.actionOptions.fetchStyle === \"gh-env-style\") {\n this.architectureFetchSuffix = this.archOs;\n } else if (this.actionOptions.fetchStyle === \"nix-style\") {\n this.architectureFetchSuffix = this.nixSystem;\n } else if (this.actionOptions.fetchStyle === \"universal\") {\n this.architectureFetchSuffix = \"universal\";\n } else {\n throw new Error(\n `fetchStyle ${this.actionOptions.fetchStyle} is not a valid style`,\n );\n }\n\n this.sourceParameters = constructSourceParameters(\n this.actionOptions.legacySourcePrefix,\n );\n\n this.recordEvent(`begin_${this.executionPhase}`);\n }\n\n /**\n * Attach a file to the diagnostics data in error conditions.\n *\n * The file at `location` doesn't need to exist when stapleFile is called.\n *\n * If the file doesn't exist or is unreadable when trying to staple the attachments, the JS error will be stored in a context value at `staple_failure_{name}`.\n * If the file is readable, the file's contents will be stored in a context value at `staple_value_{name}`.\n */\n stapleFile(name: string, location: string): void {\n this.exceptionAttachments.set(name, location);\n }\n\n /**\n * The main execution phase.\n */\n abstract main(): Promise;\n\n /**\n * The post execution phase.\n */\n abstract post(): Promise;\n\n /**\n * Execute the Action as defined.\n */\n execute(): void {\n // eslint-disable-next-line github/no-then\n this.executeAsync().catch((error: Error) => {\n // eslint-disable-next-line no-console\n console.log(error);\n process.exitCode = 1;\n });\n }\n\n getTemporaryName(): string {\n const tmpDir = process.env[\"RUNNER_TEMP\"] || tmpdir();\n return path.join(tmpDir, `${this.actionOptions.name}-${randomUUID()}`);\n }\n\n addFact(key: string, value: string | boolean | number): void {\n this.facts[key] = value;\n }\n\n async getDiagnosticsUrl(): Promise {\n return await this.idsHost.getDiagnosticsUrl();\n }\n\n getUniqueId(): string {\n return (\n this.identity.github_workflow_run_differentiator_hash ||\n process.env.RUNNER_TRACKING_ID ||\n randomUUID()\n );\n }\n\n // This ID will be saved in the action's state, to be persisted across phase steps\n getCrossPhaseId(): string {\n let crossPhaseId = actionsCore.getState(STATE_KEY_CROSS_PHASE_ID);\n\n if (crossPhaseId === \"\") {\n crossPhaseId = randomUUID();\n actionsCore.saveState(STATE_KEY_CROSS_PHASE_ID, crossPhaseId);\n }\n\n return crossPhaseId;\n }\n\n getCorrelationHashes(): correlation.AnonymizedCorrelationHashes {\n return this.identity;\n }\n\n recordEvent(\n eventName: string,\n context: Record = {},\n ): void {\n const prefixedName =\n eventName === \"$feature_flag_called\"\n ? eventName\n : `${this.actionOptions.eventPrefix}${eventName}`;\n\n this.events.push({\n name: prefixedName,\n\n // Use the anon distinct ID as the distinct ID until we actually have a distinct ID in the future\n distinct_id: this.identity.$anon_distinct_id,\n\n // distinct_id\n uuid: randomUUID(),\n timestamp: new Date(),\n\n properties: {\n ...context,\n ...this.identity,\n ...this.facts,\n ...Object.fromEntries(\n Object.entries(this.featureEventMetadata).map<\n [string, string | boolean]\n >(([name, variant]) => [`$feature/${name}`, variant]),\n ),\n },\n });\n }\n\n /**\n * Unpacks the closure returned by `fetchArtifact()`, imports the\n * contents into the Nix store, and returns the path of the executable at\n * `/nix/store/STORE_PATH/bin/${bin}`.\n */\n async unpackClosure(bin: string): Promise {\n const artifact = await this.fetchArtifact();\n const { stdout } = await promisify(exec)(\n `cat \"${artifact}\" | xz -d | nix-store --import`,\n );\n const paths = stdout.split(os.EOL);\n const lastPath = paths.at(-2);\n return `${lastPath}/bin/${bin}`;\n }\n\n /**\n * Fetches the executable at the URL determined by the `source-*` inputs and\n * other facts, `chmod`s it, and returns the path to the executable on disk.\n */\n async fetchExecutable(): Promise {\n const binaryPath = await this.fetchArtifact();\n await chmod(binaryPath, fsConstants.S_IXUSR | fsConstants.S_IXGRP);\n return binaryPath;\n }\n\n private get isMain(): boolean {\n return this.executionPhase === \"main\";\n }\n\n private get isPost(): boolean {\n return this.executionPhase === \"post\";\n }\n\n private async executeAsync(): Promise {\n try {\n await this.checkIn();\n\n const correlationHashes = JSON.stringify(this.getCorrelationHashes());\n process.env.DETSYS_CORRELATION = correlationHashes;\n try {\n await writeCorrelationHashes(correlationHashes);\n } catch (error) {\n this.recordEvent(EVENT_STORE_IDENTITY_FAILED, { error: String(error) });\n }\n\n if (!(await this.preflightRequireNix())) {\n this.recordEvent(EVENT_PREFLIGHT_REQUIRE_NIX_DENIED);\n return;\n } else {\n await this.preflightNixStoreInfo();\n await this.preflightNixVersion();\n this.addFact(FACT_NIX_STORE_TRUST, this.nixStoreTrust);\n }\n\n if (this.isMain) {\n await this.main();\n\n // Run the preflight of the nix version a second time so our \"shutdown\" events have updated version info.\n await this.preflightNixVersion();\n } else if (this.isPost) {\n await this.post();\n }\n this.addFact(FACT_ENDED_WITH_EXCEPTION, false);\n } catch (e: unknown) {\n this.addFact(FACT_ENDED_WITH_EXCEPTION, true);\n\n const reportable = stringifyError(e);\n\n this.addFact(FACT_FINAL_EXCEPTION, reportable);\n\n if (this.isPost) {\n actionsCore.warning(reportable);\n } else {\n actionsCore.setFailed(reportable);\n }\n\n const doGzip = promisify(gzip);\n\n const exceptionContext: Map = new Map();\n for (const [attachmentLabel, filePath] of this.exceptionAttachments) {\n try {\n const logText = readFileSync(filePath);\n const buf = await doGzip(logText);\n exceptionContext.set(\n `staple_value_${attachmentLabel}`,\n buf.toString(\"base64\"),\n );\n } catch (innerError: unknown) {\n exceptionContext.set(\n `staple_failure_${attachmentLabel}`,\n stringifyError(innerError),\n );\n }\n }\n\n this.recordEvent(EVENT_EXCEPTION, Object.fromEntries(exceptionContext));\n } finally {\n if (this.isPost) {\n await this.collectBacktraces();\n }\n\n await this.complete();\n }\n }\n\n async getClient(): Promise {\n return await this.idsHost.getGot(\n (incitingError: unknown, prevUrl: URL, nextUrl: URL) => {\n this.recordPlausibleTimeout(incitingError);\n\n this.recordEvent(\"ids-failover\", {\n previousUrl: prevUrl.toString(),\n nextUrl: nextUrl.toString(),\n });\n },\n );\n }\n\n private async checkIn(): Promise {\n const checkin = await this.requestCheckIn();\n if (checkin === undefined) {\n return;\n }\n\n this.features = checkin.options;\n for (const [key, feature] of Object.entries(this.features)) {\n this.featureEventMetadata[key] = feature.variant;\n }\n\n const impactSymbol: Map = new Map([\n [\"none\", \"⚪\"],\n [\"maintenance\", \"🛠️\"],\n [\"minor\", \"🟡\"],\n [\"major\", \"🟠\"],\n [\"critical\", \"🔴\"],\n ]);\n const defaultImpactSymbol = \"🔵\";\n\n if (checkin.status !== null) {\n const summaries: string[] = [];\n\n for (const incident of checkin.status.incidents) {\n summaries.push(\n `${impactSymbol.get(incident.impact) || defaultImpactSymbol} ${incident.status.replace(\"_\", \" \")}: ${incident.name} (${incident.shortlink})`,\n );\n }\n\n for (const maintenance of checkin.status.scheduled_maintenances) {\n summaries.push(\n `${impactSymbol.get(maintenance.impact) || defaultImpactSymbol} ${maintenance.status.replace(\"_\", \" \")}: ${maintenance.name} (${maintenance.shortlink})`,\n );\n }\n\n if (summaries.length > 0) {\n actionsCore.info(\n // Bright red, Bold, Underline\n `${\"\\u001b[0;31m\"}${\"\\u001b[1m\"}${\"\\u001b[4m\"}${checkin.status.page.name} Status`,\n );\n for (const notice of summaries) {\n actionsCore.info(notice);\n }\n actionsCore.info(`See: ${checkin.status.page.url}`);\n actionsCore.info(``);\n }\n }\n }\n\n getFeature(name: string): Feature | undefined {\n if (!this.features.hasOwnProperty(name)) {\n return undefined;\n }\n\n const result = this.features[name];\n if (result === undefined) {\n return undefined;\n }\n\n this.recordEvent(\"$feature_flag_called\", {\n $feature_flag: name,\n $feature_flag_response: result.variant,\n });\n\n return result;\n }\n\n /**\n * Check in to install.determinate.systems, to accomplish three things:\n *\n * 1. Preflight the server selected from IdsHost, to increase the chances of success.\n * 2. Fetch any incidents and maintenance events to let users know in case things are weird.\n * 3. Get feature flag data so we can gently roll out new features.\n */\n private async requestCheckIn(): Promise {\n for (\n let attemptsRemaining = 5;\n attemptsRemaining > 0;\n attemptsRemaining--\n ) {\n const checkInUrl = await this.getCheckInUrl();\n if (checkInUrl === undefined) {\n return undefined;\n }\n\n try {\n actionsCore.debug(`Preflighting via ${checkInUrl}`);\n\n const props = {\n // Use a distinct_id when we actually have one\n distinct_id: this.identity.$anon_distinct_id,\n anon_distinct_id: this.identity.$anon_distinct_id,\n groups: this.identity.$groups,\n person_properties: {\n ci: \"github\",\n\n ...this.identity,\n ...this.facts,\n },\n };\n\n return await (\n await this.getClient()\n )\n .post(checkInUrl, {\n json: props,\n timeout: {\n request: CHECK_IN_ENDPOINT_TIMEOUT_MS,\n },\n })\n .json();\n } catch (e: unknown) {\n this.recordPlausibleTimeout(e);\n actionsCore.debug(`Error checking in: ${stringifyError(e)}`);\n this.idsHost.markCurrentHostBroken();\n }\n }\n\n return undefined;\n }\n\n private recordPlausibleTimeout(e: unknown): void {\n // see: https://github.com/sindresorhus/got/blob/895e463fa699d6f2e4b2fc01ceb3b2bb9e157f4c/documentation/8-errors.md\n if (e instanceof TimeoutError && \"timings\" in e && \"request\" in e) {\n const reportContext: {\n [index: string]: string | number | undefined;\n } = {\n url: e.request.requestUrl?.toString(),\n retry_count: e.request.retryCount,\n };\n\n for (const [key, value] of Object.entries(e.timings.phases)) {\n if (Number.isFinite(value)) {\n reportContext[`timing_phase_${key}`] = value;\n }\n }\n\n this.recordEvent(\"timeout\", reportContext);\n }\n }\n\n /**\n * Fetch an artifact, such as a tarball, from the location determined by the\n * `source-*` inputs. If `source-binary` is specified, this will return a path\n * to a binary on disk; otherwise, the artifact will be downloaded from the\n * URL determined by the other `source-*` inputs (`source-url`, `source-pr`,\n * etc.).\n */\n private async fetchArtifact(): Promise {\n const sourceBinary = getStringOrNull(\"source-binary\");\n\n // If source-binary is set, use that. Otherwise fall back to the source-* parameters.\n if (sourceBinary !== null && sourceBinary !== \"\") {\n actionsCore.debug(`Using the provided source binary at ${sourceBinary}`);\n return sourceBinary;\n }\n\n actionsCore.startGroup(\n `Downloading ${this.actionOptions.name} for ${this.architectureFetchSuffix}`,\n );\n\n try {\n actionsCore.info(`Fetching from ${await this.getSourceUrl()}`);\n\n const correlatedUrl = await this.getSourceUrl();\n correlatedUrl.searchParams.set(\"ci\", \"github\");\n correlatedUrl.searchParams.set(\n \"correlation\",\n JSON.stringify(this.identity),\n );\n\n const versionCheckup = await (await this.getClient()).head(correlatedUrl);\n if (versionCheckup.headers.etag) {\n const v = versionCheckup.headers.etag;\n this.addFact(FACT_SOURCE_URL_ETAG, v);\n\n actionsCore.debug(\n `Checking the tool cache for ${await this.getSourceUrl()} at ${v}`,\n );\n const cached = await this.getCachedVersion(v);\n if (cached) {\n this.facts[FACT_ARTIFACT_FETCHED_FROM_CACHE] = true;\n actionsCore.debug(`Tool cache hit.`);\n return cached;\n }\n }\n\n this.facts[FACT_ARTIFACT_FETCHED_FROM_CACHE] = false;\n\n actionsCore.debug(\n `No match from the cache, re-fetching from the redirect: ${versionCheckup.url}`,\n );\n\n const destFile = this.getTemporaryName();\n\n const fetchStream = await this.downloadFile(\n new URL(versionCheckup.url),\n destFile,\n );\n\n if (fetchStream.response?.headers.etag) {\n const v = fetchStream.response.headers.etag;\n\n try {\n await this.saveCachedVersion(v, destFile);\n } catch (e: unknown) {\n actionsCore.debug(`Error caching the artifact: ${stringifyError(e)}`);\n }\n }\n\n return destFile;\n } catch (e: unknown) {\n this.recordPlausibleTimeout(e);\n throw e;\n } finally {\n actionsCore.endGroup();\n }\n }\n\n /**\n * A helper function for failing on error only if strict mode is enabled.\n * This is intended only for CI environments testing Actions themselves.\n */\n failOnError(msg: string): void {\n if (this.strictMode) {\n actionsCore.setFailed(`strict mode failure: ${msg}`);\n }\n }\n\n private async downloadFile(\n url: URL,\n destination: PathLike,\n ): Promise {\n const client = await this.getClient();\n\n return new Promise((resolve, reject) => {\n // Current stream handle\n let writeStream: WriteStream | undefined;\n\n // Sentinel condition in case we want to abort retrying due to FS issues\n let failed = false;\n\n const retry = (stream: Request): void => {\n if (writeStream) {\n writeStream.destroy();\n }\n\n writeStream = createWriteStream(destination, {\n encoding: \"binary\",\n mode: 0o755,\n });\n\n writeStream.once(\"error\", (error) => {\n // Set failed here since promise rejections don't impact control flow\n failed = true;\n reject(error);\n });\n\n writeStream.on(\"finish\", () => {\n if (!failed) {\n resolve(stream);\n }\n });\n\n stream.once(\"retry\", (_count, _error, createRetryStream) => {\n // Optional: check `failed' here in case you want to stop retrying\n retry(createRetryStream());\n });\n\n // Now that all the handlers have been set up we can pipe from the HTTP\n // stream to disk\n stream.pipe(writeStream);\n };\n\n // Begin the retry logic by giving it a fresh got.Request\n retry(client.stream(url));\n });\n }\n\n private async complete(): Promise {\n this.recordEvent(`complete_${this.executionPhase}`);\n await this.submitEvents();\n }\n\n private async getCheckInUrl(): Promise {\n const checkInUrl = await this.idsHost.getDynamicRootUrl();\n\n if (checkInUrl === undefined) {\n return undefined;\n }\n\n checkInUrl.pathname += \"check-in\";\n return checkInUrl;\n }\n\n private async getSourceUrl(): Promise {\n const p = this.sourceParameters;\n\n if (p.url) {\n this.addFact(FACT_SOURCE_URL, p.url);\n return new URL(p.url);\n }\n\n const fetchUrl = await this.idsHost.getRootUrl();\n fetchUrl.pathname += this.actionOptions.idsProjectName;\n\n if (p.tag) {\n fetchUrl.pathname += `/tag/${p.tag}`;\n } else if (p.pr) {\n fetchUrl.pathname += `/pr/${p.pr}`;\n } else if (p.branch) {\n fetchUrl.pathname += `/branch/${p.branch}`;\n } else if (p.revision) {\n fetchUrl.pathname += `/rev/${p.revision}`;\n } else {\n fetchUrl.pathname += `/stable`;\n }\n\n fetchUrl.pathname += `/${this.architectureFetchSuffix}`;\n\n this.addFact(FACT_SOURCE_URL, fetchUrl.toString());\n\n return fetchUrl;\n }\n\n private cacheKey(version: string): string {\n const cleanedVersion = version.replace(/[^a-zA-Z0-9-+.]/g, \"\");\n return `determinatesystem-${this.actionOptions.name}-${this.architectureFetchSuffix}-${cleanedVersion}`;\n }\n\n private async getCachedVersion(version: string): Promise {\n const startCwd = process.cwd();\n\n try {\n const tempDir = this.getTemporaryName();\n await mkdir(tempDir);\n process.chdir(tempDir);\n\n // extremely evil shit right here:\n process.env.GITHUB_WORKSPACE_BACKUP = process.env.GITHUB_WORKSPACE;\n delete process.env.GITHUB_WORKSPACE;\n\n if (\n await actionsCache.restoreCache(\n [this.actionOptions.name],\n this.cacheKey(version),\n [],\n undefined,\n true,\n )\n ) {\n this.recordEvent(EVENT_ARTIFACT_CACHE_HIT);\n return `${tempDir}/${this.actionOptions.name}`;\n }\n\n this.recordEvent(EVENT_ARTIFACT_CACHE_MISS);\n return undefined;\n } finally {\n process.env.GITHUB_WORKSPACE = process.env.GITHUB_WORKSPACE_BACKUP;\n delete process.env.GITHUB_WORKSPACE_BACKUP;\n process.chdir(startCwd);\n }\n }\n\n private async saveCachedVersion(\n version: string,\n toolPath: string,\n ): Promise {\n const startCwd = process.cwd();\n\n try {\n const tempDir = this.getTemporaryName();\n await mkdir(tempDir);\n process.chdir(tempDir);\n await copyFile(toolPath, `${tempDir}/${this.actionOptions.name}`);\n\n // extremely evil shit right here:\n process.env.GITHUB_WORKSPACE_BACKUP = process.env.GITHUB_WORKSPACE;\n delete process.env.GITHUB_WORKSPACE;\n\n await actionsCache.saveCache(\n [this.actionOptions.name],\n this.cacheKey(version),\n undefined,\n true,\n );\n this.recordEvent(EVENT_ARTIFACT_CACHE_PERSIST);\n } finally {\n process.env.GITHUB_WORKSPACE = process.env.GITHUB_WORKSPACE_BACKUP;\n delete process.env.GITHUB_WORKSPACE_BACKUP;\n process.chdir(startCwd);\n }\n }\n\n private collectBacktraceSetup(): void {\n if (!process.env.DETSYS_BACKTRACE_COLLECTOR) {\n actionsCore.exportVariable(\n \"DETSYS_BACKTRACE_COLLECTOR\",\n this.getCrossPhaseId(),\n );\n\n actionsCore.saveState(STATE_BACKTRACE_START_TIMESTAMP, Date.now());\n }\n }\n\n private async collectBacktraces(): Promise {\n try {\n if (process.env.DETSYS_BACKTRACE_COLLECTOR !== this.getCrossPhaseId()) {\n return;\n }\n\n const backtraces = await collectBacktraces(\n this.actionOptions.binaryNamePrefixes,\n this.actionOptions.binaryNamesDenyList,\n parseInt(actionsCore.getState(STATE_BACKTRACE_START_TIMESTAMP)),\n );\n actionsCore.debug(`Backtraces identified: ${backtraces.size}`);\n if (backtraces.size > 0) {\n this.recordEvent(EVENT_BACKTRACES, Object.fromEntries(backtraces));\n }\n } catch (innerError: unknown) {\n actionsCore.debug(\n `Error collecting backtraces: ${stringifyError(innerError)}`,\n );\n }\n }\n\n private async preflightRequireNix(): Promise {\n let nixLocation: string | undefined;\n\n const pathParts = (process.env[\"PATH\"] || \"\").split(\":\");\n for (const location of pathParts) {\n const candidateNix = path.join(location, \"nix\");\n\n try {\n await fs.access(candidateNix, fs.constants.X_OK);\n actionsCore.debug(`Found Nix at ${candidateNix}`);\n nixLocation = candidateNix;\n break;\n } catch {\n actionsCore.debug(`Nix not at ${candidateNix}`);\n }\n }\n this.addFact(FACT_NIX_LOCATION, nixLocation || \"\");\n\n if (this.actionOptions.requireNix === \"ignore\") {\n return true;\n }\n\n const currentNotFoundState = actionsCore.getState(STATE_KEY_NIX_NOT_FOUND);\n if (currentNotFoundState === STATE_NOT_FOUND) {\n // It was previously not found, so don't run subsequent actions\n return false;\n }\n\n if (nixLocation !== undefined) {\n return true;\n }\n actionsCore.saveState(STATE_KEY_NIX_NOT_FOUND, STATE_NOT_FOUND);\n\n switch (this.actionOptions.requireNix) {\n case \"fail\":\n actionsCore.setFailed(\n [\n \"This action can only be used when Nix is installed.\",\n \"Add `- uses: DeterminateSystems/determinate-nix-action@v3` earlier in your workflow.\",\n ].join(\" \"),\n );\n break;\n case \"warn\":\n actionsCore.warning(\n [\n \"This action is in no-op mode because Nix is not installed.\",\n \"Add `- uses: DeterminateSystems/determinate-nix-action@v3` earlier in your workflow.\",\n ].join(\" \"),\n );\n break;\n }\n\n return false;\n }\n\n private async preflightNixStoreInfo(): Promise {\n let output = \"\";\n\n const options: actionsExec.ExecOptions = {};\n options.silent = true;\n options.listeners = {\n stdout: (data) => {\n output += data.toString();\n },\n };\n\n try {\n output = \"\";\n await actionsExec.exec(\"nix\", [\"store\", \"info\", \"--json\"], options);\n this.addFact(FACT_NIX_STORE_CHECK_METHOD, \"info\");\n } catch {\n try {\n // reset output\n output = \"\";\n await actionsExec.exec(\"nix\", [\"store\", \"ping\", \"--json\"], options);\n this.addFact(FACT_NIX_STORE_CHECK_METHOD, \"ping\");\n } catch {\n this.addFact(FACT_NIX_STORE_CHECK_METHOD, \"none\");\n return;\n }\n }\n\n try {\n const parsed = JSON.parse(output);\n if (parsed.trusted === 1) {\n this.nixStoreTrust = \"trusted\";\n } else if (parsed.trusted === 0) {\n this.nixStoreTrust = \"untrusted\";\n } else if (parsed.trusted !== undefined) {\n this.addFact(\n FACT_NIX_STORE_CHECK_ERROR,\n `Mysterious trusted value: ${JSON.stringify(parsed.trusted)}`,\n );\n }\n\n this.addFact(FACT_NIX_STORE_VERSION, JSON.stringify(parsed.version));\n } catch (e: unknown) {\n this.addFact(FACT_NIX_STORE_CHECK_ERROR, stringifyError(e));\n }\n }\n\n private async preflightNixVersion(): Promise {\n let output = \"unknown\";\n\n try {\n ({ stdout: output } = await actionsExec.getExecOutput(\n \"nix\",\n [\"--version\"],\n {\n silent: true,\n },\n ));\n output = output.trim() || \"unknown\";\n } catch {\n // That's fine.\n }\n\n this.addFact(FACT_NIX_VERSION, output);\n }\n\n private async submitEvents(): Promise {\n const diagnosticsUrl = await this.idsHost.getDiagnosticsUrl();\n if (diagnosticsUrl === undefined) {\n actionsCore.debug(\n \"Diagnostics are disabled. Not sending the following events:\",\n );\n actionsCore.debug(JSON.stringify(this.events, undefined, 2));\n return;\n }\n\n const batch = {\n sent_at: new Date(),\n batch: this.events,\n };\n\n try {\n await (\n await this.getClient()\n ).post(diagnosticsUrl, {\n json: batch,\n timeout: {\n request: DIAGNOSTIC_ENDPOINT_TIMEOUT_MS,\n },\n });\n } catch (err: unknown) {\n this.recordPlausibleTimeout(err);\n\n actionsCore.debug(\n `Error submitting diagnostics event to ${diagnosticsUrl}: ${stringifyError(err)}`,\n );\n }\n this.events = [];\n }\n}\n\nfunction stringifyError(error: unknown): string {\n return error instanceof Error || typeof error == \"string\"\n ? error.toString()\n : JSON.stringify(error);\n}\n\nfunction makeOptionsConfident(\n actionOptions: ActionOptions,\n): ConfidentActionOptions {\n const idsProjectName = actionOptions.idsProjectName ?? actionOptions.name;\n\n const finalOpts: ConfidentActionOptions = {\n name: actionOptions.name,\n idsProjectName,\n eventPrefix: actionOptions.eventPrefix || \"action:\",\n fetchStyle: actionOptions.fetchStyle,\n legacySourcePrefix: actionOptions.legacySourcePrefix,\n requireNix: actionOptions.requireNix,\n binaryNamePrefixes: actionOptions.binaryNamePrefixes ?? [\n \"nix\",\n \"determinate-nixd\",\n actionOptions.name,\n ],\n binaryNamesDenyList:\n actionOptions.binaryNamePrefixes ?? PROGRAM_NAME_CRASH_DENY_LIST,\n };\n\n actionsCore.debug(\"idslib options:\");\n actionsCore.debug(JSON.stringify(finalOpts, undefined, 2));\n\n return finalOpts;\n}\n\n// Public exports from other files\nexport type {\n CheckIn,\n Feature,\n Incident,\n Maintenance,\n Page,\n StatusSummary,\n} from \"./check-in.js\";\nexport type { AnonymizedCorrelationHashes } from \"./correlation.js\";\nexport { stringifyError } from \"./errors.js\";\nexport { IdsHost } from \"./ids-host.js\";\nexport type { SourceDef } from \"./sourcedef.js\";\nexport * as inputs from \"./inputs.js\";\nexport * as platform from \"./platform.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,MAAM,gBAAgB,UAAUA,KAAG,SAAS;AAyB5C,MAAMC,kCAA2D;CAC/D,MAAM;CACN,YAAY;CACZ,OAAO;CACR;;;;;;;AAQD,SAAgB,YAAY,aAA8C;CACxE,MAAM,UAAU;EAAE,GAAG;EAAiC,GAAG;EAAa;CAEtE,MAAMC,0BAAoC,kBACxC,QAAQ,WACT;AAED,KAAIC,KAAG,MAAM,KAAK,QAChB,KAAI,QAAQ,SAAS,OACnB,QAAO,WAAW;KAElB,QAAO,QAAQ,QAAQ,WAAW,CAAC;AAIvC,KAAI,QAAQ,SAAS,OACnB,QAAO,sBAAsB,yBAAyB,QAAQ;KAE9D,QAAO,QAAQ,QACb,uBAAuB,yBAAyB,QAAQ,CACzD;;;;;;;;;AAWL,SAAS,eAAe,YAAoB,cAA8B;CACxE,MAAMC,QAAkB,aAAa,MAAM,KAAK;AAEhD,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,WAAW,KAAK,MAAM,IAAI;AAEhC,MAAI,SAAS,WAAW,GAAG;AACzB,YAAS,KAAK,SAAS,GAAG,QAAQ,YAAY,GAAG;AAEjD,UAAO,eAAe,YAAY,SAAS,GAAG,aAAa,EAAE;IAC3D,OAAO,SAAS;IAChB,UAAU;IACV,YAAY;IACZ,cAAc;IACf,CAAC;;;AAIN,QAAO;;;;;;;;AAST,SAAS,kBAAkB,YAAiD;CAC1E,MAAM,2BAA2B,CAAC,mBAAmB,sBAAsB;AAE3E,KAAI,CAAC,WACH,QAAO;KAEP,QAAO,MAAM,WAAW;;;;;;;;AAqB5B,SAAS,YAAoB;AAC3B,QAAO;EACL,MAAMD,KAAG,MAAM;EACf,UAAUA,KAAG,UAAU;EACvB,UAAUA,KAAG,UAAU;EACvB,MAAMA,KAAG,MAAM;EACf,SAASA,KAAG,SAAS;EACtB;;AAKH,eAAe,uBACb,UACA,SACiB;CACjB,IAAI,WAAW;AAEf,MAAK,MAAM,iBAAiB,SAC1B,KAAI;AACF,MAAI,QAAQ,MAEV,SAAQ,IAAI,mBAAmB,cAAc,MAAM;AAGrD,aAAW,MAAM,cAAc,eAAe,SAAS;AAEvD,MAAI,QAAQ,MACV,SAAQ,IAAI,eAAe,WAAW;AAGxC;UACO,OAAO;AACd,MAAI,QAAQ,MACV,SAAQ,MAAM,MAAM;;AAK1B,KAAI,aAAa,KACf,OAAM,IAAI,MAAM,+BAA+B;AAIjD,QAAO,eAAe,WAAW,EAAE,SAAS;;AAG9C,SAAS,sBACP,iBACA,SACQ;CACR,IAAI,WAAW;AAEf,MAAK,MAAM,iBAAiB,gBAC1B,KAAI;AACF,MAAI,QAAQ,MACV,SAAQ,IAAI,mBAAmB,cAAc,MAAM;AAGrD,aAAWH,KAAG,aAAa,eAAe,SAAS;AAEnD,MAAI,QAAQ,MACV,SAAQ,IAAI,eAAe,WAAW;AAGxC;UACO,OAAO;AACd,MAAI,QAAQ,MACV,SAAQ,MAAM,MAAM;;AAK1B,KAAI,aAAa,KACf,OAAM,IAAI,MAAM,+BAA+B;AAIjD,QAAO,eAAe,WAAW,EAAE,SAAS;;;;;;;;ACvM9C,MAAM,iBAAiB,YAAiC;CACtD,MAAM,EAAE,QAAQ,YAAY,MAAMK,OAAK,cACrC,sFACA,QACA,EACE,QAAQ,MACT,CACF;CAED,MAAM,EAAE,QAAQ,SAAS,MAAMA,OAAK,cAClC,sFACA,QACA,EACE,QAAQ,MACT,CACF;AAED,QAAO;EACL,MAAM,KAAK,MAAM;EACjB,SAAS,QAAQ,MAAM;EACxB;;;;;AAMH,MAAM,eAAe,YAAiC;CACpD,MAAM,EAAE,WAAW,MAAMA,OAAK,cAAc,WAAW,QAAW,EAChE,QAAQ,MACT,CAAC;CAEF,MAAM,UAAU,OAAO,MAAM,yBAAyB,GAAG,MAAM;AAG/D,QAAO;EACL,MAHW,OAAO,MAAM,sBAAsB,GAAG,MAAM;EAIvD;EACD;;;;;AAMH,MAAM,eAAe,YAAiC;CACpD,IAAIC,OAAe,EAAE;AAErB,KAAI;AACF,SAAO,YAAY,EAAE,MAAM,QAAQ,CAAC;AACpC,cAAY,MAAM,4BAA4B,KAAK,UAAU,KAAK,GAAG;UAC9D,GAAG;AACV,cAAY,MAAM,kCAAkC,IAAI;;AAG1D,QAAO;EACL,MAAM,0BACJ,MACA;GAAC;GAAM;GAAQ;GAAe;GAAU,EACxC,UACD;EACD,SAAS,0BACP,MACA;GAAC;GAAc;GAAW;GAAmB,EAC7C,UACD;EACF;;AAGH,SAAS,0BACP,MACA,OACA,cACG;AACH,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAMC,MAAS,uBAAuB,MAAM,MAAM,aAAa;AAE/D,MAAI,QAAQ,aACV,QAAO;;AAIX,QAAO;;AAGT,SAAS,uBACP,MACA,MACA,cACG;AACH,KAAI,CAAC,KAAK,eAAe,KAAK,CAC5B,QAAO;CAGT,MAAM,QAAS,KAAgC;AAG/C,KAAI,OAAO,UAAU,OAAO,aAC1B,QAAO;AAGT,QAAO;;;;;AAMT,MAAa,WAAW,GAAG,UAAU;;;;AAKrC,MAAa,OAAO,GAAG,MAAM;;;;AAK7B,MAAa,YAAY,aAAa;;;;AAKtC,MAAa,UAAU,aAAa;;;;AAKpC,MAAa,UAAU,aAAa;;;;AAkBpC,eAAsB,aAAqC;AACzD,QAAO;EACL,GAAI,OAAO,YACP,gBAAgB,GAChB,UACE,cAAc,GACd,cAAc;EACpB;EACA;EACA;EACA;EACA;EACD;;;;;;;;AC3KH,SAAgB,eAAe,GAAoB;AACjD,KAAI,aAAa,MACf,QAAO,EAAE;UACA,OAAO,MAAM,SACtB,QAAO;KAEP,QAAO,KAAK,UAAU,EAAE;;;;;ACI5B,MAAM,qBAAqB;AAE3B,eAAsB,kBACpB,UACA,qBACA,kBAC8B;AAC9B,KAAI,QACF,QAAO,MAAM,uBACX,UACA,qBACA,iBACD;AAEH,KAAI,QACF,QAAO,MAAM,yBACX,UACA,qBACA,iBACD;AAGH,wBAAO,IAAI,KAAK;;AAGlB,eAAsB,uBACpB,UACA,qBACA,kBAC8B;CAC9B,MAAMC,6BAAkC,IAAI,KAAK;AAEjD,KAAI;EACF,MAAM,EAAE,QAAQ,YAAY,MAAMC,OAAK,cACrC,OACA;GACE;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACD,EACD,EACE,QAAQ,MACT,CACF;EAED,MAAMC,aAAsB,KAAK,MAAM,QAAQ;AAC/C,MAAI,CAAC,MAAM,QAAQ,WAAW,CAC5B,OAAM,IAAI,MAAM,4BAA4B,UAAU;AAGxD,MAAI,WAAW,SAAS,GAAG;AACzB,eAAY,KAAK,2BAA2B;GAC5C,MAAM,QAAQ,OAAO,OACnB,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;AACnD,SAAM,MAAM,IAAK;;SAEb;AACN,cAAY,MACV,uHACD;;CAGH,MAAM,OAAO,CACX,CAAC,UAAU,mCAAmC,EAC9C,CAAC,QAAQ,GAAG,QAAQ,IAAI,QAAQ,kCAAkC,CACnE;AAED,MAAK,MAAM,CAAC,QAAQ,QAAQ,MAAM;EAChC,MAAM,aAAa,MAAM,QAAQ,IAAI,EAClC,QAAQ,aAAa;AACpB,UAAO,SAAS,MAAM,WAAW,SAAS,WAAW,OAAO,CAAC;IAC7D,CACD,QAAQ,aAAa;AACpB,UAAO,CAAC,oBAAoB,MAAM,gBAChC,SAAS,WAAW,YAAY,CACjC;IACD,CACD,QAAQ,aAAa;AAIpB,UAAO,CAAC,SAAS,SAAS,QAAQ;IAClC;EAEJ,MAAM,SAAS,UAAU,KAAK;AAC9B,OAAK,MAAM,YAAY,UACrB,KAAI;AACF,QAAK,MAAM,KAAK,GAAG,IAAI,GAAG,WAAW,EAAE,WAAW,kBAAkB;IAClE,MAAM,UAAU,MAAM,SAAS,GAAG,IAAI,GAAG,WAAW;IACpD,MAAM,MAAM,MAAM,OAAO,QAAQ;AACjC,eAAW,IACT,mBAAmB,OAAO,GAAG,YAC7B,IAAI,SAAS,SAAS,CACvB;;WAEIC,YAAqB;AAC5B,cAAW,IACT,qBAAqB,OAAO,GAAG,YAC/B,eAAe,WAAW,CAC3B;;;AAKP,QAAO;;AAQT,eAAsB,yBACpB,UACA,qBACA,kBAC8B;CAC9B,MAAM,eACJ,KAAK,MAAM,KAAK,KAAK,GAAG,oBAAoB,IAAK,GAAG;CACtD,MAAMH,6BAAkC,IAAI,KAAK;CAEjD,MAAMI,YAAmC,EAAE;AAE3C,KAAI;EACF,MAAM,EAAE,QAAQ,iBAAiB,MAAMH,OAAK,cAC1C,eACA;GAAC;GAAiB;GAAQ;GAAW,GAAG,aAAa;GAAc,EACnE,EACE,QAAQ,MACT,CACF;EAED,MAAMC,aAAsB,KAAK,MAAM,aAAa;AACpD,MAAI,CAAC,MAAM,QAAQ,WAAW,CAC5B,OAAM,IAAI,MAAM,4BAA4B,eAAe;AAG7D,OAAK,MAAM,eAAe,YAAY;GACpC,MAAM,OAAO,OAAO,KAAK,YAAY;AAErC,OAAI,KAAK,SAAS,MAAM,IAAI,KAAK,SAAS,MAAM,CAC9C,KACE,OAAO,YAAY,OAAO,YAC1B,OAAO,YAAY,OAAO,UAC1B;IACA,MAAM,YAAY,YAAY,IAAI,MAAM,IAAI;IAC5C,MAAM,aAAa,UAAU,UAAU,SAAS;AAEhD,QACE,SAAS,MAAM,WAAW,WAAW,WAAW,OAAO,CAAC,IACxD,CAAC,oBAAoB,SAAS,WAAW,CAEzC,WAAU,KAAK;KACb,KAAK,YAAY;KACjB,KAAK,YAAY;KAClB,CAAC;SAGJ,aAAY,MACV,mEAAmE,KAAK,UAAU,YAAY,GAC/F;OAGH,aAAY,MACV,iEAAiE,KAAK,UAAU,YAAY,GAC7F;;UAGEC,YAAqB;AAC5B,cAAY,MACV,8BAA8B,eAAe,WAAW,GACzD;AAED,SAAO;;CAGT,MAAM,SAAS,UAAU,KAAK;AAC9B,MAAK,MAAM,YAAY,UACrB,KAAI;EACF,MAAM,EAAE,QAAQ,YAAY,MAAMF,OAAK,cACrC,eACA,CAAC,QAAQ,GAAG,SAAS,MAAM,EAC3B,EACE,QAAQ,MACT,CACF;EAED,MAAM,MAAM,MAAM,OAAO,QAAQ;AACjC,aAAW,IAAI,mBAAmB,SAAS,OAAO,IAAI,SAAS,SAAS,CAAC;UAClEE,YAAqB;AAC5B,aAAW,IACT,qBAAqB,SAAS,OAC9B,eAAe,WAAW,CAC3B;;AAIL,QAAO;;;;;ACtNT,MAAM,qBAAqB,CAAC,gBAAgB;AAmB5C,SAAgB,WAAwC;CACtD,MAAM,aAAa,yBAAyB,OAAO;EACjD;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,qBAAqB,yBAAyB,SAAS;EAC3D;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAME,QAAqC;EACzC,mBAAmB,QAAQ,IAAI,yBAAyB,YAAY;EAEpE,oBAAoB;EAEpB,wBAAwB;EACxB,sBAAsB,yBAAyB,OAAO;GACpD;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACF,0BAA0B,yBAAyB,QAAQ;GACzD;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACF,0BAA0B,yBAAyB,SAAS;GAC1D;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACF,yCAAyC;EACzC,aAAa;EACb,SAAS;GACP,mBAAmB;GACnB,qBAAqB,yBAAyB,OAAO;IACnD;IACA;IACA;IACD,CAAC;GACH;EACD,OAAO;EACR;AAED,aAAY,MAAM,oBAAoB;AACtC,aAAY,MAAM,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAEjD,QAAO;;AAGT,SAAS,yBACP,QACA,WACoB;CACpB,MAAM,OAAO,WAAW,SAAS;AAEjC,MAAK,MAAM,WAAW,WAAW;EAC/B,IAAI,QAAQ,QAAQ,IAAI;AAExB,MAAI,UAAU,OACZ,KAAI,mBAAmB,SAAS,QAAQ,EAAE;AACxC,eAAY,MACV,0CAA0C,QAAQ,yCACnD;AACD,WAAQ;SACH;AACL,eAAY,MACV,iCAAiC,QAAQ,2CAC1C;AACD;;AAIJ,OAAK,OAAO,MAAM;AAClB,OAAK,OAAO,KAAK;;AAGnB,QAAO,GAAG,OAAO,GAAG,KAAK,OAAO,MAAM;;;;;AClHxC,MAAM,iBAAiB;AACvB,MAAM,mBAAmB,CACvB,gCACA,sBACD;AAED,MAAM,mBAAmB;AACzB,MAAM,SAAS,QAAQ,IAAI,iBAAiB;AAE5C,MAAM,kBAAkB;;;;AAKxB,IAAa,UAAb,MAAqB;CAOnB,YACE,gBACA,mBACA,uBACA;AACA,OAAK,iBAAiB;AACtB,OAAK,oBAAoB;AACzB,OAAK,wBAAwB;AAC7B,OAAK,SAAS;;CAGhB,MAAM,OACJ,wBAKc;AACd,MAAI,KAAK,WAAW,OAClB,MAAK,SAAS,IAAI,OAAO;GACvB,SAAS,EACP,SAAS,iBACV;GAED,OAAO;IACL,OAAO,KAAK,KAAK,MAAM,KAAK,qBAAqB,EAAE,QAAQ,EAAE;IAC7D,SAAS,CAAC,OAAO,OAAO;IACzB;GAED,OAAO;IACL,aAAa,CACX,OAAO,OAAO,eAAe;KAC3B,MAAM,UAAU,MAAM,KAAK,YAAY;AACvC,UAAK,uBAAuB;KAC5B,MAAM,UAAU,MAAM,KAAK,YAAY;AAEvC,SAAI,2BAA2B,OAC7B,wBAAuB,OAAO,SAAS,QAAQ;AAGjD,iBAAY,KACV,wBAAwB,MAAM,KAAK,aAAa,aACjD;MAEJ;IAED,eAAe,CACb,OAAO,YAAY;KAEjB,MAAMC,aAAkB,QAAQ;AAEhC,SAAI,KAAK,0BAA0B,WAAW,EAAE;MAC9C,MAAMC,SAAc,IAAI,IAAI,WAAW;AAGvC,aAAO,QADU,MAAM,KAAK,YAAY,EACtB;AAElB,cAAQ,MAAM;AACd,kBAAY,MAAM,cAAc,WAAW,QAAQ,SAAS;WAE5D,aAAY,MAAM,wBAAwB,aAAa;MAG5D;IACF;GACF,CAAC;AAGJ,SAAO,KAAK;;CAGd,wBAA8B;AAC5B,OAAK,iBAAiB,OAAO;;CAG/B,mBAAmB,MAAmB;AACpC,OAAK,kBAAkB;;CAGzB,0BAA0B,KAAmB;AAC3C,MAAI,IAAI,WAAW,iBACjB,QAAO;AAGT,OAAK,MAAM,UAAU,iBACnB,KAAI,IAAI,KAAK,SAAS,OAAO,CAC3B,QAAO;AAIX,SAAO;;CAGT,MAAM,oBAA8C;EAClD,MAAM,UAAU,QAAQ,IAAI;AAC5B,MAAI,YAAY,OACd,KAAI;AACF,UAAO,IAAI,IAAI,QAAQ;WAChBC,KAAc;AACrB,eAAY,MACV,+DAA+D,eAAe,IAAI,GACnF;;EAIL,IAAIC,MAAuB;AAC3B,MAAI;AAEF,UADa,MAAM,KAAK,qBAAqB,EAClC;WACJD,KAAc;AACrB,eAAY,MACV,4CAA4C,eAAe,IAAI,GAChE;;AAGH,MAAI,QAAQ,OACV;MAIA,QAAO,IAAI,IAAI,IAAI;;CAIvB,MAAM,aAA2B;EAC/B,MAAM,MAAM,MAAM,KAAK,mBAAmB;AAE1C,MAAI,QAAQ,OACV,QAAO,IAAI,IAAI,iBAAiB;AAGlC,SAAO;;CAGT,MAAM,oBAA8C;AAClD,MAAI,KAAK,0BAA0B,GAGjC;AAGF,MACE,KAAK,0BAA0B,OAC/B,KAAK,0BAA0B,OAE/B,KAAI;AAEF,UAAO,IAAI,IAAI,KAAK,sBAAsB;WACnCA,KAAc;AACrB,eAAY,KACV,+DAA+D,eAAe,IAAI,GACnF;;AAIL,MAAI;GACF,MAAM,gBAAgB,MAAM,KAAK,YAAY;AAC7C,iBAAc,YAAY;AAC1B,UAAO;WACAA,KAAc;AACrB,eAAY,KACV,yFAAyF,eAAe,IAAI,GAC7G;AACD;;;CAIJ,MAAc,sBAAsC;AAClD,MAAI,KAAK,oBAAoB,OAC3B,MAAK,kBAAkB,6BACrB,MAAM,wBAAwB,CAC/B,CAAC,SAAS,WAAW,YAAY,OAAO,IAAI,EAAE,CAAC;AAGlD,SAAO,KAAK;;;AAIhB,SAAgB,YAAY,QAAoC;CAC9D,MAAM,SAAS,WAAW,OAAO,KAAK,GAAG,OAAO;AAChD,KAAI;AACF,SAAO,IAAI,IAAI,OAAO;UACfA,KAAc;AACrB,cAAY,MACV,UAAU,KAAK,UAAU,OAAO,CAAC,4BAA4B,OAAO,IAAI,IAAI,GAC7E;AACD;;;AAIJ,eAAe,yBAA+C;AAC5D,QAAO,MAAM,qBAAqB,WAAW,OAAO,EAAE,IAAM;;AAG9D,eAAsB,qBACpB,QACA,SACsB;CACtB,MAAME,kBAAwC,IAAI,SAC/C,SAAS,YAAY;AACpB,aAAW,SAAS,SAAS,EAAE,CAAC;GAEnC;CAED,IAAIC;AAEJ,KAAI;AACF,YAAU,MAAM,QAAQ,KAAK,CAAC,QAAQ,gBAAgB,CAAC;UAChDC,QAAiB;AACxB,cAAY,MAAM,gCAAgC,eAAe,OAAO,GAAG;AAC3E,YAAU,EAAE;;CAGd,MAAM,oBAAoB,QAAQ,QAAQ,WAA+B;AACvE,OAAK,MAAM,UAAU,iBACnB,KAAI,OAAO,KAAK,SAAS,OAAO,CAC9B,QAAO;AAIX,cAAY,MACV,iDAAiD,OAAO,OACzD;AAED,SAAO;GACP;AAEF,KAAI,kBAAkB,WAAW,EAC/B,aAAY,MAAM,wBAAwB,SAAS;KAEnD,aAAY,MACV,YAAY,OAAO,MAAM,KAAK,UAAU,kBAAkB,GAC3D;AAGH,QAAO;;AAGT,SAAgB,6BACd,SACa;CACb,MAAMC,mCAA6C,IAAI,KAAK;AAC5D,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,WAAW,iBAAiB,IAAI,OAAO,SAAS;AACtD,MAAI,SACF,UAAS,KAAK,OAAO;MAErB,kBAAiB,IAAI,OAAO,UAAU,CAAC,OAAO,CAAC;;CAInD,MAAMC,qBAAkC,EAAE;CAC1C,MAAMC,OAAiB,MAAM,KAAK,iBAAiB,MAAM,CAAC,CAAC,MACxD,GAAG,MAAM,IAAI,EACf;AAED,MAAK,MAAM,YAAY,MAAM;EAC3B,MAAM,gBAAgB,iBAAiB,IAAI,SAAS;AACpD,MAAI,kBAAkB,OACpB;AAGF,qBAAmB,KAAK,GAAG,eAAe,cAAc,CAAC;;AAG3D,QAAO;;AAGT,SAAgB,eAAe,SAAmC;CAEhE,MAAMC,iBAA8B,QAAQ,OAAO;CACnD,MAAMC,SAAsB,EAAE;AAE9B,QAAO,eAAe,SAAS,GAAG;EAChC,MAAMC,UAAoB,EAAE;AAG1B,OAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,IACzC,SAAQ,KACN,eAAe,GAAG,UAAU,IAAI,IAAI,eAAe,IAAI,GAAG,SAAS,GACpE;EAIL,MAAM,QAAQ,KAAK,QAAQ,GAAG,QAAQ,QAAQ,SAAS;AAEvD,OACE,IAAI,gBAAgB,GACpB,gBAAgB,QAAQ,QACxB,gBAEA,KAAI,QAAQ,iBAAiB,OAAO;AAElC,UAAO,KAAK,eAAe,OAAO,eAAe,EAAE,CAAC,GAAG;AACvD;;;AAKN,QAAO;;;;;;;;;;;;;;;;;;;;ACjUT,MAAM,WAAW,SAA0B;AACzC,QAAO,YAAY,gBAAgB,KAAK;;;;;AAM1C,MAAM,sBAAsB,SAAsC;AAChE,KAAI,qBAAqB,KAAK,KAAK,OACjC;AAGF,QAAO,YAAY,gBAAgB,KAAK;;;;;;AAY1C,MAAM,qBAAqB,MAAc,cAAmC;CAC1E,MAAM,WAAW,UAAU,KAAK;AAChC,QAAO,aAAa,UAAU,UAAU;;;;;AAM1C,MAAM,2BACJ,MACA,cACoB;CACpB,MAAM,WAAW,gBAAgB,KAAK;AACtC,KAAI,aAAa,KACf,QAAO;KAEP,QAAO,aAAa,UAAU,UAAU;;AAK5C,MAAa,gBAAgB,OAAe,cAAmC;CAC7E,MAAM,UAAU,cAAc,UAAU,MAAM;CAC9C,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,YAAY,GACd,QAAO,EAAE;AAGX,QAAO,QAAQ,MAAM,QAAQ,CAAC,KAAK,MAAc,EAAE,MAAM,CAAC;;;;;AAM5D,MAAM,4BAA4B,SAAkC;CAClE,MAAM,QAAQ,YAAY,kBAAkB,KAAK;AACjD,KAAI,MAAM,WAAW,EACnB,QAAO;KAEP,QAAO;;;;;AAOX,MAAM,mBAAmB,SAAgC;CACvD,MAAM,QAAQ,YAAY,SAAS,KAAK;AACxC,KAAI,UAAU,GACZ,QAAO;KAEP,QAAO,OAAO,MAAM;;;;;AAOxB,MAAM,aAAa,SAAyB;AAC1C,QAAO,YAAY,SAAS,KAAK;;;;;AAMnC,MAAM,mBAAmB,SAAgC;CACvD,MAAM,QAAQ,YAAY,SAAS,KAAK;AACxC,KAAI,UAAU,GACZ,QAAO;KAEP,QAAO;;;;;AAOX,MAAM,wBAAwB,SAAqC;CACjE,MAAM,QAAQ,YAAY,SAAS,KAAK;AACxC,KAAI,UAAU,GACZ;KAEA,QAAO;;;;;;;;;;;;AC1GX,SAAgB,YAAoB;CAClC,MAAM,UAAU,QAAQ,IAAI;CAC5B,MAAM,QAAQ,QAAQ,IAAI;AAE1B,KAAI,WAAW,MACb,QAAO,GAAG,QAAQ,GAAG;MAChB;AACL,cAAY,MACV,oEAAoE,QAAQ,GAAG,MAAM,GACtF;AACD,QAAM,IAAI,MAAM,8CAA8C;;;;;;AAOlE,SAAgB,eAAe,QAAwB;CAQrD,MAAM,WAPiC,IAAI,IAAI;EAC7C,CAAC,aAAa,gBAAgB;EAC9B,CAAC,eAAe,iBAAiB;EACjC,CAAC,aAAa,eAAe;EAC7B,CAAC,eAAe,gBAAgB;EACjC,CAAC,CAEyB,IAAI,OAAO;AACtC,KAAI,SACF,QAAO;MACF;AACL,cAAY,MACV,WAAW,OAAO,4CACnB;AACD,QAAM,IAAI,MACR,0BAA0B,OAAO,gCAClC;;;;;;AC/BL,SAAgB,0BAA0B,cAAkC;AAC1E,QAAO;EACL,MAAM,gBAAgB,QAAQ,aAAa;EAC3C,KAAK,gBAAgB,OAAO,aAAa;EACzC,KAAK,gBAAgB,OAAO,aAAa;EACzC,IAAI,gBAAgB,MAAM,aAAa;EACvC,QAAQ,gBAAgB,UAAU,aAAa;EAC/C,UAAU,gBAAgB,YAAY,aAAa;EACpD;;AAGH,SAAS,gBACP,QACA,cACoB;CACpB,MAAM,iBAAiB,qBAAqB,UAAU,SAAS;AAE/D,KAAI,CAAC,aACH,QAAO;CAKT,MAAM,cAAc,qBAAqB,GAAG,aAAa,GAAG,SAAS;AAErE,KAAI,kBAAkB,aAAa;AACjC,cAAY,QACV,+BAA+B,OAAO,yBAAyB,aAAa,GAAG,OAAO,mCAAmC,OAAO,wBAAwB,aAAa,GAAG,OAAO,GAChL;AACD,SAAO;YACE,aAAa;AACtB,cAAY,QACV,qBAAqB,aAAa,GAAG,OAAO,oCAAoC,OAAO,GACxF;AACD,SAAO;OAEP,QAAO;;;;;ACbX,MAAM,aAAa;AAEnB,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,2BAA2B;AACjC,MAAM,4BAA4B;AAClC,MAAM,+BAA+B;AACrC,MAAM,qCAAqC;AAC3C,MAAM,8BAA8B;AAEpC,MAAM,mCAAmC;AACzC,MAAM,4BAA4B;AAClC,MAAM,uBAAuB;AAC7B,MAAM,UAAU;AAChB,MAAM,kBAAkB;AACxB,MAAM,kBAAkB;AACxB,MAAM,uBAAuB;AAC7B,MAAM,mBAAmB;AAEzB,MAAM,oBAAoB;AAC1B,MAAM,uBAAuB;AAC7B,MAAM,yBAAyB;AAC/B,MAAM,8BAA8B;AACpC,MAAM,6BAA6B;AAEnC,MAAM,4BAA4B;AAClC,MAAM,0BAA0B;AAChC,MAAM,kBAAkB;AACxB,MAAM,2BAA2B;AACjC,MAAM,kCAAkC;AAExC,MAAM,iCAAiC;AACvC,MAAM,+BAA+B;AACrC,MAAM,+BAA+B;CACnC;CACA;CACA;CACD;AA0GD,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B,KAAK,KAAK,qBAAqB,gBAAgB;AAE/E,MAAM,SAASC,KAAG,UAAU,CAAC,QAAQ;;AAGrC,eAAe,gCAA+C;CAC5D,MAAM,OAAO,MAAMC,OAAY,KAAK,QAAQ;EAC1C;EACA;EACA;EACD,CAAC;AAEF,KAAI,SAAS,EACX,OAAM,IAAI,MAAM,uBAAuB,OAAO;;;AAKlD,eAAe,4BAA2C;AACxD,KAAI,OACF,OAAM,MAAM,qBAAqB,EAAE,WAAW,MAAM,CAAC;KAErD,QAAO,+BAA+B;;;AAK1C,eAAe,2BAA2B,QAA+B;CACvE,MAAM,SAAS,OAAO,KAAK,OAAO;CAElC,MAAM,OAAO,MAAMA,OAAY,KAC7B,QACA,CAAC,OAAO,wBAAwB,EAChC;EACE,OAAO;EAGP,WAAW,kBAAkB,YAAY;EAC1C,CACF;AAED,KAAI,SAAS,EACX,OAAM,IAAI,MAAM,kBAAkB,OAAO;;;AAK7C,eAAe,uBAAuB,QAA+B;AACnE,OAAM,2BAA2B;AAEjC,KAAI,OACF,OAAM,GAAG,UAAU,yBAAyB,QAAQ,QAAQ;KAE5D,QAAO,2BAA2B,OAAO;;AAI7C,IAAsB,eAAtB,MAAmC;CAkBjC,AAAQ,0BAA0C;AAEhD,MADqB,YAAY,SAAS,0BAA0B,KAC/C,IAAI;AACvB,eAAY,UAAU,2BAA2B,OAAO;AACxD,UAAO;QAEP,QAAO;;CAIX,YAAY,eAA8B;AACxC,OAAK,gBAAgB,qBAAqB,cAAc;AACxD,OAAK,UAAU,IAAI,QACjB,KAAK,cAAc,gBACnB,cAAc,mBAGd,QAAQ,IAAI,6BACb;AACD,OAAK,uCAAuB,IAAI,KAAK;AACrC,OAAK,gBAAgB;AACrB,OAAK,aAAa,QAAQ,wBAAwB;AAElD,MACE,mBACE,0DACD,KAAK,MACN;AACA,WAAQ,IAAI,kCAAkC;AAC9C,WAAQ,IAAI,oCAAoC;;AAGlD,OAAK,WAAW,EAAE;AAClB,OAAK,uBAAuB,EAAE;AAC9B,OAAK,SAAS,EAAE;AAEhB,OAAK,iBAAiB;AACtB,OAAK,uBAAuB;AAI5B,OAAK,QAAQ;GACX,MAAM;GACN,cAAc;GACd,SAAS,KAAK,cAAc;GAC5B,aAAa,KAAK,cAAc;GACjC;EAED,MAAM,SAAS;GACb,CAAC,qBAAqB,oBAAoB;GAC1C,CAAC,4BAA4B,2BAA2B;GACxD,CAAC,qBAAqB,oBAAoB;GAC1C,CAAC,OAAO,YAAY;GACpB,CAAC,QAAQ,cAAc;GACxB;AACD,OAAK,MAAM,CAAC,QAAQ,QAAQ,QAAQ;GAClC,MAAM,QAAQ,QAAQ,IAAI;AAC1B,OAAI,MACF,MAAK,MAAM,UAAU;;AAIzB,OAAK,WAAWC,UAAsB;AACtC,OAAK,SAASC,WAAoB;AAClC,OAAK,YAAYC,eAAwB,KAAK,OAAO;AAErD,OAAK,MAAM,YAAY,GAAG,KAAK,cAAc,KAAK;AAClD,OAAK,MAAM,UAAU,KAAK;AAC1B,OAAK,MAAM,aAAa,KAAK;AAG3B,cACe,CAEZ,MAAM,YAAY;AACjB,OAAI,QAAQ,SAAS,UACnB,MAAK,QAAQ,SAAS,QAAQ,KAAK;AAErC,OAAI,QAAQ,YAAY,UACtB,MAAK,QAAQ,iBAAiB,QAAQ,QAAQ;IAEhD,CAED,OAAO,MAAe;AACrB,eAAY,MACV,qCAAqCC,iBAAe,EAAE,GACvD;IACD;AAGN,OAAK,iBAAiB,KAAK,yBAAyB;AACpD,OAAK,MAAM,kBAAkB,KAAK;AAElC,MAAI,KAAK,cAAc,eAAe,eACpC,MAAK,0BAA0B,KAAK;WAC3B,KAAK,cAAc,eAAe,YAC3C,MAAK,0BAA0B,KAAK;WAC3B,KAAK,cAAc,eAAe,YAC3C,MAAK,0BAA0B;MAE/B,OAAM,IAAI,MACR,cAAc,KAAK,cAAc,WAAW,uBAC7C;AAGH,OAAK,mBAAmB,0BACtB,KAAK,cAAc,mBACpB;AAED,OAAK,YAAY,SAAS,KAAK,iBAAiB;;;;;;;;;;CAWlD,WAAW,MAAc,UAAwB;AAC/C,OAAK,qBAAqB,IAAI,MAAM,SAAS;;;;;CAgB/C,UAAgB;AAEd,OAAK,cAAc,CAAC,OAAO,UAAiB;AAE1C,WAAQ,IAAI,MAAM;AAClB,WAAQ,WAAW;IACnB;;CAGJ,mBAA2B;EACzB,MAAM,SAAS,QAAQ,IAAI,kBAAkB,QAAQ;AACrD,SAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,cAAc,KAAK,GAAG,YAAY,GAAG;;CAGxE,QAAQ,KAAa,OAAwC;AAC3D,OAAK,MAAM,OAAO;;CAGpB,MAAM,oBAA8C;AAClD,SAAO,MAAM,KAAK,QAAQ,mBAAmB;;CAG/C,cAAsB;AACpB,SACE,KAAK,SAAS,2CACd,QAAQ,IAAI,sBACZ,YAAY;;CAKhB,kBAA0B;EACxB,IAAI,eAAe,YAAY,SAAS,yBAAyB;AAEjE,MAAI,iBAAiB,IAAI;AACvB,kBAAe,YAAY;AAC3B,eAAY,UAAU,0BAA0B,aAAa;;AAG/D,SAAO;;CAGT,uBAAgE;AAC9D,SAAO,KAAK;;CAGd,YACE,WACA,UAAiE,EAAE,EAC7D;EACN,MAAM,eACJ,cAAc,yBACV,YACA,GAAG,KAAK,cAAc,cAAc;AAE1C,OAAK,OAAO,KAAK;GACf,MAAM;GAGN,aAAa,KAAK,SAAS;GAG3B,MAAM,YAAY;GAClB,2BAAW,IAAI,MAAM;GAErB,YAAY;IACV,GAAG;IACH,GAAG,KAAK;IACR,GAAG,KAAK;IACR,GAAG,OAAO,YACR,OAAO,QAAQ,KAAK,qBAAqB,CAAC,KAEvC,CAAC,MAAM,aAAa,CAAC,YAAY,QAAQ,QAAQ,CAAC,CACtD;IACF;GACF,CAAC;;;;;;;CAQJ,MAAM,cAAc,KAA8B;EAChD,MAAM,WAAW,MAAM,KAAK,eAAe;EAC3C,MAAM,EAAE,WAAW,MAAM,UAAU,KAAK,CACtC,QAAQ,SAAS,gCAClB;AAGD,SAAO,GAFO,OAAO,MAAML,KAAG,IAAI,CACX,GAAG,GAAG,CACV,OAAO;;;;;;CAO5B,MAAM,kBAAmC;EACvC,MAAM,aAAa,MAAM,KAAK,eAAe;AAC7C,QAAM,MAAM,YAAYM,UAAY,UAAUA,UAAY,QAAQ;AAClE,SAAO;;CAGT,IAAY,SAAkB;AAC5B,SAAO,KAAK,mBAAmB;;CAGjC,IAAY,SAAkB;AAC5B,SAAO,KAAK,mBAAmB;;CAGjC,MAAc,eAA8B;AAC1C,MAAI;AACF,SAAM,KAAK,SAAS;GAEpB,MAAM,oBAAoB,KAAK,UAAU,KAAK,sBAAsB,CAAC;AACrE,WAAQ,IAAI,qBAAqB;AACjC,OAAI;AACF,UAAM,uBAAuB,kBAAkB;YACxC,OAAO;AACd,SAAK,YAAY,6BAA6B,EAAE,OAAO,OAAO,MAAM,EAAE,CAAC;;AAGzE,OAAI,CAAE,MAAM,KAAK,qBAAqB,EAAG;AACvC,SAAK,YAAY,mCAAmC;AACpD;UACK;AACL,UAAM,KAAK,uBAAuB;AAClC,UAAM,KAAK,qBAAqB;AAChC,SAAK,QAAQ,sBAAsB,KAAK,cAAc;;AAGxD,OAAI,KAAK,QAAQ;AACf,UAAM,KAAK,MAAM;AAGjB,UAAM,KAAK,qBAAqB;cACvB,KAAK,OACd,OAAM,KAAK,MAAM;AAEnB,QAAK,QAAQ,2BAA2B,MAAM;WACvCC,GAAY;AACnB,QAAK,QAAQ,2BAA2B,KAAK;GAE7C,MAAM,aAAaF,iBAAe,EAAE;AAEpC,QAAK,QAAQ,sBAAsB,WAAW;AAE9C,OAAI,KAAK,OACP,aAAY,QAAQ,WAAW;OAE/B,aAAY,UAAU,WAAW;GAGnC,MAAM,SAAS,UAAU,KAAK;GAE9B,MAAMG,mCAAwC,IAAI,KAAK;AACvD,QAAK,MAAM,CAAC,iBAAiB,aAAa,KAAK,qBAC7C,KAAI;IACF,MAAM,UAAU,aAAa,SAAS;IACtC,MAAM,MAAM,MAAM,OAAO,QAAQ;AACjC,qBAAiB,IACf,gBAAgB,mBAChB,IAAI,SAAS,SAAS,CACvB;YACMC,YAAqB;AAC5B,qBAAiB,IACf,kBAAkB,mBAClBJ,iBAAe,WAAW,CAC3B;;AAIL,QAAK,YAAY,iBAAiB,OAAO,YAAY,iBAAiB,CAAC;YAC/D;AACR,OAAI,KAAK,OACP,OAAM,KAAK,mBAAmB;AAGhC,SAAM,KAAK,UAAU;;;CAIzB,MAAM,YAA0B;AAC9B,SAAO,MAAM,KAAK,QAAQ,QACvB,eAAwB,SAAc,YAAiB;AACtD,QAAK,uBAAuB,cAAc;AAE1C,QAAK,YAAY,gBAAgB;IAC/B,aAAa,QAAQ,UAAU;IAC/B,SAAS,QAAQ,UAAU;IAC5B,CAAC;IAEL;;CAGH,MAAc,UAAyB;EACrC,MAAM,UAAU,MAAM,KAAK,gBAAgB;AAC3C,MAAI,YAAY,OACd;AAGF,OAAK,WAAW,QAAQ;AACxB,OAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,KAAK,SAAS,CACxD,MAAK,qBAAqB,OAAO,QAAQ;EAG3C,MAAMK,eAAoC,IAAI,IAAI;GAChD,CAAC,QAAQ,IAAI;GACb,CAAC,eAAe,MAAM;GACtB,CAAC,SAAS,KAAK;GACf,CAAC,SAAS,KAAK;GACf,CAAC,YAAY,KAAK;GACnB,CAAC;EACF,MAAM,sBAAsB;AAE5B,MAAI,QAAQ,WAAW,MAAM;GAC3B,MAAMC,YAAsB,EAAE;AAE9B,QAAK,MAAM,YAAY,QAAQ,OAAO,UACpC,WAAU,KACR,GAAG,aAAa,IAAI,SAAS,OAAO,IAAI,oBAAoB,GAAG,SAAS,OAAO,QAAQ,KAAK,IAAI,CAAC,IAAI,SAAS,KAAK,IAAI,SAAS,UAAU,GAC3I;AAGH,QAAK,MAAM,eAAe,QAAQ,OAAO,uBACvC,WAAU,KACR,GAAG,aAAa,IAAI,YAAY,OAAO,IAAI,oBAAoB,GAAG,YAAY,OAAO,QAAQ,KAAK,IAAI,CAAC,IAAI,YAAY,KAAK,IAAI,YAAY,UAAU,GACvJ;AAGH,OAAI,UAAU,SAAS,GAAG;AACxB,gBAAY,KAEV,kBAAgD,QAAQ,OAAO,KAAK,KAAK,SAC1E;AACD,SAAK,MAAM,UAAU,UACnB,aAAY,KAAK,OAAO;AAE1B,gBAAY,KAAK,QAAQ,QAAQ,OAAO,KAAK,MAAM;AACnD,gBAAY,KAAK,GAAG;;;;CAK1B,WAAW,MAAmC;AAC5C,MAAI,CAAC,KAAK,SAAS,eAAe,KAAK,CACrC;EAGF,MAAM,SAAS,KAAK,SAAS;AAC7B,MAAI,WAAW,OACb;AAGF,OAAK,YAAY,wBAAwB;GACvC,eAAe;GACf,wBAAwB,OAAO;GAChC,CAAC;AAEF,SAAO;;;;;;;;;CAUT,MAAc,iBAA+C;AAC3D,OACE,IAAI,oBAAoB,GACxB,oBAAoB,GACpB,qBACA;GACA,MAAM,aAAa,MAAM,KAAK,eAAe;AAC7C,OAAI,eAAe,OACjB;AAGF,OAAI;AACF,gBAAY,MAAM,oBAAoB,aAAa;IAEnD,MAAM,QAAQ;KAEZ,aAAa,KAAK,SAAS;KAC3B,kBAAkB,KAAK,SAAS;KAChC,QAAQ,KAAK,SAAS;KACtB,mBAAmB;MACjB,IAAI;MAEJ,GAAG,KAAK;MACR,GAAG,KAAK;MACT;KACF;AAED,WAAO,OACL,MAAM,KAAK,WAAW,EAErB,KAAK,YAAY;KAChB,MAAM;KACN,SAAS,EACP,SAAS,8BACV;KACF,CAAC,CACD,MAAM;YACFJ,GAAY;AACnB,SAAK,uBAAuB,EAAE;AAC9B,gBAAY,MAAM,sBAAsBF,iBAAe,EAAE,GAAG;AAC5D,SAAK,QAAQ,uBAAuB;;;;CAO1C,AAAQ,uBAAuB,GAAkB;AAE/C,MAAI,aAAa,gBAAgB,aAAa,KAAK,aAAa,GAAG;GACjE,MAAMO,gBAEF;IACF,KAAK,EAAE,QAAQ,YAAY,UAAU;IACrC,aAAa,EAAE,QAAQ;IACxB;AAED,QAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,EAAE,QAAQ,OAAO,CACzD,KAAI,OAAO,SAAS,MAAM,CACxB,eAAc,gBAAgB,SAAS;AAI3C,QAAK,YAAY,WAAW,cAAc;;;;;;;;;;CAW9C,MAAc,gBAAiC;EAC7C,MAAM,eAAe,gBAAgB,gBAAgB;AAGrD,MAAI,iBAAiB,QAAQ,iBAAiB,IAAI;AAChD,eAAY,MAAM,uCAAuC,eAAe;AACxE,UAAO;;AAGT,cAAY,WACV,eAAe,KAAK,cAAc,KAAK,OAAO,KAAK,0BACpD;AAED,MAAI;AACF,eAAY,KAAK,iBAAiB,MAAM,KAAK,cAAc,GAAG;GAE9D,MAAM,gBAAgB,MAAM,KAAK,cAAc;AAC/C,iBAAc,aAAa,IAAI,MAAM,SAAS;AAC9C,iBAAc,aAAa,IACzB,eACA,KAAK,UAAU,KAAK,SAAS,CAC9B;GAED,MAAM,iBAAiB,OAAO,MAAM,KAAK,WAAW,EAAE,KAAK,cAAc;AACzE,OAAI,eAAe,QAAQ,MAAM;IAC/B,MAAM,IAAI,eAAe,QAAQ;AACjC,SAAK,QAAQ,sBAAsB,EAAE;AAErC,gBAAY,MACV,+BAA+B,MAAM,KAAK,cAAc,CAAC,MAAM,IAChE;IACD,MAAM,SAAS,MAAM,KAAK,iBAAiB,EAAE;AAC7C,QAAI,QAAQ;AACV,UAAK,MAAM,oCAAoC;AAC/C,iBAAY,MAAM,kBAAkB;AACpC,YAAO;;;AAIX,QAAK,MAAM,oCAAoC;AAE/C,eAAY,MACV,2DAA2D,eAAe,MAC3E;GAED,MAAM,WAAW,KAAK,kBAAkB;GAExC,MAAM,cAAc,MAAM,KAAK,aAC7B,IAAI,IAAI,eAAe,IAAI,EAC3B,SACD;AAED,OAAI,YAAY,UAAU,QAAQ,MAAM;IACtC,MAAM,IAAI,YAAY,SAAS,QAAQ;AAEvC,QAAI;AACF,WAAM,KAAK,kBAAkB,GAAG,SAAS;aAClCL,GAAY;AACnB,iBAAY,MAAM,+BAA+BF,iBAAe,EAAE,GAAG;;;AAIzE,UAAO;WACAE,GAAY;AACnB,QAAK,uBAAuB,EAAE;AAC9B,SAAM;YACE;AACR,eAAY,UAAU;;;;;;;CAQ1B,YAAY,KAAmB;AAC7B,MAAI,KAAK,WACP,aAAY,UAAU,wBAAwB,MAAM;;CAIxD,MAAc,aACZ,KACA,aACkB;EAClB,MAAM,SAAS,MAAM,KAAK,WAAW;AAErC,SAAO,IAAI,SAAS,SAAS,WAAW;GAEtC,IAAIM;GAGJ,IAAI,SAAS;GAEb,MAAM,SAAS,WAA0B;AACvC,QAAI,YACF,aAAY,SAAS;AAGvB,kBAAc,kBAAkB,aAAa;KAC3C,UAAU;KACV,MAAM;KACP,CAAC;AAEF,gBAAY,KAAK,UAAU,UAAU;AAEnC,cAAS;AACT,YAAO,MAAM;MACb;AAEF,gBAAY,GAAG,gBAAgB;AAC7B,SAAI,CAAC,OACH,SAAQ,OAAO;MAEjB;AAEF,WAAO,KAAK,UAAU,QAAQ,QAAQ,sBAAsB;AAE1D,WAAM,mBAAmB,CAAC;MAC1B;AAIF,WAAO,KAAK,YAAY;;AAI1B,SAAM,OAAO,OAAO,IAAI,CAAC;IACzB;;CAGJ,MAAc,WAA0B;AACtC,OAAK,YAAY,YAAY,KAAK,iBAAiB;AACnD,QAAM,KAAK,cAAc;;CAG3B,MAAc,gBAA0C;EACtD,MAAM,aAAa,MAAM,KAAK,QAAQ,mBAAmB;AAEzD,MAAI,eAAe,OACjB;AAGF,aAAW,YAAY;AACvB,SAAO;;CAGT,MAAc,eAA6B;EACzC,MAAM,IAAI,KAAK;AAEf,MAAI,EAAE,KAAK;AACT,QAAK,QAAQ,iBAAiB,EAAE,IAAI;AACpC,UAAO,IAAI,IAAI,EAAE,IAAI;;EAGvB,MAAM,WAAW,MAAM,KAAK,QAAQ,YAAY;AAChD,WAAS,YAAY,KAAK,cAAc;AAExC,MAAI,EAAE,IACJ,UAAS,YAAY,QAAQ,EAAE;WACtB,EAAE,GACX,UAAS,YAAY,OAAO,EAAE;WACrB,EAAE,OACX,UAAS,YAAY,WAAW,EAAE;WACzB,EAAE,SACX,UAAS,YAAY,QAAQ,EAAE;MAE/B,UAAS,YAAY;AAGvB,WAAS,YAAY,IAAI,KAAK;AAE9B,OAAK,QAAQ,iBAAiB,SAAS,UAAU,CAAC;AAElD,SAAO;;CAGT,AAAQ,SAAS,SAAyB;EACxC,MAAM,iBAAiB,QAAQ,QAAQ,oBAAoB,GAAG;AAC9D,SAAO,qBAAqB,KAAK,cAAc,KAAK,GAAG,KAAK,wBAAwB,GAAG;;CAGzF,MAAc,iBAAiB,SAA8C;EAC3E,MAAM,WAAW,QAAQ,KAAK;AAE9B,MAAI;GACF,MAAM,UAAU,KAAK,kBAAkB;AACvC,SAAM,MAAM,QAAQ;AACpB,WAAQ,MAAM,QAAQ;AAGtB,WAAQ,IAAI,0BAA0B,QAAQ,IAAI;AAClD,UAAO,QAAQ,IAAI;AAEnB,OACE,MAAM,aAAa,aACjB,CAAC,KAAK,cAAc,KAAK,EACzB,KAAK,SAAS,QAAQ,EACtB,EAAE,EACF,QACA,KACD,EACD;AACA,SAAK,YAAY,yBAAyB;AAC1C,WAAO,GAAG,QAAQ,GAAG,KAAK,cAAc;;AAG1C,QAAK,YAAY,0BAA0B;AAC3C;YACQ;AACR,WAAQ,IAAI,mBAAmB,QAAQ,IAAI;AAC3C,UAAO,QAAQ,IAAI;AACnB,WAAQ,MAAM,SAAS;;;CAI3B,MAAc,kBACZ,SACA,UACe;EACf,MAAM,WAAW,QAAQ,KAAK;AAE9B,MAAI;GACF,MAAM,UAAU,KAAK,kBAAkB;AACvC,SAAM,MAAM,QAAQ;AACpB,WAAQ,MAAM,QAAQ;AACtB,SAAM,SAAS,UAAU,GAAG,QAAQ,GAAG,KAAK,cAAc,OAAO;AAGjE,WAAQ,IAAI,0BAA0B,QAAQ,IAAI;AAClD,UAAO,QAAQ,IAAI;AAEnB,SAAM,aAAa,UACjB,CAAC,KAAK,cAAc,KAAK,EACzB,KAAK,SAAS,QAAQ,EACtB,QACA,KACD;AACD,QAAK,YAAY,6BAA6B;YACtC;AACR,WAAQ,IAAI,mBAAmB,QAAQ,IAAI;AAC3C,UAAO,QAAQ,IAAI;AACnB,WAAQ,MAAM,SAAS;;;CAI3B,AAAQ,wBAA8B;AACpC,MAAI,CAAC,QAAQ,IAAI,4BAA4B;AAC3C,eAAY,eACV,8BACA,KAAK,iBAAiB,CACvB;AAED,eAAY,UAAU,iCAAiC,KAAK,KAAK,CAAC;;;CAItE,MAAc,oBAAmC;AAC/C,MAAI;AACF,OAAI,QAAQ,IAAI,+BAA+B,KAAK,iBAAiB,CACnE;GAGF,MAAM,aAAa,MAAM,kBACvB,KAAK,cAAc,oBACnB,KAAK,cAAc,qBACnB,SAAS,YAAY,SAAS,gCAAgC,CAAC,CAChE;AACD,eAAY,MAAM,0BAA0B,WAAW,OAAO;AAC9D,OAAI,WAAW,OAAO,EACpB,MAAK,YAAY,kBAAkB,OAAO,YAAY,WAAW,CAAC;WAE7DJ,YAAqB;AAC5B,eAAY,MACV,gCAAgCJ,iBAAe,WAAW,GAC3D;;;CAIL,MAAc,sBAAwC;EACpD,IAAIS;EAEJ,MAAM,aAAa,QAAQ,IAAI,WAAW,IAAI,MAAM,IAAI;AACxD,OAAK,MAAM,YAAY,WAAW;GAChC,MAAM,eAAe,KAAK,KAAK,UAAU,MAAM;AAE/C,OAAI;AACF,UAAM,GAAG,OAAO,cAAc,GAAG,UAAU,KAAK;AAChD,gBAAY,MAAM,gBAAgB,eAAe;AACjD,kBAAc;AACd;WACM;AACN,gBAAY,MAAM,cAAc,eAAe;;;AAGnD,OAAK,QAAQ,mBAAmB,eAAe,GAAG;AAElD,MAAI,KAAK,cAAc,eAAe,SACpC,QAAO;AAIT,MAD6B,YAAY,SAAS,wBAAwB,KAC7C,gBAE3B,QAAO;AAGT,MAAI,gBAAgB,OAClB,QAAO;AAET,cAAY,UAAU,yBAAyB,gBAAgB;AAE/D,UAAQ,KAAK,cAAc,YAA3B;GACE,KAAK;AACH,gBAAY,UACV,CACE,uDACA,uFACD,CAAC,KAAK,IAAI,CACZ;AACD;GACF,KAAK;AACH,gBAAY,QACV,CACE,8DACA,uFACD,CAAC,KAAK,IAAI,CACZ;AACD;;AAGJ,SAAO;;CAGT,MAAc,wBAAuC;EACnD,IAAI,SAAS;EAEb,MAAMC,UAAmC,EAAE;AAC3C,UAAQ,SAAS;AACjB,UAAQ,YAAY,EAClB,SAAS,SAAS;AAChB,aAAU,KAAK,UAAU;KAE5B;AAED,MAAI;AACF,YAAS;AACT,SAAMd,OAAY,KAAK,OAAO;IAAC;IAAS;IAAQ;IAAS,EAAE,QAAQ;AACnE,QAAK,QAAQ,6BAA6B,OAAO;UAC3C;AACN,OAAI;AAEF,aAAS;AACT,UAAMA,OAAY,KAAK,OAAO;KAAC;KAAS;KAAQ;KAAS,EAAE,QAAQ;AACnE,SAAK,QAAQ,6BAA6B,OAAO;WAC3C;AACN,SAAK,QAAQ,6BAA6B,OAAO;AACjD;;;AAIJ,MAAI;GACF,MAAM,SAAS,KAAK,MAAM,OAAO;AACjC,OAAI,OAAO,YAAY,EACrB,MAAK,gBAAgB;YACZ,OAAO,YAAY,EAC5B,MAAK,gBAAgB;YACZ,OAAO,YAAY,OAC5B,MAAK,QACH,4BACA,6BAA6B,KAAK,UAAU,OAAO,QAAQ,GAC5D;AAGH,QAAK,QAAQ,wBAAwB,KAAK,UAAU,OAAO,QAAQ,CAAC;WAC7DM,GAAY;AACnB,QAAK,QAAQ,4BAA4BF,iBAAe,EAAE,CAAC;;;CAI/D,MAAc,sBAAqC;EACjD,IAAI,SAAS;AAEb,MAAI;AACF,IAAC,CAAE,QAAQ,UAAW,MAAMJ,OAAY,cACtC,OACA,CAAC,YAAY,EACb,EACE,QAAQ,MACT,CACF;AACD,YAAS,OAAO,MAAM,IAAI;UACpB;AAIR,OAAK,QAAQ,kBAAkB,OAAO;;CAGxC,MAAc,eAA8B;EAC1C,MAAM,iBAAiB,MAAM,KAAK,QAAQ,mBAAmB;AAC7D,MAAI,mBAAmB,QAAW;AAChC,eAAY,MACV,8DACD;AACD,eAAY,MAAM,KAAK,UAAU,KAAK,QAAQ,QAAW,EAAE,CAAC;AAC5D;;EAGF,MAAM,QAAQ;GACZ,yBAAS,IAAI,MAAM;GACnB,OAAO,KAAK;GACb;AAED,MAAI;AACF,UACE,MAAM,KAAK,WAAW,EACtB,KAAK,gBAAgB;IACrB,MAAM;IACN,SAAS,EACP,SAAS,gCACV;IACF,CAAC;WACKe,KAAc;AACrB,QAAK,uBAAuB,IAAI;AAEhC,eAAY,MACV,yCAAyC,eAAe,IAAIX,iBAAe,IAAI,GAChF;;AAEH,OAAK,SAAS,EAAE;;;AAIpB,SAASA,iBAAe,OAAwB;AAC9C,QAAO,iBAAiB,SAAS,OAAO,SAAS,WAC7C,MAAM,UAAU,GAChB,KAAK,UAAU,MAAM;;AAG3B,SAAS,qBACP,eACwB;CACxB,MAAM,iBAAiB,cAAc,kBAAkB,cAAc;CAErE,MAAMY,YAAoC;EACxC,MAAM,cAAc;EACpB;EACA,aAAa,cAAc,eAAe;EAC1C,YAAY,cAAc;EAC1B,oBAAoB,cAAc;EAClC,YAAY,cAAc;EAC1B,oBAAoB,cAAc,sBAAsB;GACtD;GACA;GACA,cAAc;GACf;EACD,qBACE,cAAc,sBAAsB;EACvC;AAED,aAAY,MAAM,kBAAkB;AACpC,aAAY,MAAM,KAAK,UAAU,WAAW,QAAW,EAAE,CAAC;AAE1D,QAAO"} \ No newline at end of file +{"version":3,"file":"index.js","names":["fs","linuxReleaseInfoOptionsDefaults: LinuxReleaseInfoOptions","searchOsReleaseFileList: string[]","os","lines: string[]","exec","data: object","ret: T","backtraces: Map","exec","sussyArray: unknown","innerError: unknown","coredumps: SystemdCoreDumpInfo[]","ident: AnonymizedCorrelationHashes","currentUrl: URL","newUrl: URL","err: unknown","url: URL | undefined","defaultFallback: Promise","records: SrvRecord[]","reason: unknown","byPriorityWeight: Map","prioritizedRecords: SrvRecord[]","keys: number[]","scratchRecords: SrvRecord[]","result: SrvRecord[]","weights: number[]","os","actionsExec","correlation.identify","platform.getArchOs","platform.getNixPlatform","stringifyError","fsConstants","e: unknown","exceptionContext: Map","innerError: unknown","impactSymbol: Map","summaries: string[]","reportContext: {\n [index: string]: string | number | undefined;\n }","writeStream: WriteStream | undefined","nixLocation: string | undefined","options: actionsExec.ExecOptions","err: unknown","finalOpts: ConfidentActionOptions"],"sources":["../src/linux-release-info.ts","../src/actions-core-platform.ts","../src/errors.ts","../src/backtrace.ts","../src/correlation.ts","../src/ids-host.ts","../src/inputs.ts","../src/platform.ts","../src/sourcedef.ts","../src/index.ts"],"sourcesContent":["/*!\n * linux-release-info\n * Get Linux release info (distribution name, version, arch, release, etc.)\n * from '/etc/os-release' or '/usr/lib/os-release' files and from native os\n * module. On Windows and Darwin platforms it only returns common node os module\n * info (platform, hostname, release, and arch)\n *\n * Licensed under MIT\n * Copyright (c) 2018-2020 [Samuel Carreira]\n */\n// NOTE: we depend on this directly to get around some un-fun issues with mixing CommonJS\n// and ESM in the bundle. We've modified the original logic to improve things like typing\n// and fixing ESLint issues. Originally drawn from:\n// https://github.com/samuelcarreira/linux-release-info/blob/84a91aa5442b47900da03020c590507545d3dc74/src/index.ts\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport { promisify } from \"node:util\";\n\nconst readFileAsync = promisify(fs.readFile);\n\nexport interface LinuxReleaseInfoOptions {\n /**\n * read mode, possible values: 'async' and 'sync'\n *\n * @default 'async'\n */\n mode?: \"async\" | \"sync\";\n /**\n * custom complete file path with os info default null/none\n * if not provided the system will search on the '/etc/os-release'\n * and '/usr/lib/os-release' files\n *\n * @default null\n */\n customFile?: string | null | undefined;\n /**\n * if true, show console debug messages\n *\n * @default false\n */\n debug?: boolean;\n}\n\nconst linuxReleaseInfoOptionsDefaults: LinuxReleaseInfoOptions = {\n mode: \"async\",\n customFile: null,\n debug: false,\n};\n\n/**\n * Get OS release info from 'os-release' file and from native os module\n * on Windows or Darwin it only returns common os module info\n * (uses native fs module)\n * @returns {object} info from the current os\n */\nexport function releaseInfo(infoOptions: LinuxReleaseInfoOptions): object {\n const options = { ...linuxReleaseInfoOptionsDefaults, ...infoOptions };\n\n const searchOsReleaseFileList: string[] = osReleaseFileList(\n options.customFile,\n );\n\n if (os.type() !== \"Linux\") {\n if (options.mode === \"sync\") {\n return getOsInfo();\n } else {\n return Promise.resolve(getOsInfo());\n }\n }\n\n if (options.mode === \"sync\") {\n return readSyncOsreleaseFile(searchOsReleaseFileList, options);\n } else {\n return Promise.resolve(\n readAsyncOsReleaseFile(searchOsReleaseFileList, options),\n );\n }\n}\n\n/**\n * Format file data: convert data to object keys/values\n *\n * @param {object} sourceData Source object to be appended\n * @param {string} srcParseData Input file data to be parsed\n * @returns {object} Formated object\n */\nfunction formatFileData(sourceData: OsInfo, srcParseData: string): OsInfo {\n const lines: string[] = srcParseData.split(\"\\n\");\n\n for (const line of lines) {\n const lineData = line.split(\"=\");\n\n if (lineData.length === 2) {\n lineData[1] = lineData[1].replace(/[\"'\\r]/gi, \"\"); // remove quotes and return character\n\n Object.defineProperty(sourceData, lineData[0].toLowerCase(), {\n value: lineData[1],\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n }\n\n return sourceData;\n}\n\n/**\n * Export a list of os-release files\n *\n * @param {string} customFile optional custom complete filepath\n * @returns {array} list of os-release files\n */\nfunction osReleaseFileList(customFile: string | null | undefined): string[] {\n const DEFAULT_OS_RELEASE_FILES = [\"/etc/os-release\", \"/usr/lib/os-release\"];\n\n if (!customFile) {\n return DEFAULT_OS_RELEASE_FILES;\n } else {\n return Array(customFile);\n }\n}\n\n/**\n * Operating system info.\n */\ntype OsInfo = {\n type: string;\n platform: string;\n hostname: string;\n arch: string;\n release: string;\n};\n\n/**\n * Get OS Basic Info\n * (uses node 'os' native module)\n *\n * @returns {OsInfo} os basic info\n */\nfunction getOsInfo(): OsInfo {\n return {\n type: os.type(),\n platform: os.platform(),\n hostname: os.hostname(),\n arch: os.arch(),\n release: os.release(),\n };\n}\n\n/* Helper functions */\n\nasync function readAsyncOsReleaseFile(\n fileList: string[],\n options: LinuxReleaseInfoOptions,\n): Promise {\n let fileData = null;\n\n for (const osReleaseFile of fileList) {\n try {\n if (options.debug) {\n /* eslint-disable no-console */\n console.log(`Trying to read '${osReleaseFile}'...`);\n }\n\n fileData = await readFileAsync(osReleaseFile, \"binary\");\n\n if (options.debug) {\n console.log(`Read data:\\n${fileData}`);\n }\n\n break;\n } catch (error) {\n if (options.debug) {\n console.error(error);\n }\n }\n }\n\n if (fileData === null) {\n throw new Error(\"Cannot read os-release file!\");\n //return getOsInfo();\n }\n\n return formatFileData(getOsInfo(), fileData);\n}\n\nfunction readSyncOsreleaseFile(\n releaseFileList: string[],\n options: LinuxReleaseInfoOptions,\n): OsInfo {\n let fileData = null;\n\n for (const osReleaseFile of releaseFileList) {\n try {\n if (options.debug) {\n console.log(`Trying to read '${osReleaseFile}'...`);\n }\n\n fileData = fs.readFileSync(osReleaseFile, \"binary\");\n\n if (options.debug) {\n console.log(`Read data:\\n${fileData}`);\n }\n\n break;\n } catch (error) {\n if (options.debug) {\n console.error(error);\n }\n }\n }\n\n if (fileData === null) {\n throw new Error(\"Cannot read os-release file!\");\n //return getOsInfo();\n }\n\n return formatFileData(getOsInfo(), fileData);\n}\n","// MIT, mostly lifted from https://github.com/actions/toolkit/blob/5a736647a123ecf8582376bdaee833fbae5b3847/packages/core/src/platform.ts\n// since it isn't in @actions/core 1.10.1 which is their current release as 2024-04-19.\n// Changes: Replaced the lsb_release call in Linux with `linux-release-info` to parse the os-release file directly.\nimport { releaseInfo } from \"./linux-release-info.js\";\nimport * as actionsCore from \"@actions/core\";\nimport * as exec from \"@actions/exec\";\nimport os from \"os\";\n\n/**\n * The name and version of the Action runner's system.\n */\ntype SystemInfo = {\n name: string;\n version: string;\n};\n\n/**\n * Get the name and version of the current Windows system.\n */\nconst getWindowsInfo = async (): Promise => {\n const { stdout: version } = await exec.getExecOutput(\n 'powershell -command \"(Get-CimInstance -ClassName Win32_OperatingSystem).Version\"',\n undefined,\n {\n silent: true,\n },\n );\n\n const { stdout: name } = await exec.getExecOutput(\n 'powershell -command \"(Get-CimInstance -ClassName Win32_OperatingSystem).Caption\"',\n undefined,\n {\n silent: true,\n },\n );\n\n return {\n name: name.trim(),\n version: version.trim(),\n };\n};\n\n/**\n * Get the name and version of the current macOS system.\n */\nconst getMacOsInfo = async (): Promise => {\n const { stdout } = await exec.getExecOutput(\"sw_vers\", undefined, {\n silent: true,\n });\n\n const version = stdout.match(/ProductVersion:\\s*(.+)/)?.[1] ?? \"\";\n const name = stdout.match(/ProductName:\\s*(.+)/)?.[1] ?? \"\";\n\n return {\n name,\n version,\n };\n};\n\n/**\n * Get the name and version of the current Linux system.\n */\nconst getLinuxInfo = async (): Promise => {\n let data: object = {};\n\n try {\n data = releaseInfo({ mode: \"sync\" });\n actionsCore.debug(`Identified release info: ${JSON.stringify(data)}`);\n } catch (e) {\n actionsCore.debug(`Error collecting release info: ${e}`);\n }\n\n return {\n name: getPropertyViaWithDefault(\n data,\n [\"id\", \"name\", \"pretty_name\", \"id_like\"],\n \"unknown\",\n ),\n version: getPropertyViaWithDefault(\n data,\n [\"version_id\", \"version\", \"version_codename\"],\n \"unknown\",\n ),\n };\n};\n\nfunction getPropertyViaWithDefault(\n data: object,\n names: Property[],\n defaultValue: T,\n): T {\n for (const name of names) {\n const ret: T = getPropertyWithDefault(data, name, defaultValue);\n\n if (ret !== defaultValue) {\n return ret;\n }\n }\n\n return defaultValue;\n}\n\nfunction getPropertyWithDefault(\n data: object,\n name: Property,\n defaultValue: T,\n): T {\n if (!data.hasOwnProperty(name)) {\n return defaultValue;\n }\n\n const value = (data as { [K in Property]: T })[name];\n\n // NB. this check won't work for object instances\n if (typeof value !== typeof defaultValue) {\n return defaultValue;\n }\n\n return value;\n}\n\n/**\n * The Action runner's platform.\n */\nexport const platform = os.platform();\n\n/**\n * The Action runner's architecture.\n */\nexport const arch = os.arch();\n\n/**\n * Whether the Action runner is a Windows system.\n */\nexport const isWindows = platform === \"win32\";\n\n/**\n * Whether the Action runner is a macOS system.\n */\nexport const isMacOS = platform === \"darwin\";\n\n/**\n * Whether the Action runner is a Linux system.\n */\nexport const isLinux = platform === \"linux\";\n\n/**\n * System-level information about the current host (platform, architecture, etc.).\n */\ntype SystemDetails = {\n name: string;\n platform: string;\n arch: string;\n version: string;\n isWindows: boolean;\n isMacOS: boolean;\n isLinux: boolean;\n};\n\n/**\n * Get system-level information about the current host (platform, architecture, etc.).\n */\nexport async function getDetails(): Promise {\n return {\n ...(await (isWindows\n ? getWindowsInfo()\n : isMacOS\n ? getMacOsInfo()\n : getLinuxInfo())),\n platform,\n arch,\n isWindows,\n isMacOS,\n isLinux,\n };\n}\n","/**\n * Coerce a value of type `unknown` into a string.\n */\nexport function stringifyError(e: unknown): string {\n if (e instanceof Error) {\n return e.message;\n } else if (typeof e === \"string\") {\n return e;\n } else {\n return JSON.stringify(e);\n }\n}\n","/**\n * @packageDocumentation\n * Collects backtraces for executables for diagnostics\n */\nimport { isLinux, isMacOS } from \"./actions-core-platform.js\";\nimport { stringifyError } from \"./errors.js\";\nimport * as actionsCore from \"@actions/core\";\nimport * as exec from \"@actions/exec\";\nimport { readFile, readdir, stat } from \"node:fs/promises\";\nimport { promisify } from \"node:util\";\nimport { gzip } from \"node:zlib\";\n\n// Give a few seconds buffer, capturing traces that happened a few seconds earlier.\nconst START_SLOP_SECONDS = 5;\n\nexport async function collectBacktraces(\n prefixes: string[],\n programNameDenyList: string[],\n startTimestampMs: number,\n): Promise> {\n if (isMacOS) {\n return await collectBacktracesMacOS(\n prefixes,\n programNameDenyList,\n startTimestampMs,\n );\n }\n if (isLinux) {\n return await collectBacktracesSystemd(\n prefixes,\n programNameDenyList,\n startTimestampMs,\n );\n }\n\n return new Map();\n}\n\nexport async function collectBacktracesMacOS(\n prefixes: string[],\n programNameDenyList: string[],\n startTimestampMs: number,\n): Promise> {\n const backtraces: Map = new Map();\n\n try {\n const { stdout: logJson } = await exec.getExecOutput(\n \"log\",\n [\n \"show\",\n \"--style\",\n \"json\",\n \"--last\",\n // Note we collect the last 1m only, because it should only take a few seconds to write the crash log.\n // Therefore, any crashes before this 1m should be long done by now.\n \"1m\",\n \"--no-info\",\n \"--predicate\",\n \"sender = 'ReportCrash'\",\n ],\n {\n silent: true,\n },\n );\n\n const sussyArray: unknown = JSON.parse(logJson);\n if (!Array.isArray(sussyArray)) {\n throw new Error(`Log json isn't an array: ${logJson}`);\n }\n\n if (sussyArray.length > 0) {\n actionsCore.info(`Collecting crash data...`);\n const delay = async (ms: number): Promise =>\n new Promise((resolve) => setTimeout(resolve, ms));\n await delay(5000);\n }\n } catch {\n actionsCore.debug(\n \"Failed to check logs for in-progress crash dumps; now proceeding with the assumption that all crash dumps completed.\",\n );\n }\n\n const dirs = [\n [\"system\", \"/Library/Logs/DiagnosticReports/\"],\n [\"user\", `${process.env[\"HOME\"]}/Library/Logs/DiagnosticReports/`],\n ];\n\n for (const [source, dir] of dirs) {\n const fileNames = (await readdir(dir))\n .filter((fileName) => {\n return prefixes.some((prefix) => fileName.startsWith(prefix));\n })\n .filter((fileName) => {\n return !programNameDenyList.some((programName) =>\n fileName.startsWith(programName),\n );\n })\n .filter((fileName) => {\n // macOS creates .diag files periodically, which are called \"microstackshots\".\n // We don't necessarily want those, and they're definitely not crashes.\n // See: https://patents.google.com/patent/US20140237219A1/en\n return !fileName.endsWith(\".diag\");\n });\n\n const doGzip = promisify(gzip);\n for (const fileName of fileNames) {\n try {\n if ((await stat(`${dir}/${fileName}`)).ctimeMs >= startTimestampMs) {\n const logText = await readFile(`${dir}/${fileName}`);\n const buf = await doGzip(logText);\n backtraces.set(\n `backtrace_value_${source}_${fileName}`,\n buf.toString(\"base64\"),\n );\n }\n } catch (innerError: unknown) {\n backtraces.set(\n `backtrace_failure_${source}_${fileName}`,\n stringifyError(innerError),\n );\n }\n }\n }\n\n return backtraces;\n}\n\ntype SystemdCoreDumpInfo = {\n exe: string;\n pid: number;\n};\n\nexport async function collectBacktracesSystemd(\n prefixes: string[],\n programNameDenyList: string[],\n startTimestampMs: number,\n): Promise> {\n const sinceSeconds =\n Math.ceil((Date.now() - startTimestampMs) / 1000) + START_SLOP_SECONDS;\n const backtraces: Map = new Map();\n\n const coredumps: SystemdCoreDumpInfo[] = [];\n\n try {\n const { stdout: coredumpjson } = await exec.getExecOutput(\n \"coredumpctl\",\n [\"--json=pretty\", \"list\", \"--since\", `${sinceSeconds} seconds ago`],\n {\n silent: true,\n },\n );\n\n const sussyArray: unknown = JSON.parse(coredumpjson);\n if (!Array.isArray(sussyArray)) {\n throw new Error(`Coredump isn't an array: ${coredumpjson}`);\n }\n\n for (const sussyObject of sussyArray) {\n const keys = Object.keys(sussyObject);\n\n if (keys.includes(\"exe\") && keys.includes(\"pid\")) {\n if (\n typeof sussyObject.exe == \"string\" &&\n typeof sussyObject.pid == \"number\"\n ) {\n const execParts = sussyObject.exe.split(\"/\");\n const binaryName = execParts[execParts.length - 1];\n\n if (\n prefixes.some((prefix) => binaryName.startsWith(prefix)) &&\n !programNameDenyList.includes(binaryName)\n ) {\n coredumps.push({\n exe: sussyObject.exe,\n pid: sussyObject.pid,\n });\n }\n } else {\n actionsCore.debug(\n `Mysterious coredump entry missing exe string and/or pid number: ${JSON.stringify(sussyObject)}`,\n );\n }\n } else {\n actionsCore.debug(\n `Mysterious coredump entry missing exe value and/or pid value: ${JSON.stringify(sussyObject)}`,\n );\n }\n }\n } catch (innerError: unknown) {\n actionsCore.debug(\n `Cannot collect backtraces: ${stringifyError(innerError)}`,\n );\n\n return backtraces;\n }\n\n const doGzip = promisify(gzip);\n for (const coredump of coredumps) {\n try {\n const { stdout: logText } = await exec.getExecOutput(\n \"coredumpctl\",\n [\"info\", `${coredump.pid}`],\n {\n silent: true,\n },\n );\n\n const buf = await doGzip(logText);\n backtraces.set(`backtrace_value_${coredump.pid}`, buf.toString(\"base64\"));\n } catch (innerError: unknown) {\n backtraces.set(\n `backtrace_failure_${coredump.pid}`,\n stringifyError(innerError),\n );\n }\n }\n\n return backtraces;\n}\n","import * as actionsCore from \"@actions/core\";\nimport { createHash, randomUUID } from \"node:crypto\";\n\nconst OPTIONAL_VARIABLES = [\"INVOCATION_ID\"];\n\n/* eslint-disable camelcase */\n/**\n * JSON sent to server.\n */\nexport type AnonymizedCorrelationHashes = {\n $anon_distinct_id: string;\n $groups: Record;\n $session_id?: string;\n correlation_source: string;\n github_repository_hash?: string;\n github_workflow_hash?: string;\n github_workflow_job_hash?: string;\n github_workflow_run_differentiator_hash?: string;\n github_workflow_run_hash?: string;\n is_ci: boolean;\n};\n\nexport function identify(): AnonymizedCorrelationHashes {\n const repository = hashEnvironmentVariables(\"GHR\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n ]);\n\n const run_differentiator = hashEnvironmentVariables(\"GHWJA\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n \"GITHUB_WORKFLOW\",\n \"GITHUB_JOB\",\n \"GITHUB_RUN_ID\",\n \"GITHUB_RUN_NUMBER\",\n \"GITHUB_RUN_ATTEMPT\",\n \"INVOCATION_ID\",\n ]);\n\n const ident: AnonymizedCorrelationHashes = {\n $anon_distinct_id: process.env[\"RUNNER_TRACKING_ID\"] || randomUUID(),\n\n correlation_source: \"github-actions\",\n\n github_repository_hash: repository,\n github_workflow_hash: hashEnvironmentVariables(\"GHW\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n \"GITHUB_WORKFLOW\",\n ]),\n github_workflow_job_hash: hashEnvironmentVariables(\"GHWJ\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n \"GITHUB_WORKFLOW\",\n \"GITHUB_JOB\",\n ]),\n github_workflow_run_hash: hashEnvironmentVariables(\"GHWJR\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n \"GITHUB_REPOSITORY\",\n \"GITHUB_REPOSITORY_ID\",\n \"GITHUB_WORKFLOW\",\n \"GITHUB_JOB\",\n \"GITHUB_RUN_ID\",\n ]),\n github_workflow_run_differentiator_hash: run_differentiator,\n $session_id: run_differentiator,\n $groups: {\n github_repository: repository,\n github_organization: hashEnvironmentVariables(\"GHO\", [\n \"GITHUB_SERVER_URL\",\n \"GITHUB_REPOSITORY_OWNER\",\n \"GITHUB_REPOSITORY_OWNER_ID\",\n ]),\n },\n is_ci: true,\n };\n\n actionsCore.debug(\"Correlation data:\");\n actionsCore.debug(JSON.stringify(ident, null, 2));\n\n return ident;\n}\n\nfunction hashEnvironmentVariables(\n prefix: string,\n variables: string[],\n): undefined | string {\n const hash = createHash(\"sha256\");\n\n for (const varName of variables) {\n let value = process.env[varName];\n\n if (value === undefined) {\n if (OPTIONAL_VARIABLES.includes(varName)) {\n actionsCore.debug(\n `Optional environment variable not set: ${varName} -- substituting with the variable name`,\n );\n value = varName;\n } else {\n actionsCore.debug(\n `Environment variable not set: ${varName} -- can't generate the requested identity`,\n );\n return undefined;\n }\n }\n\n hash.update(value);\n hash.update(\"\\0\");\n }\n\n return `${prefix}-${hash.digest(\"hex\")}`;\n}\n","/**\n * @packageDocumentation\n * Identifies and discovers backend servers for install.determinate.systems\n */\nimport { stringifyError } from \"./errors.js\";\nimport * as actionsCore from \"@actions/core\";\nimport { Got, got } from \"got\";\nimport type { SrvRecord } from \"node:dns\";\nimport { resolveSrv } from \"node:dns/promises\";\n\nconst DEFAULT_LOOKUP = \"_detsys_ids._tcp.install.determinate.systems.\";\nconst ALLOWED_SUFFIXES = [\n \".install.determinate.systems\",\n \".install.detsys.dev\",\n];\n\nconst DEFAULT_IDS_HOST = \"https://install.determinate.systems\";\nconst LOOKUP = process.env[\"IDS_LOOKUP\"] ?? DEFAULT_LOOKUP;\n\nconst DEFAULT_TIMEOUT = 10_000; // 10 seconds in ms\n\n/**\n * Host information for install.determinate.systems.\n */\nexport class IdsHost {\n private idsProjectName: string;\n private diagnosticsSuffix?: string;\n private runtimeDiagnosticsUrl?: string;\n private prioritizedURLs?: URL[];\n private client?: Got;\n\n constructor(\n idsProjectName: string,\n diagnosticsSuffix: string | undefined,\n runtimeDiagnosticsUrl: string | undefined,\n ) {\n this.idsProjectName = idsProjectName;\n this.diagnosticsSuffix = diagnosticsSuffix;\n this.runtimeDiagnosticsUrl = runtimeDiagnosticsUrl;\n this.client = undefined;\n }\n\n async getGot(\n recordFailoverCallback?: (\n incitingError: unknown,\n prevUrl: URL,\n nextUrl: URL,\n ) => void,\n timeout?: number,\n ): Promise {\n if (this.client === undefined) {\n this.client = got.extend({\n timeout: {\n request: timeout ?? DEFAULT_TIMEOUT,\n },\n\n retry: {\n limit: Math.max((await this.getUrlsByPreference()).length, 3),\n methods: [\"GET\", \"HEAD\"],\n },\n\n hooks: {\n beforeRetry: [\n async (error, retryCount) => {\n const prevUrl = await this.getRootUrl();\n this.markCurrentHostBroken();\n const nextUrl = await this.getRootUrl();\n\n if (recordFailoverCallback !== undefined) {\n recordFailoverCallback(error, prevUrl, nextUrl);\n }\n\n actionsCore.info(\n `Retrying after error ${error.code}, retry #: ${retryCount}`,\n );\n },\n ],\n\n beforeRequest: [\n async (options) => {\n // The getter always returns a URL, even though the setter accepts a string\n const currentUrl: URL = options.url as URL;\n\n if (this.isUrlSubjectToDynamicUrls(currentUrl)) {\n const newUrl: URL = new URL(currentUrl);\n\n const url: URL = await this.getRootUrl();\n newUrl.host = url.host;\n\n options.url = newUrl;\n actionsCore.debug(`Transmuted ${currentUrl} into ${newUrl}`);\n } else {\n actionsCore.debug(`No transmutations on ${currentUrl}`);\n }\n },\n ],\n },\n });\n }\n\n return this.client;\n }\n\n markCurrentHostBroken(): void {\n this.prioritizedURLs?.shift();\n }\n\n setPrioritizedUrls(urls: URL[]): void {\n this.prioritizedURLs = urls;\n }\n\n isUrlSubjectToDynamicUrls(url: URL): boolean {\n if (url.origin === DEFAULT_IDS_HOST) {\n return true;\n }\n\n for (const suffix of ALLOWED_SUFFIXES) {\n if (url.host.endsWith(suffix)) {\n return true;\n }\n }\n\n return false;\n }\n\n async getDynamicRootUrl(): Promise {\n const idsHost = process.env[\"IDS_HOST\"];\n if (idsHost !== undefined) {\n try {\n return new URL(idsHost);\n } catch (err: unknown) {\n actionsCore.error(\n `IDS_HOST environment variable is not a valid URL. Ignoring. ${stringifyError(err)}`,\n );\n }\n }\n\n let url: URL | undefined = undefined;\n try {\n const urls = await this.getUrlsByPreference();\n url = urls[0];\n } catch (err: unknown) {\n actionsCore.error(\n `Error collecting IDS URLs by preference: ${stringifyError(err)}`,\n );\n }\n\n if (url === undefined) {\n return undefined;\n } else {\n // This is a load-bearing `new URL(url)` so that callers can't mutate\n // getRootUrl's return value.\n return new URL(url);\n }\n }\n\n async getRootUrl(): Promise {\n const url = await this.getDynamicRootUrl();\n\n if (url === undefined) {\n return new URL(DEFAULT_IDS_HOST);\n }\n\n return url;\n }\n\n async getDiagnosticsUrl(): Promise {\n if (this.runtimeDiagnosticsUrl === \"\") {\n // User specifically set the diagnostics URL to an empty string\n // so disable diagnostics\n return undefined;\n }\n\n if (\n this.runtimeDiagnosticsUrl !== \"-\" &&\n this.runtimeDiagnosticsUrl !== undefined\n ) {\n try {\n // Caller specified a specific diagnostics URL\n return new URL(this.runtimeDiagnosticsUrl);\n } catch (err: unknown) {\n actionsCore.info(\n `User-provided diagnostic endpoint ignored: not a valid URL: ${stringifyError(err)}`,\n );\n }\n }\n\n try {\n const diagnosticUrl = await this.getRootUrl();\n diagnosticUrl.pathname += \"events/batch\";\n return diagnosticUrl;\n } catch (err: unknown) {\n actionsCore.info(\n `Generated diagnostic endpoint ignored, and diagnostics are disabled: not a valid URL: ${stringifyError(err)}`,\n );\n return undefined;\n }\n }\n\n private async getUrlsByPreference(): Promise {\n if (this.prioritizedURLs === undefined) {\n this.prioritizedURLs = orderRecordsByPriorityWeight(\n await discoverServiceRecords(),\n ).flatMap((record) => recordToUrl(record) || []);\n }\n\n return this.prioritizedURLs;\n }\n}\n\nexport function recordToUrl(record: SrvRecord): URL | undefined {\n const urlStr = `https://${record.name}:${record.port}`;\n try {\n return new URL(urlStr);\n } catch (err: unknown) {\n actionsCore.debug(\n `Record ${JSON.stringify(record)} produced an invalid URL: ${urlStr} (${err})`,\n );\n return undefined;\n }\n}\n\nasync function discoverServiceRecords(): Promise {\n return await discoverServicesStub(resolveSrv(LOOKUP), 1_000);\n}\n\nexport async function discoverServicesStub(\n lookup: Promise,\n timeout: number,\n): Promise {\n const defaultFallback: Promise = new Promise(\n (resolve, _reject) => {\n setTimeout(resolve, timeout, []);\n },\n );\n\n let records: SrvRecord[];\n\n try {\n records = await Promise.race([lookup, defaultFallback]);\n } catch (reason: unknown) {\n actionsCore.debug(`Error resolving SRV records: ${stringifyError(reason)}`);\n records = [];\n }\n\n const acceptableRecords = records.filter((record: SrvRecord): boolean => {\n for (const suffix of ALLOWED_SUFFIXES) {\n if (record.name.endsWith(suffix)) {\n return true;\n }\n }\n\n actionsCore.debug(\n `Unacceptable domain due to an invalid suffix: ${record.name}`,\n );\n\n return false;\n });\n\n if (acceptableRecords.length === 0) {\n actionsCore.debug(`No records found for ${LOOKUP}`);\n } else {\n actionsCore.debug(\n `Resolved ${LOOKUP} to ${JSON.stringify(acceptableRecords)}`,\n );\n }\n\n return acceptableRecords;\n}\n\nexport function orderRecordsByPriorityWeight(\n records: SrvRecord[],\n): SrvRecord[] {\n const byPriorityWeight: Map = new Map();\n for (const record of records) {\n const existing = byPriorityWeight.get(record.priority);\n if (existing) {\n existing.push(record);\n } else {\n byPriorityWeight.set(record.priority, [record]);\n }\n }\n\n const prioritizedRecords: SrvRecord[] = [];\n const keys: number[] = Array.from(byPriorityWeight.keys()).sort(\n (a, b) => a - b,\n );\n\n for (const priority of keys) {\n const recordsByPrio = byPriorityWeight.get(priority);\n if (recordsByPrio === undefined) {\n continue;\n }\n\n prioritizedRecords.push(...weightedRandom(recordsByPrio));\n }\n\n return prioritizedRecords;\n}\n\nexport function weightedRandom(records: SrvRecord[]): SrvRecord[] {\n // Duplicate records so we don't accidentally change our caller's data\n const scratchRecords: SrvRecord[] = records.slice();\n const result: SrvRecord[] = [];\n\n while (scratchRecords.length > 0) {\n const weights: number[] = [];\n\n {\n for (let i = 0; i < scratchRecords.length; i++) {\n weights.push(\n scratchRecords[i].weight + (i > 0 ? scratchRecords[i - 1].weight : 0),\n );\n }\n }\n\n const point = Math.random() * weights[weights.length - 1];\n\n for (\n let selectedIndex = 0;\n selectedIndex < weights.length;\n selectedIndex++\n ) {\n if (weights[selectedIndex] > point) {\n // Remove our selected record and add it to the result\n result.push(scratchRecords.splice(selectedIndex, 1)[0]);\n break;\n }\n }\n }\n\n return result;\n}\n","/**\n * @packageDocumentation\n * Helpers for getting values from an Action's configuration.\n */\nimport * as actionsCore from \"@actions/core\";\n\n/**\n * Get a Boolean input from the Action's configuration by name.\n */\nconst getBool = (name: string): boolean => {\n return actionsCore.getBooleanInput(name);\n};\n\n/**\n * Get a Boolean input from the Action's configuration by name, or undefined if it is unset.\n */\nconst getBoolOrUndefined = (name: string): boolean | undefined => {\n if (getStringOrUndefined(name) === undefined) {\n return undefined;\n }\n\n return actionsCore.getBooleanInput(name);\n};\n\n/**\n * The character used to separate values in the input string.\n */\nexport type Separator = \"space\" | \"comma\";\n\n/**\n * Convert a comma-separated string input into an array of strings. If `comma` is selected,\n * all whitespace is removed from the string before converting to an array.\n */\nconst getArrayOfStrings = (name: string, separator: Separator): string[] => {\n const original = getString(name);\n return handleString(original, separator);\n};\n\n/**\n * Convert a string input into an array of strings or `null` if no value is set.\n */\nconst getArrayOfStringsOrNull = (\n name: string,\n separator: Separator,\n): string[] | null => {\n const original = getStringOrNull(name);\n if (original === null) {\n return null;\n } else {\n return handleString(original, separator);\n }\n};\n\n// Split out this function for use in testing\nexport const handleString = (input: string, separator: Separator): string[] => {\n const sepChar = separator === \"comma\" ? \",\" : /\\s+/;\n const trimmed = input.trim(); // Remove whitespace at the beginning and end\n if (trimmed === \"\") {\n return [];\n }\n\n return trimmed.split(sepChar).map((s: string) => s.trim());\n};\n\n/**\n * Get a multi-line string input from the Action's configuration by name or return `null` if not set.\n */\nconst getMultilineStringOrNull = (name: string): string[] | null => {\n const value = actionsCore.getMultilineInput(name);\n if (value.length === 0) {\n return null;\n } else {\n return value;\n }\n};\n\n/**\n * Get a number input from the Action's configuration by name or return `null` if not set.\n */\nconst getNumberOrNull = (name: string): number | null => {\n const value = actionsCore.getInput(name);\n if (value === \"\") {\n return null;\n } else {\n return Number(value);\n }\n};\n\n/**\n * Get a string input from the Action's configuration.\n */\nconst getString = (name: string): string => {\n return actionsCore.getInput(name);\n};\n\n/**\n * Get a string input from the Action's configuration by name or return `null` if not set.\n */\nconst getStringOrNull = (name: string): string | null => {\n const value = actionsCore.getInput(name);\n if (value === \"\") {\n return null;\n } else {\n return value;\n }\n};\n\n/**\n * Get a string input from the Action's configuration by name or return `undefined` if not set.\n */\nconst getStringOrUndefined = (name: string): string | undefined => {\n const value = actionsCore.getInput(name);\n if (value === \"\") {\n return undefined;\n } else {\n return value;\n }\n};\n\nexport {\n getBool,\n getBoolOrUndefined,\n getArrayOfStrings,\n getArrayOfStringsOrNull,\n getMultilineStringOrNull,\n getNumberOrNull,\n getString,\n getStringOrNull,\n getStringOrUndefined,\n};\n","/**\n * @packageDocumentation\n * Helpers for determining system attributes of the current runner.\n */\nimport * as actionsCore from \"@actions/core\";\n\n/**\n * Get the current architecture plus OS. Examples include `X64-Linux` and `ARM64-macOS`.\n */\nexport function getArchOs(): string {\n const envArch = process.env.RUNNER_ARCH;\n const envOs = process.env.RUNNER_OS;\n\n if (envArch && envOs) {\n return `${envArch}-${envOs}`;\n } else {\n actionsCore.error(\n `Can't identify the platform: RUNNER_ARCH or RUNNER_OS undefined (${envArch}-${envOs})`,\n );\n throw new Error(\"RUNNER_ARCH and/or RUNNER_OS is not defined\");\n }\n}\n\n/**\n * Get the current Nix system. Examples include `x86_64-linux` and `aarch64-darwin`.\n */\nexport function getNixPlatform(archOs: string): string {\n const archOsMap: Map = new Map([\n [\"X64-macOS\", \"x86_64-darwin\"],\n [\"ARM64-macOS\", \"aarch64-darwin\"],\n [\"X64-Linux\", \"x86_64-linux\"],\n [\"ARM64-Linux\", \"aarch64-linux\"],\n ]);\n\n const mappedTo = archOsMap.get(archOs);\n if (mappedTo) {\n return mappedTo;\n } else {\n actionsCore.error(\n `ArchOs (${archOs}) doesn't map to a supported Nix platform.`,\n );\n throw new Error(\n `Cannot convert ArchOs (${archOs}) to a supported Nix platform.`,\n );\n }\n}\n","import { getStringOrUndefined } from \"./inputs.js\";\nimport * as actionsCore from \"@actions/core\";\n\nexport type SourceDef = {\n path?: string;\n url?: string;\n tag?: string;\n pr?: string;\n branch?: string;\n revision?: string;\n};\n\nexport function constructSourceParameters(legacyPrefix?: string): SourceDef {\n return {\n path: noisilyGetInput(\"path\", legacyPrefix),\n url: noisilyGetInput(\"url\", legacyPrefix),\n tag: noisilyGetInput(\"tag\", legacyPrefix),\n pr: noisilyGetInput(\"pr\", legacyPrefix),\n branch: noisilyGetInput(\"branch\", legacyPrefix),\n revision: noisilyGetInput(\"revision\", legacyPrefix),\n };\n}\n\nfunction noisilyGetInput(\n suffix: string,\n legacyPrefix: string | undefined,\n): string | undefined {\n const preferredInput = getStringOrUndefined(`source-${suffix}`);\n\n if (!legacyPrefix) {\n return preferredInput;\n }\n\n // Remaining is for handling cases where the legacy prefix\n // should be examined.\n const legacyInput = getStringOrUndefined(`${legacyPrefix}-${suffix}`);\n\n if (preferredInput && legacyInput) {\n actionsCore.warning(\n `The supported option source-${suffix} and the legacy option ${legacyPrefix}-${suffix} are both set. Preferring source-${suffix}. Please stop setting ${legacyPrefix}-${suffix}.`,\n );\n return preferredInput;\n } else if (legacyInput) {\n actionsCore.warning(\n `The legacy option ${legacyPrefix}-${suffix} is set. Please migrate to source-${suffix}.`,\n );\n return legacyInput;\n } else {\n return preferredInput;\n }\n}\n","/**\n * @packageDocumentation\n * Determinate Systems' TypeScript library for creating GitHub Actions logic.\n */\n// import { version as pkgVersion } from \"../package.json\";\nimport * as ghActionsCorePlatform from \"./actions-core-platform.js\";\nimport { collectBacktraces } from \"./backtrace.js\";\nimport type { CheckIn, Feature } from \"./check-in.js\";\nimport * as correlation from \"./correlation.js\";\nimport { IdsHost } from \"./ids-host.js\";\nimport { getBool, getBoolOrUndefined, getStringOrNull } from \"./inputs.js\";\nimport * as platform from \"./platform.js\";\nimport type { SourceDef } from \"./sourcedef.js\";\nimport { constructSourceParameters } from \"./sourcedef.js\";\nimport * as actionsCache from \"@actions/cache\";\nimport * as actionsCore from \"@actions/core\";\nimport * as actionsExec from \"@actions/exec\";\nimport { type Got, type Request, TimeoutError } from \"got\";\nimport { exec } from \"node:child_process\";\nimport type { UUID } from \"node:crypto\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n PathLike,\n WriteStream,\n createWriteStream,\n constants as fsConstants,\n readFileSync,\n} from \"node:fs\";\nimport fs, { chmod, copyFile, mkdir } from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport { tmpdir } from \"node:os\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { gzip } from \"node:zlib\";\n\nconst pkgVersion = \"1.0\";\n\nconst EVENT_BACKTRACES = \"backtrace\";\nconst EVENT_EXCEPTION = \"exception\";\nconst EVENT_ARTIFACT_CACHE_HIT = \"artifact_cache_hit\";\nconst EVENT_ARTIFACT_CACHE_MISS = \"artifact_cache_miss\";\nconst EVENT_ARTIFACT_CACHE_PERSIST = \"artifact_cache_persist\";\nconst EVENT_PREFLIGHT_REQUIRE_NIX_DENIED = \"preflight-require-nix-denied\";\nconst EVENT_STORE_IDENTITY_FAILED = \"store_identity_failed\";\n\nconst FACT_ARTIFACT_FETCHED_FROM_CACHE = \"artifact_fetched_from_cache\";\nconst FACT_ENDED_WITH_EXCEPTION = \"ended_with_exception\";\nconst FACT_FINAL_EXCEPTION = \"final_exception\";\nconst FACT_OS = \"$os\";\nconst FACT_OS_VERSION = \"$os_version\";\nconst FACT_SOURCE_URL = \"source_url\";\nconst FACT_SOURCE_URL_ETAG = \"source_url_etag\";\nconst FACT_NIX_VERSION = \"nix_version\";\n\nconst FACT_NIX_LOCATION = \"nix_location\";\nconst FACT_NIX_STORE_TRUST = \"nix_store_trusted\";\nconst FACT_NIX_STORE_VERSION = \"nix_store_version\";\nconst FACT_NIX_STORE_CHECK_METHOD = \"nix_store_check_method\";\nconst FACT_NIX_STORE_CHECK_ERROR = \"nix_store_check_error\";\n\nconst STATE_KEY_EXECUTION_PHASE = \"detsys_action_execution_phase\";\nconst STATE_KEY_NIX_NOT_FOUND = \"detsys_action_nix_not_found\";\nconst STATE_NOT_FOUND = \"not-found\";\nconst STATE_KEY_CROSS_PHASE_ID = \"detsys_cross_phase_id\";\nconst STATE_BACKTRACE_START_TIMESTAMP = \"detsys_backtrace_start_timestamp\";\n\nconst DIAGNOSTIC_ENDPOINT_TIMEOUT_MS = 10_000; // 10 seconds in ms\nconst CHECK_IN_ENDPOINT_TIMEOUT_MS = 1_000; // 1 second in ms\nconst PROGRAM_NAME_CRASH_DENY_LIST = [\n \"nix-expr-tests\",\n \"nix-store-tests\",\n \"nix-util-tests\",\n];\n\n/**\n * An enum for describing different \"fetch suffixes\" for i.d.s.\n *\n * - `nix-style` means that system names like `x86_64-linux` and `aarch64-darwin` are used\n * - `gh-env-style` means that names like `X64-Linux` and `ARM64-macOS` are used\n * - `universal` means that the suffix is the static `universal` (for non-system-specific things)\n */\nexport type FetchSuffixStyle = \"nix-style\" | \"gh-env-style\" | \"universal\";\n\n/**\n * GitHub Actions has two possible execution phases: `main` and `post`.\n */\nexport type ExecutionPhase = \"main\" | \"post\";\n\n/**\n * How to handle whether Nix is currently installed on the runner.\n *\n * - `fail` means that the workflow fails if Nix isn't installed\n * - `warn` means that a warning is logged if Nix isn't installed\n * - `ignore` means that Nix will not be checked\n */\nexport type NixRequirementHandling = \"fail\" | \"warn\" | \"ignore\";\n\n/**\n * Whether the Nix store on the runner is trusted.\n *\n * - `trusted` means yes\n * - `untrusted` means no\n * - `unknown` means that the status couldn't be determined\n *\n * This is determined via the output of `nix store info --json`.\n */\nexport type NixStoreTrust = \"trusted\" | \"untrusted\" | \"unknown\";\n\nexport type ActionOptions = {\n // Name of the project generally, and the name of the binary on disk.\n name: string;\n\n // Defaults to `name`, Corresponds to the ProjectHost entry on i.d.s.\n idsProjectName?: string;\n\n // Defaults to `action:`\n eventPrefix?: string;\n\n // The \"architecture\" URL component expected by I.D.S. for the ProjectHost.\n fetchStyle: FetchSuffixStyle;\n\n // IdsToolbox assumes the GitHub Action exposes source overrides, like branch/pr/etc. to be named `source-*`.\n // This prefix adds a fallback name, prefixed by `${legacySourcePrefix}-`.\n // Users who configure legacySourcePrefix will get warnings asking them to change to `source-*`.\n legacySourcePrefix?: string;\n\n // Check if Nix is installed before running this action.\n // If Nix isn't installed, this action will not fail, and will instead do nothing.\n // The action will emit a user-visible warning instructing them to install Nix.\n requireNix: NixRequirementHandling;\n\n // The URL suffix to send diagnostics events to.\n //\n // The final URL is constructed via IDS_HOST/idsProjectName/diagnosticsSuffix.\n //\n // Default: `diagnostics`.\n diagnosticsSuffix?: string;\n\n // Collect backtraces from segfaults and other failures from binaries that start with these names.\n //\n // Default: `[ \"nix\", \"determinate-nixd\", ActionOptions.name ]`.\n binaryNamePrefixes?: string[];\n\n // Do NOT collect backtraces from segfaults and other failures from binaries with exact these names.\n //\n // Default: `[ \"nix-expr-tests\" ]`.\n binaryNamesDenyList?: string[];\n};\n\n/**\n * A confident version of Options, where defaults have been resolved into final values.\n */\nexport type ConfidentActionOptions = {\n name: string;\n idsProjectName: string;\n eventPrefix: string;\n fetchStyle: FetchSuffixStyle;\n legacySourcePrefix?: string;\n requireNix: NixRequirementHandling;\n providedDiagnosticsUrl?: URL;\n binaryNamePrefixes: string[];\n binaryNamesDenyList: string[];\n};\n\n/**\n * An event to send to the diagnostic endpoint of i.d.s.\n */\nexport type DiagnosticEvent = {\n // Note: putting a Map in here won't serialize to json properly.\n // It'll just be {} on serialization.\n name: string;\n distinct_id?: string;\n uuid: UUID;\n timestamp: Date;\n\n properties: Record;\n};\n\nconst determinateStateDir = \"/var/lib/determinate\";\nconst determinateIdentityFile = path.join(determinateStateDir, \"identity.json\");\n\nconst isRoot = os.userInfo().uid === 0;\n\n/** Create the Determinate state directory by escalating via sudo */\nasync function sudoEnsureDeterminateStateDir(): Promise {\n const code = await actionsExec.exec(\"sudo\", [\n \"mkdir\",\n \"-p\",\n determinateStateDir,\n ]);\n\n if (code !== 0) {\n throw new Error(`sudo mkdir -p exit: ${code}`);\n }\n}\n\n/** Ensures the Determinate state directory exists, escalating if necessary */\nasync function ensureDeterminateStateDir(): Promise {\n if (isRoot) {\n await mkdir(determinateStateDir, { recursive: true });\n } else {\n return sudoEnsureDeterminateStateDir();\n }\n}\n\n/** Writes correlation hashes to the Determinate state directory by writing to a `sudo tee` pipe */\nasync function sudoWriteCorrelationHashes(hashes: string): Promise {\n const buffer = Buffer.from(hashes);\n\n const code = await actionsExec.exec(\n \"sudo\",\n [\"tee\", determinateIdentityFile],\n {\n input: buffer,\n\n // Ignore output from tee\n outStream: createWriteStream(\"/dev/null\"),\n },\n );\n\n if (code !== 0) {\n throw new Error(`sudo tee exit: ${code}`);\n }\n}\n\n/** Writes correlation hashes to the Determinate state directory, escalating if necessary */\nasync function writeCorrelationHashes(hashes: string): Promise {\n await ensureDeterminateStateDir();\n\n if (isRoot) {\n await fs.writeFile(determinateIdentityFile, hashes, \"utf-8\");\n } else {\n return sudoWriteCorrelationHashes(hashes);\n }\n}\n\nexport abstract class DetSysAction {\n nixStoreTrust: NixStoreTrust;\n strictMode: boolean;\n\n private actionOptions: ConfidentActionOptions;\n private exceptionAttachments: Map;\n private archOs: string;\n private executionPhase: ExecutionPhase;\n private nixSystem: string;\n private architectureFetchSuffix: string;\n private sourceParameters: SourceDef;\n private facts: Record;\n private events: DiagnosticEvent[];\n private identity: correlation.AnonymizedCorrelationHashes;\n private idsHost: IdsHost;\n private features: { [k: string]: Feature };\n private featureEventMetadata: { [k: string]: string | boolean };\n\n private determineExecutionPhase(): ExecutionPhase {\n const currentPhase = actionsCore.getState(STATE_KEY_EXECUTION_PHASE);\n if (currentPhase === \"\") {\n actionsCore.saveState(STATE_KEY_EXECUTION_PHASE, \"post\");\n return \"main\";\n } else {\n return \"post\";\n }\n }\n\n constructor(actionOptions: ActionOptions) {\n this.actionOptions = makeOptionsConfident(actionOptions);\n this.idsHost = new IdsHost(\n this.actionOptions.idsProjectName,\n actionOptions.diagnosticsSuffix,\n // Note: we don't use actionsCore.getInput('diagnostic-endpoint') on purpose:\n // getInput silently converts absent data to an empty string.\n process.env[\"INPUT_DIAGNOSTIC-ENDPOINT\"],\n );\n this.exceptionAttachments = new Map();\n this.nixStoreTrust = \"unknown\";\n this.strictMode = getBool(\"_internal-strict-mode\");\n\n if (\n getBoolOrUndefined(\n \"_internal-obliterate-actions-id-token-request-variables\",\n ) === true\n ) {\n process.env[\"ACTIONS_ID_TOKEN_REQUEST_URL\"] = undefined;\n process.env[\"ACTIONS_ID_TOKEN_REQUEST_TOKEN\"] = undefined;\n }\n\n this.features = {};\n this.featureEventMetadata = {};\n this.events = [];\n\n this.getCrossPhaseId();\n this.collectBacktraceSetup();\n\n // JSON sent to server\n /* eslint-disable camelcase */\n this.facts = {\n $lib: \"idslib\",\n $lib_version: pkgVersion,\n project: this.actionOptions.name,\n ids_project: this.actionOptions.idsProjectName,\n };\n\n const params = [\n [\"github_action_ref\", \"GITHUB_ACTION_REF\"],\n [\"github_action_repository\", \"GITHUB_ACTION_REPOSITORY\"],\n [\"github_event_name\", \"GITHUB_EVENT_NAME\"],\n [\"$os\", \"RUNNER_OS\"],\n [\"arch\", \"RUNNER_ARCH\"],\n ];\n for (const [target, env] of params) {\n const value = process.env[env];\n if (value) {\n this.facts[target] = value;\n }\n }\n\n this.identity = correlation.identify();\n this.archOs = platform.getArchOs();\n this.nixSystem = platform.getNixPlatform(this.archOs);\n\n this.facts.$app_name = `${this.actionOptions.name}/action`;\n this.facts.arch_os = this.archOs;\n this.facts.nix_system = this.nixSystem;\n\n {\n ghActionsCorePlatform\n .getDetails()\n // eslint-disable-next-line github/no-then\n .then((details) => {\n if (details.name !== \"unknown\") {\n this.addFact(FACT_OS, details.name);\n }\n if (details.version !== \"unknown\") {\n this.addFact(FACT_OS_VERSION, details.version);\n }\n })\n // eslint-disable-next-line github/no-then\n .catch((e: unknown) => {\n actionsCore.debug(\n `Failure getting platform details: ${stringifyError(e)}`,\n );\n });\n }\n\n this.executionPhase = this.determineExecutionPhase();\n this.facts.execution_phase = this.executionPhase;\n\n if (this.actionOptions.fetchStyle === \"gh-env-style\") {\n this.architectureFetchSuffix = this.archOs;\n } else if (this.actionOptions.fetchStyle === \"nix-style\") {\n this.architectureFetchSuffix = this.nixSystem;\n } else if (this.actionOptions.fetchStyle === \"universal\") {\n this.architectureFetchSuffix = \"universal\";\n } else {\n throw new Error(\n `fetchStyle ${this.actionOptions.fetchStyle} is not a valid style`,\n );\n }\n\n this.sourceParameters = constructSourceParameters(\n this.actionOptions.legacySourcePrefix,\n );\n\n this.recordEvent(`begin_${this.executionPhase}`);\n }\n\n /**\n * Attach a file to the diagnostics data in error conditions.\n *\n * The file at `location` doesn't need to exist when stapleFile is called.\n *\n * If the file doesn't exist or is unreadable when trying to staple the attachments, the JS error will be stored in a context value at `staple_failure_{name}`.\n * If the file is readable, the file's contents will be stored in a context value at `staple_value_{name}`.\n */\n stapleFile(name: string, location: string): void {\n this.exceptionAttachments.set(name, location);\n }\n\n /**\n * The main execution phase.\n */\n abstract main(): Promise;\n\n /**\n * The post execution phase.\n */\n abstract post(): Promise;\n\n /**\n * Execute the Action as defined.\n */\n execute(): void {\n // eslint-disable-next-line github/no-then\n this.executeAsync().catch((error: Error) => {\n // eslint-disable-next-line no-console\n console.log(error);\n process.exitCode = 1;\n });\n }\n\n getTemporaryName(): string {\n const tmpDir = process.env[\"RUNNER_TEMP\"] || tmpdir();\n return path.join(tmpDir, `${this.actionOptions.name}-${randomUUID()}`);\n }\n\n addFact(key: string, value: string | boolean | number): void {\n this.facts[key] = value;\n }\n\n async getDiagnosticsUrl(): Promise {\n return await this.idsHost.getDiagnosticsUrl();\n }\n\n getUniqueId(): string {\n return (\n this.identity.github_workflow_run_differentiator_hash ||\n process.env.RUNNER_TRACKING_ID ||\n randomUUID()\n );\n }\n\n // This ID will be saved in the action's state, to be persisted across phase steps\n getCrossPhaseId(): string {\n let crossPhaseId = actionsCore.getState(STATE_KEY_CROSS_PHASE_ID);\n\n if (crossPhaseId === \"\") {\n crossPhaseId = randomUUID();\n actionsCore.saveState(STATE_KEY_CROSS_PHASE_ID, crossPhaseId);\n }\n\n return crossPhaseId;\n }\n\n getCorrelationHashes(): correlation.AnonymizedCorrelationHashes {\n return this.identity;\n }\n\n recordEvent(\n eventName: string,\n context: Record = {},\n ): void {\n const prefixedName =\n eventName === \"$feature_flag_called\"\n ? eventName\n : `${this.actionOptions.eventPrefix}${eventName}`;\n\n this.events.push({\n name: prefixedName,\n\n // Use the anon distinct ID as the distinct ID until we actually have a distinct ID in the future\n distinct_id: this.identity.$anon_distinct_id,\n\n // distinct_id\n uuid: randomUUID(),\n timestamp: new Date(),\n\n properties: {\n ...context,\n ...this.identity,\n ...this.facts,\n ...Object.fromEntries(\n Object.entries(this.featureEventMetadata).map<\n [string, string | boolean]\n >(([name, variant]) => [`$feature/${name}`, variant]),\n ),\n },\n });\n }\n\n /**\n * Unpacks the closure returned by `fetchArtifact()`, imports the\n * contents into the Nix store, and returns the path of the executable at\n * `/nix/store/STORE_PATH/bin/${bin}`.\n */\n async unpackClosure(bin: string): Promise {\n const artifact = await this.fetchArtifact();\n const { stdout } = await promisify(exec)(\n `cat \"${artifact}\" | xz -d | nix-store --import`,\n );\n const paths = stdout.split(os.EOL);\n const lastPath = paths.at(-2);\n return `${lastPath}/bin/${bin}`;\n }\n\n /**\n * Fetches the executable at the URL determined by the `source-*` inputs and\n * other facts, `chmod`s it, and returns the path to the executable on disk.\n */\n async fetchExecutable(timeout?: number): Promise {\n const binaryPath = await this.fetchArtifact(timeout);\n await chmod(binaryPath, fsConstants.S_IXUSR | fsConstants.S_IXGRP);\n return binaryPath;\n }\n\n private get isMain(): boolean {\n return this.executionPhase === \"main\";\n }\n\n private get isPost(): boolean {\n return this.executionPhase === \"post\";\n }\n\n private async executeAsync(): Promise {\n try {\n await this.checkIn();\n\n const correlationHashes = JSON.stringify(this.getCorrelationHashes());\n process.env.DETSYS_CORRELATION = correlationHashes;\n try {\n await writeCorrelationHashes(correlationHashes);\n } catch (error) {\n this.recordEvent(EVENT_STORE_IDENTITY_FAILED, { error: String(error) });\n }\n\n if (!(await this.preflightRequireNix())) {\n this.recordEvent(EVENT_PREFLIGHT_REQUIRE_NIX_DENIED);\n return;\n } else {\n await this.preflightNixStoreInfo();\n await this.preflightNixVersion();\n this.addFact(FACT_NIX_STORE_TRUST, this.nixStoreTrust);\n }\n\n if (this.isMain) {\n await this.main();\n\n // Run the preflight of the nix version a second time so our \"shutdown\" events have updated version info.\n await this.preflightNixVersion();\n } else if (this.isPost) {\n await this.post();\n }\n this.addFact(FACT_ENDED_WITH_EXCEPTION, false);\n } catch (e: unknown) {\n this.addFact(FACT_ENDED_WITH_EXCEPTION, true);\n\n const reportable = stringifyError(e);\n\n this.addFact(FACT_FINAL_EXCEPTION, reportable);\n\n if (this.isPost) {\n actionsCore.warning(reportable);\n } else {\n actionsCore.setFailed(reportable);\n }\n\n const doGzip = promisify(gzip);\n\n const exceptionContext: Map = new Map();\n for (const [attachmentLabel, filePath] of this.exceptionAttachments) {\n try {\n const logText = readFileSync(filePath);\n const buf = await doGzip(logText);\n exceptionContext.set(\n `staple_value_${attachmentLabel}`,\n buf.toString(\"base64\"),\n );\n } catch (innerError: unknown) {\n exceptionContext.set(\n `staple_failure_${attachmentLabel}`,\n stringifyError(innerError),\n );\n }\n }\n\n this.recordEvent(EVENT_EXCEPTION, Object.fromEntries(exceptionContext));\n } finally {\n if (this.isPost) {\n await this.collectBacktraces();\n }\n\n await this.complete();\n }\n }\n\n async getClient(timeout?: number): Promise {\n return await this.idsHost.getGot(\n (incitingError: unknown, prevUrl: URL, nextUrl: URL) => {\n this.recordPlausibleTimeout(incitingError);\n\n this.recordEvent(\"ids-failover\", {\n previousUrl: prevUrl.toString(),\n nextUrl: nextUrl.toString(),\n });\n },\n timeout,\n );\n }\n\n private async checkIn(): Promise {\n const checkin = await this.requestCheckIn();\n if (checkin === undefined) {\n return;\n }\n\n this.features = checkin.options;\n for (const [key, feature] of Object.entries(this.features)) {\n this.featureEventMetadata[key] = feature.variant;\n }\n\n const impactSymbol: Map = new Map([\n [\"none\", \"⚪\"],\n [\"maintenance\", \"🛠️\"],\n [\"minor\", \"🟡\"],\n [\"major\", \"🟠\"],\n [\"critical\", \"🔴\"],\n ]);\n const defaultImpactSymbol = \"🔵\";\n\n if (checkin.status !== null) {\n const summaries: string[] = [];\n\n for (const incident of checkin.status.incidents) {\n summaries.push(\n `${impactSymbol.get(incident.impact) || defaultImpactSymbol} ${incident.status.replace(\"_\", \" \")}: ${incident.name} (${incident.shortlink})`,\n );\n }\n\n for (const maintenance of checkin.status.scheduled_maintenances) {\n summaries.push(\n `${impactSymbol.get(maintenance.impact) || defaultImpactSymbol} ${maintenance.status.replace(\"_\", \" \")}: ${maintenance.name} (${maintenance.shortlink})`,\n );\n }\n\n if (summaries.length > 0) {\n actionsCore.info(\n // Bright red, Bold, Underline\n `${\"\\u001b[0;31m\"}${\"\\u001b[1m\"}${\"\\u001b[4m\"}${checkin.status.page.name} Status`,\n );\n for (const notice of summaries) {\n actionsCore.info(notice);\n }\n actionsCore.info(`See: ${checkin.status.page.url}`);\n actionsCore.info(``);\n }\n }\n }\n\n getFeature(name: string): Feature | undefined {\n if (!this.features.hasOwnProperty(name)) {\n return undefined;\n }\n\n const result = this.features[name];\n if (result === undefined) {\n return undefined;\n }\n\n this.recordEvent(\"$feature_flag_called\", {\n $feature_flag: name,\n $feature_flag_response: result.variant,\n });\n\n return result;\n }\n\n /**\n * Check in to install.determinate.systems, to accomplish three things:\n *\n * 1. Preflight the server selected from IdsHost, to increase the chances of success.\n * 2. Fetch any incidents and maintenance events to let users know in case things are weird.\n * 3. Get feature flag data so we can gently roll out new features.\n */\n private async requestCheckIn(): Promise {\n for (\n let attemptsRemaining = 5;\n attemptsRemaining > 0;\n attemptsRemaining--\n ) {\n const checkInUrl = await this.getCheckInUrl();\n if (checkInUrl === undefined) {\n return undefined;\n }\n\n try {\n actionsCore.debug(`Preflighting via ${checkInUrl}`);\n\n const props = {\n // Use a distinct_id when we actually have one\n distinct_id: this.identity.$anon_distinct_id,\n anon_distinct_id: this.identity.$anon_distinct_id,\n groups: this.identity.$groups,\n person_properties: {\n ci: \"github\",\n\n ...this.identity,\n ...this.facts,\n },\n };\n\n return await (\n await this.getClient()\n )\n .post(checkInUrl, {\n json: props,\n timeout: {\n request: CHECK_IN_ENDPOINT_TIMEOUT_MS,\n },\n })\n .json();\n } catch (e: unknown) {\n this.recordPlausibleTimeout(e);\n actionsCore.debug(`Error checking in: ${stringifyError(e)}`);\n this.idsHost.markCurrentHostBroken();\n }\n }\n\n return undefined;\n }\n\n private recordPlausibleTimeout(e: unknown): void {\n // see: https://github.com/sindresorhus/got/blob/895e463fa699d6f2e4b2fc01ceb3b2bb9e157f4c/documentation/8-errors.md\n if (e instanceof TimeoutError && \"timings\" in e && \"request\" in e) {\n const reportContext: {\n [index: string]: string | number | undefined;\n } = {\n url: e.request.requestUrl?.toString(),\n retry_count: e.request.retryCount,\n };\n\n for (const [key, value] of Object.entries(e.timings.phases)) {\n if (Number.isFinite(value)) {\n reportContext[`timing_phase_${key}`] = value;\n }\n }\n\n this.recordEvent(\"timeout\", reportContext);\n }\n }\n\n /**\n * Fetch an artifact, such as a tarball, from the location determined by the\n * `source-*` inputs. If `source-binary` is specified, this will return a path\n * to a binary on disk; otherwise, the artifact will be downloaded from the\n * URL determined by the other `source-*` inputs (`source-url`, `source-pr`,\n * etc.).\n */\n private async fetchArtifact(timeout?: number): Promise {\n const sourceBinary = getStringOrNull(\"source-binary\");\n\n // If source-binary is set, use that. Otherwise fall back to the source-* parameters.\n if (sourceBinary !== null && sourceBinary !== \"\") {\n actionsCore.debug(`Using the provided source binary at ${sourceBinary}`);\n return sourceBinary;\n }\n\n actionsCore.startGroup(\n `Downloading ${this.actionOptions.name} for ${this.architectureFetchSuffix}`,\n );\n\n try {\n actionsCore.info(`Fetching from ${await this.getSourceUrl()}`);\n\n const correlatedUrl = await this.getSourceUrl();\n correlatedUrl.searchParams.set(\"ci\", \"github\");\n correlatedUrl.searchParams.set(\n \"correlation\",\n JSON.stringify(this.identity),\n );\n\n const versionCheckup = await (\n await this.getClient(timeout)\n ).head(correlatedUrl);\n if (versionCheckup.headers.etag) {\n const v = versionCheckup.headers.etag;\n this.addFact(FACT_SOURCE_URL_ETAG, v);\n\n actionsCore.debug(\n `Checking the tool cache for ${await this.getSourceUrl()} at ${v}`,\n );\n const cached = await this.getCachedVersion(v);\n if (cached) {\n this.facts[FACT_ARTIFACT_FETCHED_FROM_CACHE] = true;\n actionsCore.debug(`Tool cache hit.`);\n return cached;\n }\n }\n\n this.facts[FACT_ARTIFACT_FETCHED_FROM_CACHE] = false;\n\n actionsCore.debug(\n `No match from the cache, re-fetching from the redirect: ${versionCheckup.url}`,\n );\n\n const destFile = this.getTemporaryName();\n\n const fetchStream = await this.downloadFile(\n new URL(versionCheckup.url),\n destFile,\n timeout,\n );\n\n if (fetchStream.response?.headers.etag) {\n const v = fetchStream.response.headers.etag;\n\n try {\n await this.saveCachedVersion(v, destFile);\n } catch (e: unknown) {\n actionsCore.debug(`Error caching the artifact: ${stringifyError(e)}`);\n }\n }\n\n return destFile;\n } catch (e: unknown) {\n this.recordPlausibleTimeout(e);\n throw e;\n } finally {\n actionsCore.endGroup();\n }\n }\n\n /**\n * A helper function for failing on error only if strict mode is enabled.\n * This is intended only for CI environments testing Actions themselves.\n */\n failOnError(msg: string): void {\n if (this.strictMode) {\n actionsCore.setFailed(`strict mode failure: ${msg}`);\n }\n }\n\n private async downloadFile(\n url: URL,\n destination: PathLike,\n timeout?: number,\n ): Promise {\n const client = await this.getClient(timeout);\n\n return new Promise((resolve, reject) => {\n // Current stream handle\n let writeStream: WriteStream | undefined;\n\n // Sentinel condition in case we want to abort retrying due to FS issues\n let failed = false;\n\n const retry = (stream: Request): void => {\n if (writeStream) {\n writeStream.destroy();\n }\n\n writeStream = createWriteStream(destination, {\n encoding: \"binary\",\n mode: 0o755,\n });\n\n writeStream.once(\"error\", (error) => {\n // Set failed here since promise rejections don't impact control flow\n failed = true;\n reject(error);\n });\n\n writeStream.on(\"finish\", () => {\n if (!failed) {\n resolve(stream);\n }\n });\n\n stream.once(\"retry\", (_count, _error, createRetryStream) => {\n // Optional: check `failed' here in case you want to stop retrying\n retry(createRetryStream());\n });\n\n // Now that all the handlers have been set up we can pipe from the HTTP\n // stream to disk\n stream.pipe(writeStream);\n };\n\n // Begin the retry logic by giving it a fresh got.Request\n retry(client.stream(url));\n });\n }\n\n private async complete(): Promise {\n this.recordEvent(`complete_${this.executionPhase}`);\n await this.submitEvents();\n }\n\n private async getCheckInUrl(): Promise {\n const checkInUrl = await this.idsHost.getDynamicRootUrl();\n\n if (checkInUrl === undefined) {\n return undefined;\n }\n\n checkInUrl.pathname += \"check-in\";\n return checkInUrl;\n }\n\n private async getSourceUrl(): Promise {\n const p = this.sourceParameters;\n\n if (p.url) {\n this.addFact(FACT_SOURCE_URL, p.url);\n return new URL(p.url);\n }\n\n const fetchUrl = await this.idsHost.getRootUrl();\n fetchUrl.pathname += this.actionOptions.idsProjectName;\n\n if (p.tag) {\n fetchUrl.pathname += `/tag/${p.tag}`;\n } else if (p.pr) {\n fetchUrl.pathname += `/pr/${p.pr}`;\n } else if (p.branch) {\n fetchUrl.pathname += `/branch/${p.branch}`;\n } else if (p.revision) {\n fetchUrl.pathname += `/rev/${p.revision}`;\n } else {\n fetchUrl.pathname += `/stable`;\n }\n\n fetchUrl.pathname += `/${this.architectureFetchSuffix}`;\n\n this.addFact(FACT_SOURCE_URL, fetchUrl.toString());\n\n return fetchUrl;\n }\n\n private cacheKey(version: string): string {\n const cleanedVersion = version.replace(/[^a-zA-Z0-9-+.]/g, \"\");\n return `determinatesystem-${this.actionOptions.name}-${this.architectureFetchSuffix}-${cleanedVersion}`;\n }\n\n private async getCachedVersion(version: string): Promise {\n const startCwd = process.cwd();\n\n try {\n const tempDir = this.getTemporaryName();\n await mkdir(tempDir);\n process.chdir(tempDir);\n\n // extremely evil shit right here:\n process.env.GITHUB_WORKSPACE_BACKUP = process.env.GITHUB_WORKSPACE;\n delete process.env.GITHUB_WORKSPACE;\n\n if (\n await actionsCache.restoreCache(\n [this.actionOptions.name],\n this.cacheKey(version),\n [],\n undefined,\n true,\n )\n ) {\n this.recordEvent(EVENT_ARTIFACT_CACHE_HIT);\n return `${tempDir}/${this.actionOptions.name}`;\n }\n\n this.recordEvent(EVENT_ARTIFACT_CACHE_MISS);\n return undefined;\n } finally {\n process.env.GITHUB_WORKSPACE = process.env.GITHUB_WORKSPACE_BACKUP;\n delete process.env.GITHUB_WORKSPACE_BACKUP;\n process.chdir(startCwd);\n }\n }\n\n private async saveCachedVersion(\n version: string,\n toolPath: string,\n ): Promise {\n const startCwd = process.cwd();\n\n try {\n const tempDir = this.getTemporaryName();\n await mkdir(tempDir);\n process.chdir(tempDir);\n await copyFile(toolPath, `${tempDir}/${this.actionOptions.name}`);\n\n // extremely evil shit right here:\n process.env.GITHUB_WORKSPACE_BACKUP = process.env.GITHUB_WORKSPACE;\n delete process.env.GITHUB_WORKSPACE;\n\n await actionsCache.saveCache(\n [this.actionOptions.name],\n this.cacheKey(version),\n undefined,\n true,\n );\n this.recordEvent(EVENT_ARTIFACT_CACHE_PERSIST);\n } finally {\n process.env.GITHUB_WORKSPACE = process.env.GITHUB_WORKSPACE_BACKUP;\n delete process.env.GITHUB_WORKSPACE_BACKUP;\n process.chdir(startCwd);\n }\n }\n\n private collectBacktraceSetup(): void {\n if (!process.env.DETSYS_BACKTRACE_COLLECTOR) {\n actionsCore.exportVariable(\n \"DETSYS_BACKTRACE_COLLECTOR\",\n this.getCrossPhaseId(),\n );\n\n actionsCore.saveState(STATE_BACKTRACE_START_TIMESTAMP, Date.now());\n }\n }\n\n private async collectBacktraces(): Promise {\n try {\n if (process.env.DETSYS_BACKTRACE_COLLECTOR !== this.getCrossPhaseId()) {\n return;\n }\n\n const backtraces = await collectBacktraces(\n this.actionOptions.binaryNamePrefixes,\n this.actionOptions.binaryNamesDenyList,\n parseInt(actionsCore.getState(STATE_BACKTRACE_START_TIMESTAMP)),\n );\n actionsCore.debug(`Backtraces identified: ${backtraces.size}`);\n if (backtraces.size > 0) {\n this.recordEvent(EVENT_BACKTRACES, Object.fromEntries(backtraces));\n }\n } catch (innerError: unknown) {\n actionsCore.debug(\n `Error collecting backtraces: ${stringifyError(innerError)}`,\n );\n }\n }\n\n private async preflightRequireNix(): Promise {\n let nixLocation: string | undefined;\n\n const pathParts = (process.env[\"PATH\"] || \"\").split(\":\");\n for (const location of pathParts) {\n const candidateNix = path.join(location, \"nix\");\n\n try {\n await fs.access(candidateNix, fs.constants.X_OK);\n actionsCore.debug(`Found Nix at ${candidateNix}`);\n nixLocation = candidateNix;\n break;\n } catch {\n actionsCore.debug(`Nix not at ${candidateNix}`);\n }\n }\n this.addFact(FACT_NIX_LOCATION, nixLocation || \"\");\n\n if (this.actionOptions.requireNix === \"ignore\") {\n return true;\n }\n\n const currentNotFoundState = actionsCore.getState(STATE_KEY_NIX_NOT_FOUND);\n if (currentNotFoundState === STATE_NOT_FOUND) {\n // It was previously not found, so don't run subsequent actions\n return false;\n }\n\n if (nixLocation !== undefined) {\n return true;\n }\n actionsCore.saveState(STATE_KEY_NIX_NOT_FOUND, STATE_NOT_FOUND);\n\n switch (this.actionOptions.requireNix) {\n case \"fail\":\n actionsCore.setFailed(\n [\n \"This action can only be used when Nix is installed.\",\n \"Add `- uses: DeterminateSystems/determinate-nix-action@v3` earlier in your workflow.\",\n ].join(\" \"),\n );\n break;\n case \"warn\":\n actionsCore.warning(\n [\n \"This action is in no-op mode because Nix is not installed.\",\n \"Add `- uses: DeterminateSystems/determinate-nix-action@v3` earlier in your workflow.\",\n ].join(\" \"),\n );\n break;\n }\n\n return false;\n }\n\n private async preflightNixStoreInfo(): Promise {\n let output = \"\";\n\n const options: actionsExec.ExecOptions = {};\n options.silent = true;\n options.listeners = {\n stdout: (data) => {\n output += data.toString();\n },\n };\n\n try {\n output = \"\";\n await actionsExec.exec(\"nix\", [\"store\", \"info\", \"--json\"], options);\n this.addFact(FACT_NIX_STORE_CHECK_METHOD, \"info\");\n } catch {\n try {\n // reset output\n output = \"\";\n await actionsExec.exec(\"nix\", [\"store\", \"ping\", \"--json\"], options);\n this.addFact(FACT_NIX_STORE_CHECK_METHOD, \"ping\");\n } catch {\n this.addFact(FACT_NIX_STORE_CHECK_METHOD, \"none\");\n return;\n }\n }\n\n try {\n const parsed = JSON.parse(output);\n if (parsed.trusted === 1) {\n this.nixStoreTrust = \"trusted\";\n } else if (parsed.trusted === 0) {\n this.nixStoreTrust = \"untrusted\";\n } else if (parsed.trusted !== undefined) {\n this.addFact(\n FACT_NIX_STORE_CHECK_ERROR,\n `Mysterious trusted value: ${JSON.stringify(parsed.trusted)}`,\n );\n }\n\n this.addFact(FACT_NIX_STORE_VERSION, JSON.stringify(parsed.version));\n } catch (e: unknown) {\n this.addFact(FACT_NIX_STORE_CHECK_ERROR, stringifyError(e));\n }\n }\n\n private async preflightNixVersion(): Promise {\n let output = \"unknown\";\n\n try {\n ({ stdout: output } = await actionsExec.getExecOutput(\n \"nix\",\n [\"--version\"],\n {\n silent: true,\n },\n ));\n output = output.trim() || \"unknown\";\n } catch {\n // That's fine.\n }\n\n this.addFact(FACT_NIX_VERSION, output);\n }\n\n private async submitEvents(): Promise {\n const diagnosticsUrl = await this.idsHost.getDiagnosticsUrl();\n if (diagnosticsUrl === undefined) {\n actionsCore.debug(\n \"Diagnostics are disabled. Not sending the following events:\",\n );\n actionsCore.debug(JSON.stringify(this.events, undefined, 2));\n return;\n }\n\n const batch = {\n sent_at: new Date(),\n batch: this.events,\n };\n\n try {\n await (\n await this.getClient()\n ).post(diagnosticsUrl, {\n json: batch,\n timeout: {\n request: DIAGNOSTIC_ENDPOINT_TIMEOUT_MS,\n },\n });\n } catch (err: unknown) {\n this.recordPlausibleTimeout(err);\n\n actionsCore.debug(\n `Error submitting diagnostics event to ${diagnosticsUrl}: ${stringifyError(err)}`,\n );\n }\n this.events = [];\n }\n}\n\nfunction stringifyError(error: unknown): string {\n return error instanceof Error || typeof error == \"string\"\n ? error.toString()\n : JSON.stringify(error);\n}\n\nfunction makeOptionsConfident(\n actionOptions: ActionOptions,\n): ConfidentActionOptions {\n const idsProjectName = actionOptions.idsProjectName ?? actionOptions.name;\n\n const finalOpts: ConfidentActionOptions = {\n name: actionOptions.name,\n idsProjectName,\n eventPrefix: actionOptions.eventPrefix || \"action:\",\n fetchStyle: actionOptions.fetchStyle,\n legacySourcePrefix: actionOptions.legacySourcePrefix,\n requireNix: actionOptions.requireNix,\n binaryNamePrefixes: actionOptions.binaryNamePrefixes ?? [\n \"nix\",\n \"determinate-nixd\",\n actionOptions.name,\n ],\n binaryNamesDenyList:\n actionOptions.binaryNamePrefixes ?? PROGRAM_NAME_CRASH_DENY_LIST,\n };\n\n actionsCore.debug(\"idslib options:\");\n actionsCore.debug(JSON.stringify(finalOpts, undefined, 2));\n\n return finalOpts;\n}\n\n// Public exports from other files\nexport type {\n CheckIn,\n Feature,\n Incident,\n Maintenance,\n Page,\n StatusSummary,\n} from \"./check-in.js\";\nexport type { AnonymizedCorrelationHashes } from \"./correlation.js\";\nexport { stringifyError } from \"./errors.js\";\nexport { IdsHost } from \"./ids-host.js\";\nexport type { SourceDef } from \"./sourcedef.js\";\nexport * as inputs from \"./inputs.js\";\nexport * as platform from \"./platform.js\";\n"],"mappings":"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"} \ No newline at end of file diff --git a/src/ids-host.ts b/src/ids-host.ts index d44d305..289af7a 100644 --- a/src/ids-host.ts +++ b/src/ids-host.ts @@ -46,11 +46,12 @@ export class IdsHost { prevUrl: URL, nextUrl: URL, ) => void, + timeout?: number, ): Promise { if (this.client === undefined) { this.client = got.extend({ timeout: { - request: DEFAULT_TIMEOUT, + request: timeout ?? DEFAULT_TIMEOUT, }, retry: { diff --git a/src/index.ts b/src/index.ts index ff14a38..6b425dc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -486,8 +486,8 @@ export abstract class DetSysAction { * Fetches the executable at the URL determined by the `source-*` inputs and * other facts, `chmod`s it, and returns the path to the executable on disk. */ - async fetchExecutable(): Promise { - const binaryPath = await this.fetchArtifact(); + async fetchExecutable(timeout?: number): Promise { + const binaryPath = await this.fetchArtifact(timeout); await chmod(binaryPath, fsConstants.S_IXUSR | fsConstants.S_IXGRP); return binaryPath; } @@ -572,7 +572,7 @@ export abstract class DetSysAction { } } - async getClient(): Promise { + async getClient(timeout?: number): Promise { return await this.idsHost.getGot( (incitingError: unknown, prevUrl: URL, nextUrl: URL) => { this.recordPlausibleTimeout(incitingError); @@ -582,6 +582,7 @@ export abstract class DetSysAction { nextUrl: nextUrl.toString(), }); }, + timeout, ); } @@ -733,7 +734,7 @@ export abstract class DetSysAction { * URL determined by the other `source-*` inputs (`source-url`, `source-pr`, * etc.). */ - private async fetchArtifact(): Promise { + private async fetchArtifact(timeout?: number): Promise { const sourceBinary = getStringOrNull("source-binary"); // If source-binary is set, use that. Otherwise fall back to the source-* parameters. @@ -756,7 +757,9 @@ export abstract class DetSysAction { JSON.stringify(this.identity), ); - const versionCheckup = await (await this.getClient()).head(correlatedUrl); + const versionCheckup = await ( + await this.getClient(timeout) + ).head(correlatedUrl); if (versionCheckup.headers.etag) { const v = versionCheckup.headers.etag; this.addFact(FACT_SOURCE_URL_ETAG, v); @@ -783,6 +786,7 @@ export abstract class DetSysAction { const fetchStream = await this.downloadFile( new URL(versionCheckup.url), destFile, + timeout, ); if (fetchStream.response?.headers.etag) { @@ -817,8 +821,9 @@ export abstract class DetSysAction { private async downloadFile( url: URL, destination: PathLike, + timeout?: number, ): Promise { - const client = await this.getClient(); + const client = await this.getClient(timeout); return new Promise((resolve, reject) => { // Current stream handle