Add support for JetBrains' Amper build/cache

The Amper build system uses `.cache/Amper/` for its dependencies, and
also (currently) uses some `.gradle/` folders for Android builds.
This commit is contained in:
Salvatore Testa 2025-06-23 14:51:00 +02:00
commit 9cedcca2cc
No known key found for this signature in database
6 changed files with 146 additions and 2 deletions

View file

@ -14,6 +14,7 @@ The `setup-java` action provides the following functionality for GitHub Actions
- Caching dependencies managed by Apache Maven.
- Caching dependencies managed by Gradle.
- Caching dependencies managed by sbt.
- Caching dependencies managed by Amper.
- [Maven Toolchains declaration](https://maven.apache.org/guides/mini/guide-using-toolchains.html) for specified JDK versions.
This action allows you to work with Java and Scala projects.

View file

@ -201,6 +201,60 @@ describe('dependency cache', () => {
expect(firstCall).not.toBe(thirdCall);
});
});
describe('for amper', () => {
it('throws error if no module.xml found', async () => {
await expect(restore('amper', '')).rejects.toThrow(
`No file in ${projectRoot(
workspace
)} matched to [**/module.xml,amper,amper.bat,gradle/*.versions.toml], make sure you have checked out the target repository`
);
});
it('downloads cache based on module.xml', async () => {
createFile(join(workspace, 'module.xml'));
await restore('amper', '');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyGlobHashFiles).toHaveBeenCalledWith(
'**/module.xml\namper\namper.bat\ngradle/*.versions.toml'
);
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('amper cache is not found');
});
it('downloads cache based on amper script', async () => {
createFile(join(workspace, 'amper'));
await restore('amper', '');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyGlobHashFiles).toHaveBeenCalledWith(
'**/module.xml\namper\namper.bat\ngradle/*.versions.toml'
);
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('amper cache is not found');
});
it('downloads cache based on amper.bat script', async () => {
createFile(join(workspace, 'amper.bat'));
await restore('amper', '');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyGlobHashFiles).toHaveBeenCalledWith(
'**/module.xml\namper\namper.bat\ngradle/*.versions.toml'
);
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('amper cache is not found');
});
it('downloads cache based on gradle/libs.versions.toml', async () => {
createDirectory(join(workspace, 'gradle'));
createFile(join(workspace, 'gradle', 'libs.versions.toml'));
await restore('amper', '');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyGlobHashFiles).toHaveBeenCalledWith(
'**/module.xml\namper\namper.bat\ngradle/*.versions.toml'
);
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('amper cache is not found');
});
});
it('downloads cache based on versions.properties', async () => {
createFile(join(workspace, 'versions.properties'));
@ -419,6 +473,68 @@ describe('dependency cache', () => {
);
});
});
describe('for amper', () => {
it('uploads cache even if no module.xml found', async () => {
createStateForMissingBuildFile();
await save('amper');
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
});
it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'module.xml'));
await save('amper');
expect(spyCacheSave).not.toHaveBeenCalled();
expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
);
});
it('uploads cache based on module.xml', async () => {
createFile(join(workspace, 'module.xml'));
createStateForSuccessfulRestore();
await save('amper');
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
it('uploads cache based on amper script', async () => {
createFile(join(workspace, 'amper'));
createStateForSuccessfulRestore();
await save('amper');
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
it('uploads cache based on amper.bat script', async () => {
createFile(join(workspace, 'amper.bat'));
createStateForSuccessfulRestore();
await save('amper');
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
it('uploads cache based on gradle/libs.versions.toml', async () => {
createDirectory(join(workspace, 'gradle'));
createFile(join(workspace, 'gradle', 'libs.versions.toml'));
createStateForSuccessfulRestore();
await save('amper');
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
});
});
});

View file

@ -54,7 +54,7 @@ inputs:
$GPG_PASSPHRASE.'
required: false
cache:
description: 'Name of the build platform to cache dependencies. It can be "maven", "gradle" or "sbt".'
description: 'Name of the build platform to cache dependencies. It can be "maven", "gradle", "sbt", or "amper".'
required: false
cache-dependency-path:
description: 'The path to a dependency file: pom.xml, build.gradle, build.sbt, etc. This option can be used with the `cache` option. If this option is omitted, the action searches for the dependency file in the entire repository. This option supports wildcards and a list of file names for caching multiple dependencies.'

View file

@ -93140,6 +93140,15 @@ const supportedPackageManager = [
'**/project/**.scala',
'**/project/**.sbt'
]
},
{
id: 'amper',
path: [
(0, path_1.join)(os_1.default.homedir(), '.cache', 'Amper'),
(0, path_1.join)(os_1.default.homedir(), '.gradle', 'caches'),
(0, path_1.join)(os_1.default.homedir(), '.gradle', 'wrapper')
],
pattern: ['**/module.xml', 'amper', 'amper.bat', 'gradle/*.versions.toml']
}
];
function getCoursierCachePath() {

9
dist/setup/index.js vendored
View file

@ -128389,6 +128389,15 @@ const supportedPackageManager = [
'**/project/**.scala',
'**/project/**.sbt'
]
},
{
id: 'amper',
path: [
(0, path_1.join)(os_1.default.homedir(), '.cache', 'Amper'),
(0, path_1.join)(os_1.default.homedir(), '.gradle', 'caches'),
(0, path_1.join)(os_1.default.homedir(), '.gradle', 'wrapper')
],
pattern: ['**/module.xml', 'amper', 'amper.bat', 'gradle/*.versions.toml']
}
];
function getCoursierCachePath() {

View file

@ -13,7 +13,7 @@ const CACHE_MATCHED_KEY = 'cache-matched-key';
const CACHE_KEY_PREFIX = 'setup-java';
interface PackageManager {
id: 'maven' | 'gradle' | 'sbt';
id: 'maven' | 'gradle' | 'sbt' | 'amper';
/**
* Paths of the file that specify the files to cache.
*/
@ -60,6 +60,15 @@ const supportedPackageManager: PackageManager[] = [
'**/project/**.scala',
'**/project/**.sbt'
]
},
{
id: 'amper',
path: [
join(os.homedir(), '.cache', 'Amper'),
join(os.homedir(), '.gradle', 'caches'),
join(os.homedir(), '.gradle', 'wrapper')
],
pattern: ['**/module.xml', 'amper', 'amper.bat', 'gradle/*.versions.toml']
}
];