Skip to content

Commit ac3a4a8

Browse files
brunoborgesCopilot
andauthored
Cache Gradle wrapper distribution separately from the dependency cache (#1098)
The Gradle wrapper distribution (~/.gradle/wrapper) only depends on gradle-wrapper.properties, which changes rarely, but it was previously cached in the same entry as ~/.gradle/caches, keyed on volatile **/*.gradle* files with no restoreKeys (issue #269). Every dependency change therefore re-downloaded the wrapper. Move ~/.gradle/wrapper into a dedicated `gradle-wrapper` additional cache keyed only on **/gradle-wrapper.properties, reusing the additionalCaches infrastructure introduced for the Maven wrapper fix. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent bc6a9b1 commit ac3a4a8

4 files changed

Lines changed: 117 additions & 12 deletions

File tree

__tests__/cache.test.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,43 @@ describe('dependency cache', () => {
316316
expect(spyWarning).not.toHaveBeenCalled();
317317
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
318318
});
319+
it('restores the gradle wrapper distribution cache independently of the main cache', async () => {
320+
createFile(join(workspace, 'build.gradle'));
321+
322+
await restore('gradle', '');
323+
// Main dependency cache no longer carries the wrapper path.
324+
expect(spyCacheRestore).toHaveBeenCalledWith(
325+
[join(os.homedir(), '.gradle', 'caches')],
326+
expect.any(String)
327+
);
328+
// Wrapper distribution is restored on its own, keyed only on the
329+
// wrapper properties file.
330+
expect(spyCacheRestore).toHaveBeenCalledWith(
331+
[join(os.homedir(), '.gradle', 'wrapper')],
332+
expect.stringContaining('setup-java-')
333+
);
334+
expect(spyGlobHashFiles).toHaveBeenCalledWith(
335+
'**/gradle-wrapper.properties'
336+
);
337+
});
338+
it('skips the gradle wrapper cache when no wrapper properties exist', async () => {
339+
createFile(join(workspace, 'build.gradle'));
340+
spyGlobHashFiles.mockImplementation((pattern: string) =>
341+
Promise.resolve(
342+
pattern === '**/gradle-wrapper.properties' ? '' : 'hash-stub'
343+
)
344+
);
345+
346+
await restore('gradle', '');
347+
// Only the main dependency cache is restored; the wrapper cache path is
348+
// never touched because the project does not use the gradle wrapper.
349+
expect(spyCacheRestore).toHaveBeenCalledTimes(1);
350+
expect(spyCacheRestore).toHaveBeenCalledWith(
351+
[join(os.homedir(), '.gradle', 'caches')],
352+
expect.any(String)
353+
);
354+
expect(spyWarning).not.toHaveBeenCalled();
355+
});
319356
});
320357
describe('for sbt', () => {
321358
it('throws error if no build.sbt found', async () => {
@@ -587,6 +624,50 @@ describe('dependency cache', () => {
587624
expect.stringMatching(/^Cache saved with the key:.*/)
588625
);
589626
});
627+
it('saves the gradle wrapper distribution cache under its own key', async () => {
628+
createFile(join(workspace, 'build.gradle'));
629+
(core.getState as jest.Mock<any>).mockImplementation((name: any) => {
630+
switch (name) {
631+
case 'cache-primary-key':
632+
return 'setup-java-cache-primary-key';
633+
case 'cache-matched-key':
634+
return 'setup-java-cache-matched-key';
635+
case 'cache-primary-key-gradle-wrapper':
636+
return 'setup-java-gradle-wrapper-key';
637+
default:
638+
return '';
639+
}
640+
});
641+
642+
await save('gradle');
643+
expect(spyCacheSave).toHaveBeenCalledWith(
644+
[join(os.homedir(), '.gradle', 'wrapper')],
645+
'setup-java-gradle-wrapper-key'
646+
);
647+
expect(spyWarning).not.toHaveBeenCalled();
648+
});
649+
it('does not save the gradle wrapper cache on an exact wrapper hit', async () => {
650+
createFile(join(workspace, 'build.gradle'));
651+
(core.getState as jest.Mock<any>).mockImplementation((name: any) => {
652+
switch (name) {
653+
case 'cache-primary-key':
654+
return 'setup-java-cache-primary-key';
655+
case 'cache-matched-key':
656+
return 'setup-java-cache-matched-key';
657+
case 'cache-primary-key-gradle-wrapper':
658+
case 'cache-matched-key-gradle-wrapper':
659+
return 'setup-java-gradle-wrapper-key';
660+
default:
661+
return '';
662+
}
663+
});
664+
665+
await save('gradle');
666+
expect(spyCacheSave).not.toHaveBeenCalledWith(
667+
[join(os.homedir(), '.gradle', 'wrapper')],
668+
expect.any(String)
669+
);
670+
});
590671
});
591672
describe('for sbt', () => {
592673
it('uploads cache even if no build.sbt found', async () => {

dist/cleanup/index.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99687,10 +99687,7 @@ const supportedPackageManager = [
9968799687
},
9968899688
{
9968999689
id: 'gradle',
99690-
path: [
99691-
(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'caches'),
99692-
(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'wrapper')
99693-
],
99690+
path: [(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'caches')],
9969499691
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
9969599692
pattern: [
9969699693
'**/*.gradle*',
@@ -99699,6 +99696,17 @@ const supportedPackageManager = [
9969999696
'buildSrc/**/Dependencies.kt',
9970099697
'gradle/*.versions.toml',
9970199698
'**/versions.properties'
99699+
],
99700+
// The Gradle wrapper distribution only depends on the wrapper properties,
99701+
// which change very rarely, so it is cached separately from the Gradle
99702+
// caches. This keeps it available across the frequent *.gradle* changes
99703+
// that rotate the main cache key. See issue #1095.
99704+
additionalCaches: [
99705+
{
99706+
name: 'gradle-wrapper',
99707+
path: [(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'wrapper')],
99708+
pattern: ['**/gradle-wrapper.properties']
99709+
}
9970299710
]
9970399711
},
9970499712
{

dist/setup/index.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130909,10 +130909,7 @@ const supportedPackageManager = [
130909130909
},
130910130910
{
130911130911
id: 'gradle',
130912-
path: [
130913-
(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'caches'),
130914-
(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'wrapper')
130915-
],
130912+
path: [(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'caches')],
130916130913
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
130917130914
pattern: [
130918130915
'**/*.gradle*',
@@ -130921,6 +130918,17 @@ const supportedPackageManager = [
130921130918
'buildSrc/**/Dependencies.kt',
130922130919
'gradle/*.versions.toml',
130923130920
'**/versions.properties'
130921+
],
130922+
// The Gradle wrapper distribution only depends on the wrapper properties,
130923+
// which change very rarely, so it is cached separately from the Gradle
130924+
// caches. This keeps it available across the frequent *.gradle* changes
130925+
// that rotate the main cache key. See issue #1095.
130926+
additionalCaches: [
130927+
{
130928+
name: 'gradle-wrapper',
130929+
path: [(0,external_path_.join)(external_os_default().homedir(), '.gradle', 'wrapper')],
130930+
pattern: ['**/gradle-wrapper.properties']
130931+
}
130924130932
]
130925130933
},
130926130934
{

src/cache.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,7 @@ const supportedPackageManager: PackageManager[] = [
7272
},
7373
{
7474
id: 'gradle',
75-
path: [
76-
join(os.homedir(), '.gradle', 'caches'),
77-
join(os.homedir(), '.gradle', 'wrapper')
78-
],
75+
path: [join(os.homedir(), '.gradle', 'caches')],
7976
// https://github.com/actions/cache/blob/0638051e9af2c23d10bb70fa9beffcad6cff9ce3/examples.md#java---gradle
8077
pattern: [
8178
'**/*.gradle*',
@@ -84,6 +81,17 @@ const supportedPackageManager: PackageManager[] = [
8481
'buildSrc/**/Dependencies.kt',
8582
'gradle/*.versions.toml',
8683
'**/versions.properties'
84+
],
85+
// The Gradle wrapper distribution only depends on the wrapper properties,
86+
// which change very rarely, so it is cached separately from the Gradle
87+
// caches. This keeps it available across the frequent *.gradle* changes
88+
// that rotate the main cache key. See issue #1095.
89+
additionalCaches: [
90+
{
91+
name: 'gradle-wrapper',
92+
path: [join(os.homedir(), '.gradle', 'wrapper')],
93+
pattern: ['**/gradle-wrapper.properties']
94+
}
8795
]
8896
},
8997
{

0 commit comments

Comments
 (0)