diff --git a/action.yml b/action.yml index 733eb58..c594df5 100644 --- a/action.yml +++ b/action.yml @@ -20,6 +20,10 @@ inputs: description: 'The maximum permitted size of the global Zig cache directory, in MiB. When the cache directory exceeds this size, it is cleared. Default is 2048 (2 GiB). 0 means no limit.' required: true default: 2048 + use-tool-cache: + description: 'Override whether to use the tool cache when caching Zig installations. Default is false for GitHub-hosted runners, true for other runners.' + required: false + default: '' runs: using: 'node20' main: 'main.js' diff --git a/common.js b/common.js index e7500a2..f6e6a4b 100644 --- a/common.js +++ b/common.js @@ -32,7 +32,7 @@ async function getVersion() { return _cached_version; } - // Else, look for `mach_zig_version` first + // Else, look for `minimum_zig_version` match = MINIMUM_ZIG_VERSION_REGEX.exec(zon); if (match !== null) { _cached_version = match[1]; diff --git a/main.js b/main.js index 1070718..869cafc 100644 --- a/main.js +++ b/main.js @@ -91,16 +91,41 @@ async function main() { // * 'cache' only caches the unextracted archive, but it does so across runs. It's a little // less efficient, but still much preferable to fetching Zig from a mirror. We have this // dependency anyway for caching the global Zig cache. + // + // Unfortunately, tool-cache can lead to serious performance problems on GitHub-hosted Actions + // runners -- or their Windows ones at least, because the tool cache is stored on a slow drive. + // There are even hacky workarounds for this in official Actions: + // + // https://github.com/actions/setup-go/blob/d35c59abb061a4a6fb18e82ac0862c26744d6ab5/src/installer.ts#L174 + // + // Since tool-cache is only really useful on self-hosted runners, let's just disable it by + // default on GitHub-hosted runners, and hence execute Zig straight out of its extracted dir. + let use_tool_cache = core.getInput('use-tool-cache'); + if (use_tool_cache === 'true') { + use_tool_cache = true; + } else if (use_tool_cache === 'false') { + use_tool_cache = false; + } else if (use_tool_cache === '') { + use_tool_cache = process.env['RUNNER_ENVIRONMENT'] !== 'github-hosted'; + } else { + throw new Error("Invalid 'use-tool-cache' value. Valid values: 'true', 'false'"); + } + core.info(`Using tool-cache: ${use_tool_cache}`); - let zig_dir = tc.find('zig', await common.getVersion()); - if (!zig_dir) { + let zig_dir; + if (use_tool_cache) { + zig_dir = tc.find('zig', await common.getVersion()); + } + if (zig_dir) { + core.info('Using cached Zig installation from tool-cache'); + } else { const tarball_name = await common.getTarballName(); const tarball_ext = await common.getTarballExt(); core.info(`Fetching ${tarball_name}${tarball_ext}`); const fetch_start = Date.now(); const tarball_path = await retrieveTarball(tarball_name, tarball_ext); - core.info(`fetch took ${Date.now() - fetch_start} ms`); + core.info(`Fetch took ${Date.now() - fetch_start} ms`); core.info(`Extracting tarball ${tarball_name}${tarball_ext}`); @@ -108,10 +133,15 @@ async function main() { const zig_parent_dir = tarball_ext === '.zip' ? await tc.extractZip(tarball_path) : await tc.extractTar(tarball_path, null, 'xJ'); // J for xz - core.info(`extract took ${Date.now() - extract_start} ms`); + core.info(`Extract took ${Date.now() - extract_start} ms`); const zig_inner_dir = path.join(zig_parent_dir, tarball_name); - zig_dir = await tc.cacheDir(zig_inner_dir, 'zig', await common.getVersion()); + if (use_tool_cache) { + core.info('Copying Zig installation to tool-cache'); + zig_dir = await tc.cacheDir(zig_inner_dir, 'zig', await common.getVersion()); + } else { + zig_dir = zig_inner_dir; + } } core.addPath(zig_dir); @@ -120,6 +150,7 @@ async function main() { core.exportVariable('ZIG_LOCAL_CACHE_DIR', await common.getZigCachePath()); if (core.getBooleanInput('use-cache')) { + core.info('Attempting restore of Zig cache'); await cache.restoreCache([await common.getZigCachePath()], await common.getCachePrefix()); } } catch (err) { diff --git a/post.js b/post.js index 686323b..563a17b 100644 --- a/post.js +++ b/post.js @@ -18,6 +18,7 @@ async function main() { } if (accessible) { + core.info('Checking cache size'); const size = await totalSize(cache_path); const size_limit = core.getInput('cache-size-limit') * 1024 * 1024; // MiB -> bytes if (size_limit !== 0 && size > size_limit) { @@ -26,10 +27,13 @@ async function main() { // remove the old cache entries, so we instead want to save an empty cache directory. // To do this, delete all the contents of the cache directory before saving the cache. await rmDirContents(cache_path); + } else { + core.info(`Cache directory is ${size} bytes, below limit of ${size_limit} bytes; keeping intact`); } const prefix = await common.getCachePrefix(); const name = prefix + github.context.runId; + core.info('Saving Zig cache'); await cache.saveCache([cache_path], name); } }