From 382d4b753d3cff1d6059c833f5912634bce6947b Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Tue, 28 Jul 2026 19:14:06 -0400 Subject: [PATCH] Fix caching when wrapper distributions are absent (#1151) * Fix missing wrapper cache distributions Skip optional Maven and Gradle wrapper cache saves when their distribution paths do not exist, while allowing the main dependency cache to save. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a43181c5-548d-4293-be58-b76c03cece79 * Use resolved paths for wrapper cache saves Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a43181c5-548d-4293-be58-b76c03cece79 * Rebuild action distributions Regenerate the setup and cleanup bundles after updating additional cache saves to use resolved paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a43181c5-548d-4293-be58-b76c03cece79 --------- Copilot-Session: a43181c5-548d-4293-be58-b76c03cece79 --- __tests__/cache.test.ts | 64 ++++++++++++++++++++++++++++++++++------- dist/cleanup/index.js | 10 ++++++- dist/setup/index.js | 10 ++++++- src/cache.ts | 14 ++++++++- 4 files changed, 84 insertions(+), 14 deletions(-) diff --git a/__tests__/cache.test.ts b/__tests__/cache.test.ts index 072b406c..5bac4d61 100644 --- a/__tests__/cache.test.ts +++ b/__tests__/cache.test.ts @@ -458,11 +458,16 @@ describe('dependency cache', () => { }); describe('save', () => { let spyCacheSave: any; + let spyGlobCreate: jest.Mock; beforeEach(() => { spyCacheSave = (cache.saveCache as any).mockImplementation( (paths: string[], key: string) => Promise.resolve(0) ); + spyGlobCreate = glob.create as jest.Mock; + spyGlobCreate.mockResolvedValue({ + glob: jest.fn(() => Promise.resolve(['wrapper-path'])) + }); spyWarning.mockImplementation(() => null); }); @@ -543,7 +548,7 @@ describe('dependency cache', () => { await save('maven'); expect(spyCacheSave).toHaveBeenCalledWith( - [join(os.homedir(), '.m2', 'wrapper', 'dists')], + ['wrapper-path'], 'setup-java-maven-wrapper-key' ); expect(spyWarning).not.toHaveBeenCalled(); @@ -572,6 +577,11 @@ describe('dependency cache', () => { }); it('does not fail the post step when the wrapper distribution path is missing', async () => { createFile(join(workspace, 'pom.xml')); + createDirectory(join(workspace, '.mvn')); + createDirectory(join(workspace, '.mvn', 'wrapper')); + createFile( + join(workspace, '.mvn', 'wrapper', 'maven-wrapper.properties') + ); (core.getState as jest.Mock).mockImplementation((name: any) => { switch (name) { case 'cache-primary-key': @@ -584,17 +594,19 @@ describe('dependency cache', () => { return ''; } }); - spyCacheSave.mockImplementation((paths: string[]) => - paths.includes(join(os.homedir(), '.m2', 'wrapper', 'dists')) - ? Promise.reject( - new cache.ValidationError( - 'Path Validation Error: Path(s) specified in the action for caching do(es) not exist' - ) - ) - : Promise.resolve(0) - ); + spyGlobCreate.mockResolvedValue({ + glob: jest.fn(() => Promise.resolve([])) + }); await expect(save('maven')).resolves.toBeUndefined(); + expect(spyCacheSave).not.toHaveBeenCalledWith( + [join(os.homedir(), '.m2', 'wrapper', 'dists')], + expect.any(String) + ); + expect(spyCacheSave).toHaveBeenCalledWith( + [join(os.homedir(), '.m2', 'repository')], + 'setup-java-cache-primary-key' + ); expect(spyWarning).not.toHaveBeenCalled(); }); }); @@ -666,7 +678,7 @@ describe('dependency cache', () => { await save('gradle'); expect(spyCacheSave).toHaveBeenCalledWith( - [join(os.homedir(), '.gradle', 'wrapper')], + ['wrapper-path'], 'setup-java-gradle-wrapper-key' ); expect(spyWarning).not.toHaveBeenCalled(); @@ -693,6 +705,36 @@ describe('dependency cache', () => { expect.any(String) ); }); + it('does not fail the post step when the wrapper distribution path is missing', async () => { + createFile(join(workspace, 'build.gradle')); + createFile(join(workspace, 'gradle-wrapper.properties')); + (core.getState as jest.Mock).mockImplementation((name: any) => { + switch (name) { + case 'cache-primary-key': + return 'setup-java-cache-primary-key'; + case 'cache-matched-key': + return 'setup-java-cache-matched-key'; + case 'cache-primary-key-gradle-wrapper': + return 'setup-java-gradle-wrapper-key'; + default: + return ''; + } + }); + spyGlobCreate.mockResolvedValue({ + glob: jest.fn(() => Promise.resolve([])) + }); + + await expect(save('gradle')).resolves.toBeUndefined(); + expect(spyCacheSave).not.toHaveBeenCalledWith( + [join(os.homedir(), '.gradle', 'wrapper')], + expect.any(String) + ); + expect(spyCacheSave).toHaveBeenCalledWith( + [join(os.homedir(), '.gradle', 'caches')], + 'setup-java-cache-primary-key' + ); + expect(spyWarning).not.toHaveBeenCalled(); + }); }); describe('for sbt', () => { it('uploads cache even if no build.sbt found', async () => { diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index 71754470..6ef805e2 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -97988,8 +97988,16 @@ async function saveAdditionalCache(packageManager, additionalCache) { info(`Cache hit occurred on the ${additionalCache.name} primary key ${primaryKey}, not saving cache.`); return; } + const globber = await create(additionalCache.path.join('\n'), { + implicitDescendants: false + }); + const cachePaths = await globber.glob(); + if (cachePaths.length === 0) { + core_debug(`${additionalCache.name} cache paths do not exist, not saving cache.`); + return; + } try { - const cacheId = await cache_saveCache(additionalCache.path, primaryKey); + const cacheId = await cache_saveCache(cachePaths, primaryKey); if (cacheId === -1) { core_debug(`${additionalCache.name} cache was not saved for the key: ${primaryKey}`); return; diff --git a/dist/setup/index.js b/dist/setup/index.js index 69379a0e..ee1e3f06 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -129229,8 +129229,16 @@ async function saveAdditionalCache(packageManager, additionalCache) { core.info(`Cache hit occurred on the ${additionalCache.name} primary key ${primaryKey}, not saving cache.`); return; } + const globber = await glob.create(additionalCache.path.join('\n'), { + implicitDescendants: false + }); + const cachePaths = await globber.glob(); + if (cachePaths.length === 0) { + core.debug(`${additionalCache.name} cache paths do not exist, not saving cache.`); + return; + } try { - const cacheId = await cache.saveCache(additionalCache.path, primaryKey); + const cacheId = await cache.saveCache(cachePaths, primaryKey); if (cacheId === -1) { core.debug(`${additionalCache.name} cache was not saved for the key: ${primaryKey}`); return; diff --git a/src/cache.ts b/src/cache.ts index 1ca7e762..e5951a3a 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -319,8 +319,20 @@ async function saveAdditionalCache( ); return; } + + const globber = await glob.create(additionalCache.path.join('\n'), { + implicitDescendants: false + }); + const cachePaths = await globber.glob(); + if (cachePaths.length === 0) { + core.debug( + `${additionalCache.name} cache paths do not exist, not saving cache.` + ); + return; + } + try { - const cacheId = await cache.saveCache(additionalCache.path, primaryKey); + const cacheId = await cache.saveCache(cachePaths, primaryKey); if (cacheId === -1) { core.debug( `${additionalCache.name} cache was not saved for the key: ${primaryKey}`