From f18d7be1e2d9d80d65f26850fb340075d4fc2054 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Wed, 5 Aug 2026 03:05:04 -0400 Subject: [PATCH] Fix two crashes the first live run exposed `requireEnv` validates a list and returns nothing; two reports called it as a getter and assigned its result, so the key stability check died before reading a single key and the cache value report would have died after collecting all of its samples. `@actions/cache` publishes an `exports` map with no "." entry, so requiring it by package name throws ERR_PACKAGE_PATH_NOT_EXPORTED and every cache save slot failed. Resolve its manifest and require what `main` points at instead, which goes around the map and keeps working across the versions different setup-java refs pin. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71c45320-1417-4029-8402-69075d61dac1 --- scripts/cache-save.sh | 54 ++++++++++++++++++++++++++++++++-- scripts/check-cache-keys.mjs | 8 ++--- scripts/report-cache-value.mjs | 17 +++++++---- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/scripts/cache-save.sh b/scripts/cache-save.sh index 4b3cbff..5277a7a 100755 --- a/scripts/cache-save.sh +++ b/scripts/cache-save.sh @@ -215,9 +215,34 @@ NODE node --input-type=module - "$PWD/$arm_dir/package.json" <<'NODE' import { createRequire } from "node:module"; +// `@actions/cache` publishes an `exports` map with no "." entry, so requiring it +// by package name fails outright. Resolving its manifest and requiring the file +// its `main` points at goes around the map, and keeps working whichever version +// a given setup-java ref happens to pin. +function loadCacheClient(require, manifest) { + const { readFileSync } = require("node:fs"); + const { dirname, join } = require("node:path"); + let manifestPath; + try { + manifestPath = require.resolve("@actions/cache/package.json"); + } catch { + // Some versions do not expose "./package.json" through the map either, in + // which case the install layout is the only thing left to go on. + manifestPath = join( + dirname(manifest), + "node_modules", + "@actions", + "cache", + "package.json", + ); + } + const manifest = JSON.parse(readFileSync(manifestPath, "utf8")); + return require(join(dirname(manifestPath), manifest.main ?? "lib/cache.js")); +} + const [manifest] = process.argv.slice(2); const require = createRequire(manifest); -require.resolve("@actions/cache"); +loadCacheClient(require, manifest); NODE ;; save) @@ -236,10 +261,35 @@ NODE import { createRequire } from "node:module"; import { pathToFileURL } from "node:url"; +// `@actions/cache` publishes an `exports` map with no "." entry, so requiring it +// by package name fails outright. Resolving its manifest and requiring the file +// its `main` points at goes around the map, and keeps working whichever version +// a given setup-java ref happens to pin. +function loadCacheClient(require, manifest) { + const { readFileSync } = require("node:fs"); + const { dirname, join } = require("node:path"); + let manifestPath; + try { + manifestPath = require.resolve("@actions/cache/package.json"); + } catch { + // Some versions do not expose "./package.json" through the map either, in + // which case the install layout is the only thing left to go on. + manifestPath = join( + dirname(manifest), + "node_modules", + "@actions", + "cache", + "package.json", + ); + } + const manifest = JSON.parse(readFileSync(manifestPath, "utf8")); + return require(join(dirname(manifestPath), manifest.main ?? "lib/cache.js")); +} + const [manifest, fixtureDir, key, resultsFile, sample, arm, slot] = process.argv.slice(2); const require = createRequire(manifest); -const cache = require("@actions/cache"); +const cache = loadCacheClient(require, manifest); const started = Date.now(); const cacheId = await cache.saveCache([fixtureDir], key); diff --git a/scripts/check-cache-keys.mjs b/scripts/check-cache-keys.mjs index 5da4288..53c2293 100644 --- a/scripts/check-cache-keys.mjs +++ b/scripts/check-cache-keys.mjs @@ -218,11 +218,11 @@ export function markdown(metadata, result) { } export async function main(env = process.env) { - const runId = requireEnv(env, "GITHUB_RUN_ID"); + requireEnv(env, ["GITHUB_RUN_ID", "SETUP_JAVA_REPOSITORY", "SETUP_JAVA_REF"]); const metadata = { - runId, - setupJavaRepository: requireEnv(env, "SETUP_JAVA_REPOSITORY"), - setupJavaRef: requireEnv(env, "SETUP_JAVA_REF"), + runId: env.GITHUB_RUN_ID, + setupJavaRepository: env.SETUP_JAVA_REPOSITORY, + setupJavaRef: env.SETUP_JAVA_REF, generatedAt: new Date().toISOString(), }; const rows = parseKeys(await readKeyFiles()); diff --git a/scripts/report-cache-value.mjs b/scripts/report-cache-value.mjs index 11af807..a116313 100644 --- a/scripts/report-cache-value.mjs +++ b/scripts/report-cache-value.mjs @@ -133,11 +133,18 @@ export function markdown(metadata, analysis, caches) { } export async function main(env = process.env) { - const token = requireEnv(env, "GH_TOKEN"); - const runId = requireEnv(env, "GITHUB_RUN_ID"); - const setupJavaRepository = requireEnv(env, "SETUP_JAVA_REPOSITORY"); - const setupJavaRef = requireEnv(env, "SETUP_JAVA_REF"); - const [owner, repo] = requireEnv(env, "GITHUB_REPOSITORY").split("/"); + requireEnv(env, [ + "GH_TOKEN", + "GITHUB_RUN_ID", + "SETUP_JAVA_REPOSITORY", + "SETUP_JAVA_REF", + "GITHUB_REPOSITORY", + ]); + const token = env.GH_TOKEN; + const runId = env.GITHUB_RUN_ID; + const setupJavaRepository = env.SETUP_JAVA_REPOSITORY; + const setupJavaRef = env.SETUP_JAVA_REF; + const [owner, repo] = env.GITHUB_REPOSITORY.split("/"); if (!owner || !repo) { throw new Error( `GITHUB_REPOSITORY must be owner/repo, got "${env.GITHUB_REPOSITORY}"`,