From 825a3d6e2cde7889594bf53e491f568deae0029f Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Thu, 26 Mar 2026 15:31:00 -0400 Subject: [PATCH 1/3] fix: migrate to esm module In order to use dependencies that are esm modules (which `@actions/*` just did), we have to be an esm module ourselves. Note that this doesn't work yet; esm modules break jest's mocking. This'll be addressed in future commits. --- jest.config.js | 23 +++++++++++++++++++++++ jest.config.ts | 13 ------------- package.json | 3 ++- src/dirty-files.test.ts | 4 +++- src/envsubst.test.ts | 4 +++- src/get-cache-keys.test.ts | 4 +++- src/hie.ts | 2 +- src/inputs.ts | 4 ++-- src/main.ts | 16 ++++++++-------- src/parse-stack-path.test.ts | 4 +++- src/parse-stack-query.test.ts | 4 +++- src/stack-cli.test.ts | 3 ++- src/stack-cli.ts | 8 ++++---- src/stack-yaml.test.ts | 6 ++++-- src/stack-yaml.ts | 2 +- src/with-cache.test.ts | 5 +++-- src/with-cache.ts | 2 +- tsconfig.json | 4 +++- 18 files changed, 69 insertions(+), 42 deletions(-) create mode 100644 jest.config.js delete mode 100644 jest.config.ts diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..9a75e12 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,23 @@ +import { createDefaultPreset } from "ts-jest"; + +const presetConfig = createDefaultPreset(); + +const jestConfig = { + ...presetConfig, + resetMocks: true, + testEnvironment: "node", + extensionsToTreatAsEsm: [".ts"], + moduleNameMapper: { + "^(\\.{1,2}/.*)\\.js$": "$1", + }, + transform: { + "^.+\\.ts$": [ + "ts-jest", + { + useESM: true, + }, + ], + }, +}; + +export default jestConfig; diff --git a/jest.config.ts b/jest.config.ts deleted file mode 100644 index b0ac37e..0000000 --- a/jest.config.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { createDefaultPreset, type JestConfigWithTsJest } from "ts-jest"; - -const presetConfig = createDefaultPreset({ - isolatedModules: true, -}); - -const jestConfig: JestConfigWithTsJest = { - ...presetConfig, - resetMocks: true, - testEnvironment: "node", -}; - -export default jestConfig; diff --git a/package.json b/package.json index 25d905d..d380268 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { "name": "stack-action", "version": "0.0.0", + "type": "module", "description": "Build and test stack-based Haskell projects", "main": "lib/main.js", "scripts": { "build": "tsc && ncc build lib/main.js && sed -i 's/\\x0D$//' ./dist/index.js", "format": "prettier --write \"**/*.ts\"", "format-check": "prettier --check \"**/*.ts\"", - "test": "jest", + "test": "NODE_OPTIONS='--experimental-vm-modules' jest", "readme": "npx action-docs -u && prettier --write README.md" }, "repository": { diff --git a/src/dirty-files.test.ts b/src/dirty-files.test.ts index fad91fb..32a67fb 100644 --- a/src/dirty-files.test.ts +++ b/src/dirty-files.test.ts @@ -1,4 +1,6 @@ -import { parseGitStatus, isInterestingFile } from "./dirty-files"; +import { jest } from "@jest/globals"; + +import { parseGitStatus, isInterestingFile } from "./dirty-files.js"; describe("parseGitStatus", () => { test("parse file name, and filters untracked", () => { diff --git a/src/envsubst.test.ts b/src/envsubst.test.ts index 3f842d4..472ebf1 100644 --- a/src/envsubst.test.ts +++ b/src/envsubst.test.ts @@ -1,4 +1,6 @@ -import { envsubst } from "./envsubst"; +import { jest } from "@jest/globals"; + +import { envsubst } from "./envsubst.js"; const HOME = process.env.HOME; diff --git a/src/get-cache-keys.test.ts b/src/get-cache-keys.test.ts index 24731c6..cb6d2b1 100644 --- a/src/get-cache-keys.test.ts +++ b/src/get-cache-keys.test.ts @@ -1,4 +1,6 @@ -import { getCacheKeys } from "./get-cache-keys"; +import { jest } from "@jest/globals"; + +import { getCacheKeys } from "./get-cache-keys.js"; test("getCacheKeys", () => { const keys = getCacheKeys(["prefix-os-compiler", "package", "source"]); diff --git a/src/hie.ts b/src/hie.ts index 170b8ea..ad45d74 100644 --- a/src/hie.ts +++ b/src/hie.ts @@ -1,7 +1,7 @@ import * as fs from "fs"; import * as core from "@actions/core"; -import { StackCLI } from "./stack-cli"; +import { StackCLI } from "./stack-cli.js" export const HIE_YAML: string = "hie.yaml"; diff --git a/src/inputs.ts b/src/inputs.ts index c48fcea..a2ed41a 100644 --- a/src/inputs.ts +++ b/src/inputs.ts @@ -1,7 +1,7 @@ import * as core from "@actions/core"; import * as Shellwords from "shellwords-ts"; -import { envsubst } from "./envsubst"; -import { type OnDirtyFiles, parseOnDirtyFiles } from "./dirty-files"; +import { envsubst } from "./envsubst.js" +import { type OnDirtyFiles, parseOnDirtyFiles } from "./dirty-files.js" export type Inputs = { workingDirectory: string | null; diff --git a/src/main.ts b/src/main.ts index 4c5df21..3a6f792 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,13 +1,13 @@ import * as core from "@actions/core"; -import { checkDirtyFiles } from "./dirty-files"; -import { StackCLI } from "./stack-cli"; -import { getCacheKeys } from "./get-cache-keys"; -import { hashProject } from "./hash-project"; -import { getInputs } from "./inputs"; -import { readStackYamlSync, getStackDirectories } from "./stack-yaml"; -import { DEFAULT_CACHE_OPTIONS, withCache } from "./with-cache"; -import { GenHIE } from "./hie"; +import { checkDirtyFiles } from "./dirty-files.js" +import { StackCLI } from "./stack-cli.js" +import { getCacheKeys } from "./get-cache-keys.js" +import { hashProject } from "./hash-project.js" +import { getInputs } from "./inputs.js" +import { readStackYamlSync, getStackDirectories } from "./stack-yaml.js" +import { DEFAULT_CACHE_OPTIONS, withCache } from "./with-cache.js" +import { GenHIE } from "./hie.js" async function run() { try { diff --git a/src/parse-stack-path.test.ts b/src/parse-stack-path.test.ts index 557ff0c..b9d5c35 100644 --- a/src/parse-stack-path.test.ts +++ b/src/parse-stack-path.test.ts @@ -1,4 +1,6 @@ -import { parseStackPath } from "./parse-stack-path"; +import { jest } from "@jest/globals"; + +import { parseStackPath } from "./parse-stack-path.js"; const EXAMPLE = [ "snapshot-doc-root: /home/patrick/.stack/snapshots/x86_64-linux-tinfo6/0dd02c1d8a380045321779c4567c2aa8873910743eac342f72d56f3d26881028/9.2.7/doc", diff --git a/src/parse-stack-query.test.ts b/src/parse-stack-query.test.ts index 5dde394..24fdf64 100644 --- a/src/parse-stack-query.test.ts +++ b/src/parse-stack-query.test.ts @@ -1,4 +1,6 @@ -import { parseStackQuery } from "./parse-stack-query"; +import { jest } from "@jest/globals"; + +import { parseStackQuery } from "./parse-stack-query.js"; const EXAMPLE = [ "compiler:", diff --git a/src/stack-cli.test.ts b/src/stack-cli.test.ts index f142206..0ef8f6b 100644 --- a/src/stack-cli.test.ts +++ b/src/stack-cli.test.ts @@ -1,6 +1,7 @@ import * as exec from "@actions/exec"; +import { jest } from "@jest/globals"; -import { StackCLI } from "./stack-cli"; +import { StackCLI } from "./stack-cli.js"; jest.spyOn(exec, "exec"); diff --git a/src/stack-cli.ts b/src/stack-cli.ts index 7d7b0c6..b210eb3 100644 --- a/src/stack-cli.ts +++ b/src/stack-cli.ts @@ -4,10 +4,10 @@ import { devNull } from "os"; import type { ExecOptions } from "@actions/exec"; import * as exec from "@actions/exec"; -import type { StackPath } from "./parse-stack-path"; -import { parseStackPath } from "./parse-stack-path"; -import type { StackQuery } from "./parse-stack-query"; -import { parseStackQuery } from "./parse-stack-query"; +import type { StackPath } from "./parse-stack-path.js" +import { parseStackPath } from "./parse-stack-path.js" +import type { StackQuery } from "./parse-stack-query.js" +import { parseStackQuery } from "./parse-stack-query.js" export interface ExecDelegate { exec: ( diff --git a/src/stack-yaml.test.ts b/src/stack-yaml.test.ts index 56779c6..600e61c 100644 --- a/src/stack-yaml.test.ts +++ b/src/stack-yaml.test.ts @@ -1,5 +1,7 @@ -import { parseStackYaml, getStackDirectories } from "./stack-yaml"; -import { StackCLI } from "./stack-cli"; +import { jest } from "@jest/globals"; + +import { parseStackYaml, getStackDirectories } from "./stack-yaml.js"; +import { StackCLI } from "./stack-cli.js"; const testStackRoot = "/home/me/.stack"; const testPrograms = `${testStackRoot}/programs/x86_64-linux`; diff --git a/src/stack-yaml.ts b/src/stack-yaml.ts index 708c68c..b1e8f8a 100644 --- a/src/stack-yaml.ts +++ b/src/stack-yaml.ts @@ -2,7 +2,7 @@ import * as fs from "fs"; import { join as pathJoin } from "path"; import * as yaml from "js-yaml"; -import { StackCLI } from "./stack-cli"; +import { StackCLI } from "./stack-cli.js" export type StackYaml = { resolver: string; diff --git a/src/with-cache.test.ts b/src/with-cache.test.ts index ac9fa1a..4771c3b 100644 --- a/src/with-cache.test.ts +++ b/src/with-cache.test.ts @@ -1,8 +1,9 @@ import * as core from "@actions/core"; import * as cache from "@actions/cache"; +import { jest } from "@jest/globals"; -import { getCacheKeys } from "./get-cache-keys"; -import { DEFAULT_CACHE_OPTIONS, withCache } from "./with-cache"; +import { getCacheKeys } from "./get-cache-keys.js"; +import { DEFAULT_CACHE_OPTIONS, withCache } from "./with-cache.js"; const restoreCacheMock = jest.spyOn(cache, "restoreCache"); jest.spyOn(cache, "saveCache"); diff --git a/src/with-cache.ts b/src/with-cache.ts index 590225e..dcce628 100644 --- a/src/with-cache.ts +++ b/src/with-cache.ts @@ -1,6 +1,6 @@ import * as core from "@actions/core"; import * as cache from "@actions/cache"; -import type { CacheKeys } from "./get-cache-keys"; +import type { CacheKeys } from "./get-cache-keys.js"; export type CacheOptions = { skipOnHit: boolean; diff --git a/tsconfig.json b/tsconfig.json index 3dfd4fe..4ed1658 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,8 +14,10 @@ "noEmitOnError": true, "removeComments": true, "module": "NodeNext", + "moduleResolution": "NodeNext", "esModuleInterop": true, - "strict": true + "strict": true, + "isolatedModules": true }, "include": ["./src/**/*"], "exclude": ["./src/**/*.test.ts"] From ebe8dbd8aa16c290c02111d4b508786523409178 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Thu, 26 Mar 2026 15:34:40 -0400 Subject: [PATCH 2/3] chore: replace jest mock with dep injection We can't mock that way with esm dependencies[^1]. There are some workarounds, but nothing worked, so I decided to introduce my own interface and dependency injection. In the `exec` module, apparently, we used to do it this way; there was an old (unused) `ExecDelegate` interface. When implementing `withCache`, I tried to follow that naming and test definition style, balanced against reducing the diff with `main`. [^1]: https://github.com/jestjs/jest/issues/10025 --- src/stack-cli.test.ts | 26 +++++++++++++++---------- src/stack-cli.ts | 28 ++++++++++++++++----------- src/with-cache.test.ts | 44 +++++++++++++++++++++++++++++++----------- src/with-cache.ts | 19 ++++++++++++++---- 4 files changed, 81 insertions(+), 36 deletions(-) diff --git a/src/stack-cli.test.ts b/src/stack-cli.test.ts index 0ef8f6b..b382c26 100644 --- a/src/stack-cli.test.ts +++ b/src/stack-cli.test.ts @@ -1,13 +1,17 @@ -import * as exec from "@actions/exec"; +import { ExecOptions } from "@actions/exec"; import { jest } from "@jest/globals"; -import { StackCLI } from "./stack-cli.js"; +import { ExecDelegate, StackCLI } from "./stack-cli.js"; -jest.spyOn(exec, "exec"); +const exec: ExecDelegate = { + exec: jest.fn((command: string, args: string[], options?: ExecOptions) => + Promise.resolve(0), + ), +}; describe("StackCLI", () => { test("Respects --resolver given", async () => { - const stackCLI = new StackCLI(["--resolver", "lts"], false); + const stackCLI = new StackCLI(["--resolver", "lts"], false, exec); await stackCLI.setup([]); @@ -22,6 +26,7 @@ describe("StackCLI", () => { const stackCLI = new StackCLI( ["--stack-yaml", "sub/stack-nightly.yaml"], false, + exec, ); await stackCLI.setup([]); @@ -48,6 +53,7 @@ describe("StackCLI", () => { "nightly-20240201", ], false, + exec, ); await stackCLI.setup([]); @@ -66,7 +72,7 @@ describe("StackCLI", () => { }); test("installCompilerTools", async () => { - const stackCLI = new StackCLI([], false); + const stackCLI = new StackCLI([], false, exec); await stackCLI.installCompilerTools(["hlint", "weeder"]); expect(exec.exec).toHaveBeenCalledWith( @@ -77,14 +83,14 @@ describe("StackCLI", () => { }); test("installCompilerTools with empty arguments", async () => { - const stackCLI = new StackCLI([], false); + const stackCLI = new StackCLI([], false, exec); await stackCLI.installCompilerTools([]); expect(exec.exec).not.toHaveBeenCalled(); }); test("buildDependencies", async () => { - const stackCLI = new StackCLI([], false); + const stackCLI = new StackCLI([], false, exec); await stackCLI.buildDependencies(["--coverage"]); @@ -102,7 +108,7 @@ describe("StackCLI", () => { }); test("buildNoTest", async () => { - const stackCLI = new StackCLI([], false); + const stackCLI = new StackCLI([], false, exec); await stackCLI.buildNoTest(["--coverage"]); @@ -114,7 +120,7 @@ describe("StackCLI", () => { }); test("buildTest", async () => { - const stackCLI = new StackCLI([], false); + const stackCLI = new StackCLI([], false, exec); await stackCLI.buildTest(["--coverage"]); @@ -126,7 +132,7 @@ describe("StackCLI", () => { }); test("build", async () => { - const stackCLI = new StackCLI([], false); + const stackCLI = new StackCLI([], false, exec); await stackCLI.build(["--coverage"]); diff --git a/src/stack-cli.ts b/src/stack-cli.ts index b210eb3..cce736f 100644 --- a/src/stack-cli.ts +++ b/src/stack-cli.ts @@ -2,12 +2,12 @@ import * as fs from "fs"; import * as path from "path"; import { devNull } from "os"; import type { ExecOptions } from "@actions/exec"; -import * as exec from "@actions/exec"; +import * as realExec from "@actions/exec"; -import type { StackPath } from "./parse-stack-path.js" -import { parseStackPath } from "./parse-stack-path.js" -import type { StackQuery } from "./parse-stack-query.js" -import { parseStackQuery } from "./parse-stack-query.js" +import type { StackPath } from "./parse-stack-path.js"; +import { parseStackPath } from "./parse-stack-path.js"; +import type { StackQuery } from "./parse-stack-query.js"; +import { parseStackQuery } from "./parse-stack-query.js"; export interface ExecDelegate { exec: ( @@ -23,10 +23,12 @@ export class StackCLI { private debug: boolean; private globalArgs: string[]; + private execImpl: ExecDelegate; - constructor(args: string[], debug?: boolean) { + constructor(args: string[], debug?: boolean, exec?: ExecDelegate) { this.debug = debug ?? false; this.globalArgs = args; + this.execImpl = exec ?? realExec; // Capture --stack-yaml if given const stackYamlIdx = args.indexOf("--stack-yaml"); @@ -49,7 +51,7 @@ export class StackCLI { } async installed(): Promise { - const ec = await exec.exec("which", ["stack"], { + const ec = await this.execImpl.exec("which", ["stack"], { silent: true, ignoreReturnCode: true, }); @@ -59,14 +61,14 @@ export class StackCLI { async install(): Promise { const url = "https://get.haskellstack.org"; const tmp = "install-stack.sh"; - await exec.exec("curl", ["-sSL", "-o", tmp, url]); - await exec.exec("sh", [tmp]); + await this.execImpl.exec("curl", ["-sSL", "-o", tmp, url]); + await this.execImpl.exec("sh", [tmp]); fs.rmSync(tmp); } async upgrade(): Promise { // Avoid this.exec because we don't need/want globalArgs - return await exec.exec("stack", ["upgrade"]); + return await this.execImpl.exec("stack", ["upgrade"]); } async setup(args: string[]): Promise { @@ -139,6 +141,10 @@ export class StackCLI { } private async exec(args: string[], options?: ExecOptions): Promise { - return await exec.exec("stack", this.globalArgs.concat(args), options); + return await this.execImpl.exec( + "stack", + this.globalArgs.concat(args), + options, + ); } } diff --git a/src/with-cache.test.ts b/src/with-cache.test.ts index 4771c3b..452ec80 100644 --- a/src/with-cache.test.ts +++ b/src/with-cache.test.ts @@ -1,12 +1,19 @@ import * as core from "@actions/core"; -import * as cache from "@actions/cache"; import { jest } from "@jest/globals"; import { getCacheKeys } from "./get-cache-keys.js"; -import { DEFAULT_CACHE_OPTIONS, withCache } from "./with-cache.js"; +import { + CacheDelegate, + DEFAULT_CACHE_OPTIONS, + withCache, +} from "./with-cache.js"; + +const cache: CacheDelegate = { + restoreCache: jest.fn(() => Promise.resolve("")), + saveCache: jest.fn(() => Promise.resolve(0)), +}; const restoreCacheMock = jest.spyOn(cache, "restoreCache"); -jest.spyOn(cache, "saveCache"); jest.spyOn(core, "info"); async function testFunction(): Promise { @@ -43,6 +50,7 @@ test("withCache skips on primary-key hit", async () => { cacheKeys, testFunction, DEFAULT_CACHE_OPTIONS, + cache, ); expect(result).toBeUndefined(); @@ -64,6 +72,7 @@ test("withCache acts and saves if no primary-key hit", async () => { cacheKeys, testFunction, DEFAULT_CACHE_OPTIONS, + cache, ); expect(result).toEqual(42); @@ -83,10 +92,16 @@ test("withCache can be configured to act and save anyway", async () => { const cacheKeys = getCacheKeys(["a-b", "c", "d"]); restoreCacheMock.mockImplementation(simulateCacheHit); - const result = await withCache(cachePaths, cacheKeys, testFunction, { - ...DEFAULT_CACHE_OPTIONS, - skipOnHit: false, - }); + const result = await withCache( + cachePaths, + cacheKeys, + testFunction, + { + ...DEFAULT_CACHE_OPTIONS, + skipOnHit: false, + }, + cache, + ); expect(result).toEqual(42); expect(cache.restoreCache).toHaveBeenCalledWith( @@ -110,6 +125,7 @@ test("withCache does not save on error", async () => { cacheKeys, testFunctionThrows, DEFAULT_CACHE_OPTIONS, + cache, ); }).rejects.toThrow(); @@ -129,10 +145,16 @@ test("withCache can be configured to save on error", async () => { restoreCacheMock.mockImplementation(simulateCacheMiss); await expect(async () => { - await withCache(cachePaths, cacheKeys, testFunctionThrows, { - ...DEFAULT_CACHE_OPTIONS, - saveOnError: true, - }); + await withCache( + cachePaths, + cacheKeys, + testFunctionThrows, + { + ...DEFAULT_CACHE_OPTIONS, + saveOnError: true, + }, + cache, + ); }).rejects.toThrow(); expect(cache.restoreCache).toHaveBeenCalledWith( diff --git a/src/with-cache.ts b/src/with-cache.ts index dcce628..33db9d5 100644 --- a/src/with-cache.ts +++ b/src/with-cache.ts @@ -1,5 +1,5 @@ import * as core from "@actions/core"; -import * as cache from "@actions/cache"; +import * as realCache from "@actions/cache"; import type { CacheKeys } from "./get-cache-keys.js"; export type CacheOptions = { @@ -12,19 +12,30 @@ export const DEFAULT_CACHE_OPTIONS = { saveOnError: false, }; +export interface CacheDelegate { + restoreCache: ( + paths: string[], + primaryKey: string, + restoreKeys?: string[], + ) => Promise; + saveCache: (paths: string[], key: string) => Promise; +} + export async function withCache( paths: string[], keys: CacheKeys, fn: () => Promise, options: CacheOptions = DEFAULT_CACHE_OPTIONS, + cache?: CacheDelegate, ): Promise { + const cacheImpl = cache ?? realCache; const { skipOnHit, saveOnError } = options; core.info(`Cached paths:\n - ${paths.join("\n - ")}`); core.info(`Cache key: ${keys.primaryKey}`); core.info(`Cache restore keys:\n - ${keys.restoreKeys.join("\n - ")}`); - const restoredKey = await cache.restoreCache( + const restoredKey = await cacheImpl.restoreCache( paths, keys.primaryKey, keys.restoreKeys, @@ -49,11 +60,11 @@ export async function withCache( result = await fn(); if (!primaryKeyHit) { - await cache.saveCache(paths, keys.primaryKey); + await cacheImpl.saveCache(paths, keys.primaryKey); } } catch (ex) { if (saveOnError && !primaryKeyHit) { - await cache.saveCache(paths, keys.primaryKey); + await cacheImpl.saveCache(paths, keys.primaryKey); } throw ex; From 1be63c3a260440f3f6b87b4ee80fb27dd26574a5 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Thu, 26 Mar 2026 15:36:04 -0400 Subject: [PATCH 3/3] chore: introduce CacheOptions{silent} to avoid logging in tests Now that it's an esm module, we can't mock `core` like we were. --- src/with-cache.test.ts | 9 +++++---- src/with-cache.ts | 20 ++++++++++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/with-cache.test.ts b/src/with-cache.test.ts index 452ec80..f19438e 100644 --- a/src/with-cache.test.ts +++ b/src/with-cache.test.ts @@ -14,7 +14,6 @@ const cache: CacheDelegate = { }; const restoreCacheMock = jest.spyOn(cache, "restoreCache"); -jest.spyOn(core, "info"); async function testFunction(): Promise { return 42; @@ -49,7 +48,7 @@ test("withCache skips on primary-key hit", async () => { cachePaths, cacheKeys, testFunction, - DEFAULT_CACHE_OPTIONS, + { ...DEFAULT_CACHE_OPTIONS, silent: true }, cache, ); @@ -71,7 +70,7 @@ test("withCache acts and saves if no primary-key hit", async () => { cachePaths, cacheKeys, testFunction, - DEFAULT_CACHE_OPTIONS, + { ...DEFAULT_CACHE_OPTIONS, silent: true }, cache, ); @@ -99,6 +98,7 @@ test("withCache can be configured to act and save anyway", async () => { { ...DEFAULT_CACHE_OPTIONS, skipOnHit: false, + silent: true, }, cache, ); @@ -124,7 +124,7 @@ test("withCache does not save on error", async () => { cachePaths, cacheKeys, testFunctionThrows, - DEFAULT_CACHE_OPTIONS, + { ...DEFAULT_CACHE_OPTIONS, silent: true }, cache, ); }).rejects.toThrow(); @@ -152,6 +152,7 @@ test("withCache can be configured to save on error", async () => { { ...DEFAULT_CACHE_OPTIONS, saveOnError: true, + silent: true, }, cache, ); diff --git a/src/with-cache.ts b/src/with-cache.ts index 33db9d5..92e3a6b 100644 --- a/src/with-cache.ts +++ b/src/with-cache.ts @@ -5,11 +5,13 @@ import type { CacheKeys } from "./get-cache-keys.js"; export type CacheOptions = { skipOnHit: boolean; saveOnError: boolean; + silent: boolean; }; export const DEFAULT_CACHE_OPTIONS = { skipOnHit: true, saveOnError: false, + silent: false, }; export interface CacheDelegate { @@ -29,11 +31,13 @@ export async function withCache( cache?: CacheDelegate, ): Promise { const cacheImpl = cache ?? realCache; - const { skipOnHit, saveOnError } = options; + const { skipOnHit, saveOnError, silent } = options; - core.info(`Cached paths:\n - ${paths.join("\n - ")}`); - core.info(`Cache key: ${keys.primaryKey}`); - core.info(`Cache restore keys:\n - ${keys.restoreKeys.join("\n - ")}`); + if (!silent) { + core.info(`Cached paths:\n - ${paths.join("\n - ")}`); + core.info(`Cache key: ${keys.primaryKey}`); + core.info(`Cache restore keys:\n - ${keys.restoreKeys.join("\n - ")}`); + } const restoredKey = await cacheImpl.restoreCache( paths, @@ -44,13 +48,17 @@ export async function withCache( const primaryKeyHit = restoredKey == keys.primaryKey; if (restoredKey) { - core.info(`Cache restored from key: ${restoredKey}`); + if (!silent) { + core.info(`Cache restored from key: ${restoredKey}`); + } } else { core.warning("No cache found"); } if (primaryKeyHit && skipOnHit && !saveOnError) { - core.info("Skipping due to primary key hit"); + if (!silent) { + core.info("Skipping due to primary key hit"); + } return; }