feat: expose cache-primary-key output (#597)

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

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Bruno Borges
2026-07-08 14:49:54 -04:00
parent fe9b749bcb
commit 90c9ef6da7
6 changed files with 19 additions and 0 deletions

View File

@@ -149,6 +149,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.

View File

@@ -133,6 +133,7 @@ describe('dependency cache', () => {
describe('restore', () => {
let spyCacheRestore: any;
let spyGlobHashFiles: any;
let spySetOutput: any;
beforeEach(() => {
spyCacheRestore = (cache.restoreCache as any).mockImplementation(
@@ -140,6 +141,8 @@ describe('dependency cache', () => {
);
spyGlobHashFiles = glob.hashFiles as jest.Mock;
spyGlobHashFiles.mockResolvedValue('hash-stub');
spySetOutput = core.setOutput as jest.Mock;
spySetOutput.mockImplementation(() => null);
spyWarning.mockImplementation(() => null);
});
@@ -175,6 +178,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'));

View File

@@ -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'

View File

@@ -99735,6 +99735,7 @@ async function restore(id, cacheDependencyPath) {
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);
if (matchedKey) {

1
dist/setup/index.js vendored
View File

@@ -130957,6 +130957,7 @@ async function restore(id, cacheDependencyPath) {
const primaryKey = await computeCacheKey(packageManager, cacheDependencyPath);
core_debug(`primary key is ${primaryKey}`);
saveState(STATE_CACHE_PRIMARY_KEY, primaryKey);
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 restoreCache(packageManager.path, primaryKey);
if (matchedKey) {

View File

@@ -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);