From 4eb34c79bd76b0285e268023701f65353e3ce3b4 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Wed, 8 Jul 2026 14:51:56 -0400 Subject: [PATCH 1/2] feat: expose cache-primary-key output (#597) Backport of the cache-primary-key output to the v5 release line. Expose the primary cache key computed by the caching logic as a new `cache-primary-key` action output, so workflows can compose the built-in setup-java cache key with actions/cache or actions/cache/restore across steps and dependent jobs. - src/cache.ts: set the `cache-primary-key` output in restore() - action.yml: declare the new output - README.md: document the new output - __tests__/cache.test.ts: assert the output is set - dist: rebuild (CommonJS) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 2 ++ __tests__/cache.test.ts | 14 ++++++++++++++ action.yml | 2 ++ dist/cleanup/index.js | 1 + dist/setup/index.js | 1 + src/cache.ts | 1 + 6 files changed, 21 insertions(+) diff --git a/README.md b/README.md index f8a0b5727..c7c3f202e 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,8 @@ When the option `cache-dependency-path` is specified, the hash is based on the m The workflow output `cache-hit` is set to indicate if an exact match was found for the key [as actions/cache does](https://github.com/actions/cache/tree/main#outputs). +The workflow output `cache-primary-key` exposes the primary cache key computed by the action for the configured build tool. It is useful for composing with [`actions/cache`](https://github.com/actions/cache) or [`actions/cache/restore`](https://github.com/actions/cache/tree/main/restore) in later steps or dependent jobs that need to reuse the exact same key. It is empty when caching is not enabled. + The cache input is optional, and caching is turned off by default. **Maven Wrapper:** when `cache: 'maven'` is enabled, the action also caches and restores the Maven Wrapper distribution downloaded to `~/.m2/wrapper/dists` (in addition to the local repository), so wrapper-based (`./mvnw`) builds don't re-download the wrapper on every run. This is keyed on `**/.mvn/wrapper/maven-wrapper.properties` as shown above. diff --git a/__tests__/cache.test.ts b/__tests__/cache.test.ts index 690568706..90f68efe1 100644 --- a/__tests__/cache.test.ts +++ b/__tests__/cache.test.ts @@ -78,6 +78,10 @@ describe('dependency cache', () => { ReturnType, Parameters >; + let spySetOutput: jest.SpyInstance< + ReturnType, + Parameters + >; beforeEach(() => { spyCacheRestore = jest @@ -86,6 +90,7 @@ describe('dependency cache', () => { Promise.resolve(undefined) ); spyGlobHashFiles = jest.spyOn(glob, 'hashFiles'); + spySetOutput = jest.spyOn(core, 'setOutput').mockImplementation(() => {}); spyWarning.mockImplementation(() => null); }); @@ -120,6 +125,15 @@ describe('dependency cache', () => { expect(spyWarning).not.toHaveBeenCalled(); expect(spyInfo).toHaveBeenCalledWith('maven cache is not found'); }); + it('sets the cache-primary-key output', async () => { + createFile(join(workspace, 'pom.xml')); + + await restore('maven', ''); + expect(spySetOutput).toHaveBeenCalledWith( + 'cache-primary-key', + expect.stringContaining('setup-java-') + ); + }); it('downloads cache based on maven-wrapper.properties', async () => { createDirectory(join(workspace, '.mvn')); createDirectory(join(workspace, '.mvn', 'wrapper')); diff --git a/action.yml b/action.yml index 781c82456..53d65e855 100644 --- a/action.yml +++ b/action.yml @@ -103,6 +103,8 @@ outputs: description: 'Path to where the java environment has been installed (same as $JAVA_HOME)' cache-hit: description: 'A boolean value to indicate an exact match was found for the primary key' + cache-primary-key: + description: 'The primary cache key computed by the action for the configured build tool. Empty when caching is not enabled. Useful for composing with actions/cache or actions/cache/restore across jobs.' runs: using: 'node24' main: 'dist/setup/index.js' diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index 01fb85055..9efafbd82 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -52056,6 +52056,7 @@ function restore(id, cacheDependencyPath) { const primaryKey = yield computeCacheKey(packageManager, cacheDependencyPath); core.debug(`primary key is ${primaryKey}`); core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey); + core.setOutput('cache-primary-key', primaryKey); // No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269) const matchedKey = yield cache.restoreCache(packageManager.path, primaryKey); if (matchedKey) { diff --git a/dist/setup/index.js b/dist/setup/index.js index 30395de2d..cadc3f70c 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -77921,6 +77921,7 @@ function restore(id, cacheDependencyPath) { const primaryKey = yield computeCacheKey(packageManager, cacheDependencyPath); core.debug(`primary key is ${primaryKey}`); core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey); + core.setOutput('cache-primary-key', primaryKey); // No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269) const matchedKey = yield cache.restoreCache(packageManager.path, primaryKey); if (matchedKey) { diff --git a/src/cache.ts b/src/cache.ts index 42c086c13..9b45de3e6 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -118,6 +118,7 @@ export async function restore(id: string, cacheDependencyPath: string) { const primaryKey = await computeCacheKey(packageManager, cacheDependencyPath); core.debug(`primary key is ${primaryKey}`); core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey); + core.setOutput('cache-primary-key', primaryKey); // No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269) const matchedKey = await cache.restoreCache(packageManager.path, primaryKey); From 1c4b6666fc61d36805c4fad9c1c63c4201cfd039 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Wed, 8 Jul 2026 15:05:50 -0400 Subject: [PATCH 2/2] Apply PR #1088 review suggestions to v5 backport Port the review feedback from the main-line PR (#1088) into the v5 backport: - src/cache.ts: use the STATE_CACHE_PRIMARY_KEY constant for the output name instead of a duplicated string literal - action.yml / README.md: clarify that the output is also empty when caching is skipped (e.g. the cache service is unavailable) - dist: rebuild Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 2 +- action.yml | 2 +- dist/cleanup/index.js | 2 +- dist/setup/index.js | 2 +- src/cache.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c7c3f202e..24ffb3394 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,7 @@ When the option `cache-dependency-path` is specified, the hash is based on the m The workflow output `cache-hit` is set to indicate if an exact match was found for the key [as actions/cache does](https://github.com/actions/cache/tree/main#outputs). -The workflow output `cache-primary-key` exposes the primary cache key computed by the action for the configured build tool. It is useful for composing with [`actions/cache`](https://github.com/actions/cache) or [`actions/cache/restore`](https://github.com/actions/cache/tree/main/restore) in later steps or dependent jobs that need to reuse the exact same key. It is empty when caching is not enabled. +The workflow output `cache-primary-key` exposes the primary cache key computed by the action for the configured build tool. It is useful for composing with [`actions/cache`](https://github.com/actions/cache) or [`actions/cache/restore`](https://github.com/actions/cache/tree/main/restore) in later steps or dependent jobs that need to reuse the exact same key. It is empty when caching is not enabled or when caching is skipped (for example, when the cache service is unavailable). The cache input is optional, and caching is turned off by default. diff --git a/action.yml b/action.yml index 53d65e855..5237f1a8f 100644 --- a/action.yml +++ b/action.yml @@ -104,7 +104,7 @@ outputs: cache-hit: description: 'A boolean value to indicate an exact match was found for the primary key' cache-primary-key: - description: 'The primary cache key computed by the action for the configured build tool. Empty when caching is not enabled. Useful for composing with actions/cache or actions/cache/restore across jobs.' + description: 'The primary cache key computed by the action for the configured build tool. Empty when caching is not enabled or when caching is skipped (e.g. cache service unavailable). Useful for composing with actions/cache or actions/cache/restore across jobs.' runs: using: 'node24' main: 'dist/setup/index.js' diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index 9efafbd82..1154a0bc6 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -52056,7 +52056,7 @@ function restore(id, cacheDependencyPath) { const primaryKey = yield computeCacheKey(packageManager, cacheDependencyPath); core.debug(`primary key is ${primaryKey}`); core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey); - core.setOutput('cache-primary-key', primaryKey); + core.setOutput(STATE_CACHE_PRIMARY_KEY, primaryKey); // No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269) const matchedKey = yield cache.restoreCache(packageManager.path, primaryKey); if (matchedKey) { diff --git a/dist/setup/index.js b/dist/setup/index.js index cadc3f70c..7b098a526 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -77921,7 +77921,7 @@ function restore(id, cacheDependencyPath) { const primaryKey = yield computeCacheKey(packageManager, cacheDependencyPath); core.debug(`primary key is ${primaryKey}`); core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey); - core.setOutput('cache-primary-key', primaryKey); + core.setOutput(STATE_CACHE_PRIMARY_KEY, primaryKey); // No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269) const matchedKey = yield cache.restoreCache(packageManager.path, primaryKey); if (matchedKey) { diff --git a/src/cache.ts b/src/cache.ts index 9b45de3e6..263cc0d8a 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -118,7 +118,7 @@ export async function restore(id: string, cacheDependencyPath: string) { const primaryKey = await computeCacheKey(packageManager, cacheDependencyPath); core.debug(`primary key is ${primaryKey}`); core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey); - core.setOutput('cache-primary-key', primaryKey); + core.setOutput(STATE_CACHE_PRIMARY_KEY, primaryKey); // No "restoreKeys" is set, to start with a clear cache after dependency update (see https://github.com/actions/setup-java/issues/269) const matchedKey = await cache.restoreCache(packageManager.path, primaryKey);