From e498d2a66a953492f322542257b22125c989b422 Mon Sep 17 00:00:00 2001 From: Bruno Borges Date: Tue, 28 Jul 2026 21:46:39 -0400 Subject: [PATCH] Backport #1151: Fix missing wrapper cache distributions (#1153) 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: c0b19ff2-ef52-4ac1-a832-0f8f72c43219 --- __tests__/cache.test.ts | 63 +++++++++++++++++++++++++++++++++++------ dist/cleanup/index.js | 8 ++++++ dist/setup/index.js | 8 ++++++ src/cache.ts | 12 ++++++++ 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/__tests__/cache.test.ts b/__tests__/cache.test.ts index 88660ae6..08ded85b 100644 --- a/__tests__/cache.test.ts +++ b/__tests__/cache.test.ts @@ -377,6 +377,10 @@ describe('dependency cache', () => { ReturnType, Parameters >; + let spyGlobCreate: jest.SpyInstance< + ReturnType, + Parameters + >; beforeEach(() => { spyCacheSave = jest @@ -384,6 +388,9 @@ describe('dependency cache', () => { .mockImplementation((paths: string[], key: string) => Promise.resolve(0) ); + spyGlobCreate = jest + .spyOn(glob, 'create') + .mockResolvedValue(createGlobber(['wrapper-path'])); spyWarning.mockImplementation(() => null); }); @@ -469,17 +476,24 @@ 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') + ); createStateForWrapperRestore('maven-wrapper', false); - spyCacheSave.mockImplementation((paths: string[], key: string) => { - if (paths.includes(join(os.homedir(), '.m2', 'wrapper', 'dists'))) { - return Promise.reject( - new cache.ValidationError('Path Validation Error') - ); - } - return Promise.resolve(0); - }); + spyGlobCreate.mockResolvedValue(createGlobber([])); - await expect(save('maven')).resolves.not.toThrow(); + 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(); }); }); describe('for gradle', () => { @@ -553,6 +567,23 @@ 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')); + createStateForWrapperRestore('gradle-wrapper', false); + spyGlobCreate.mockResolvedValue(createGlobber([])); + + 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 () => { @@ -663,6 +694,20 @@ function createDirectory(path: string) { fs.mkdirSync(path); } +function createGlobber( + paths: string[] +): Awaited> { + return { + getSearchPaths: () => [], + glob: () => Promise.resolve(paths), + globGenerator: async function* () { + for (const path of paths) { + yield path; + } + } + }; +} + function projectRoot(workspace: string): string { if (os.platform() === 'darwin') { return `/private${workspace}`; diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index 7ff509c0..d0fef1ef 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -50898,6 +50898,14 @@ function saveAdditionalCache(packageManager, additionalCache) { core.info(`Cache hit occurred on the ${additionalCache.name} primary key ${primaryKey}, not saving cache.`); return; } + const globber = yield glob.create(additionalCache.path.join('\n'), { + implicitDescendants: false + }); + const cachePaths = yield globber.glob(); + if (cachePaths.length === 0) { + core.debug(`${additionalCache.name} cache paths do not exist, not saving cache.`); + return; + } try { const cacheId = yield cache.saveCache(additionalCache.path, primaryKey); if (cacheId === -1) { diff --git a/dist/setup/index.js b/dist/setup/index.js index f99f5cb7..72eec485 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -76733,6 +76733,14 @@ function saveAdditionalCache(packageManager, additionalCache) { core.info(`Cache hit occurred on the ${additionalCache.name} primary key ${primaryKey}, not saving cache.`); return; } + const globber = yield glob.create(additionalCache.path.join('\n'), { + implicitDescendants: false + }); + const cachePaths = yield globber.glob(); + if (cachePaths.length === 0) { + core.debug(`${additionalCache.name} cache paths do not exist, not saving cache.`); + return; + } try { const cacheId = yield cache.saveCache(additionalCache.path, primaryKey); if (cacheId === -1) { diff --git a/src/cache.ts b/src/cache.ts index 1ca7e762..9f9c079a 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -319,6 +319,18 @@ 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); if (cacheId === -1) {