Repository navigation
Introduce the dependency caching for Maven and Gradle #193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 12 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
fef7d58
implement a core logic to cache dependnecies
KengoTODA 4a7bf99
integrate the cache logic to entry points
KengoTODA 945940e
add a user doc about the dependency cache feature
KengoTODA 0591f86
reflect changes to the dist dir
KengoTODA f537562
add a prefix to the cache key
KengoTODA b047f97
test: extract build.gradle to a file in __tests__ dir
KengoTODA 3e2fde2
run the restore e2e test on the specified OS
KengoTODA a5a0c52
add an e2e test for maven
KengoTODA 1872d8e
fix the dependency among workflows
KengoTODA 313e1ad
stabilize the cache on the Windows in e2e test
KengoTODA 8687e45
add .gitignore files to __tests__/cache directories
KengoTODA 6977c03
try to run restore after the authentication
KengoTODA 7fe6c4d
use the key in state to save caches in the post process
KengoTODA fae2927
suggest users to run without daemon if fail to save Gradle cache on W…
KengoTODA f6a3b97
add missing description in the README.md
KengoTODA 5f3f74c
run clean-up tasks in serial
KengoTODA 53f73ba
Add validation for post step (#3)
dmitry-shibanov 862dedb
Merge remote-tracking branch 'origin/main' into introduce-cache
KengoTODA 098a656
Update src/cleanup-java.ts
KengoTODA cb966d0
Update src/cache.ts
KengoTODA 6edf849
style: put the name of input to the constants.ts
KengoTODA 0082baa
format: run `npm run build` to reflect changes to the dist dir
KengoTODA ea721b3
chore: update licensed files by `licensed cache`
KengoTODA 807e574
fix: rerun ncc on macOS with node v12
KengoTODA 33dfe17
build: follow the suggestion at PR page
KengoTODA 67b74a1
fix: throw error in case of no package manager file found
KengoTODA File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| name: Validate cache | ||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| - releases/* | ||
| paths-ignore: | ||
| - '**.md' | ||
| pull_request: | ||
| paths-ignore: | ||
| - '**.md' | ||
|
|
||
| defaults: | ||
| run: | ||
| shell: bash | ||
|
|
||
| jobs: | ||
| gradle-save: | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [macos-latest, windows-latest, ubuntu-latest] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v2 | ||
| - name: Run setup-java with the cache for gradle | ||
| uses: ./ | ||
| id: setup-java | ||
| with: | ||
| distribution: 'adopt' | ||
| java-version: '11' | ||
| cache: gradle | ||
| - name: Create files to cache | ||
| # Need to avoid using Gradle daemon to stabilize the save process on Windows | ||
| # https://github.com/actions/cache/issues/454#issuecomment-840493935 | ||
| run: | | ||
| gradle downloadDependencies --no-daemon -p __tests__/cache/gradle | ||
| if [ ! -d ~/.gradle/caches ]; then | ||
| echo "::error::The ~/.gradle/caches directory does not exist unexpectedly" | ||
| exit 1 | ||
| fi | ||
| gradle-restore: | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [macos-latest, windows-latest, ubuntu-latest] | ||
| needs: gradle-save | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v2 | ||
| - name: Run setup-java with the cache for gradle | ||
| uses: ./ | ||
| id: setup-java | ||
| with: | ||
| distribution: 'adopt' | ||
| java-version: '11' | ||
| cache: gradle | ||
| - name: Confirm that ~/.gradle/caches directory has been made | ||
| run: | | ||
| if [ ! -d ~/.gradle/caches ]; then | ||
| echo "::error::The ~/.gradle/caches directory does not exist unexpectedly" | ||
| exit 1 | ||
| fi | ||
| ls ~/.gradle/caches/ | ||
| maven-save: | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [macos-latest, windows-latest, ubuntu-latest] | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v2 | ||
| - name: Run setup-java with the cache for maven | ||
| uses: ./ | ||
| id: setup-java | ||
| with: | ||
| distribution: 'adopt' | ||
| java-version: '11' | ||
| cache: maven | ||
| - name: Create files to cache | ||
| run: | | ||
| mvn verify -f __tests__/cache/maven/pom.xml | ||
| if [ ! -d ~/.m2/repository ]; then | ||
| echo "::error::The ~/.m2/repository directory does not exist unexpectedly" | ||
| exit 1 | ||
| fi | ||
| maven-restore: | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [macos-latest, windows-latest, ubuntu-latest] | ||
| needs: maven-save | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v2 | ||
| - name: Run setup-java with the cache for maven | ||
| uses: ./ | ||
| id: setup-java | ||
| with: | ||
| distribution: 'adopt' | ||
| java-version: '11' | ||
| cache: maven | ||
| - name: Confirm that ~/.m2/repository directory has been made | ||
| run: | | ||
| if [ ! -d ~/.m2/repository ]; then | ||
| echo "::error::The ~/.m2/repository directory does not exist unexpectedly" | ||
| exit 1 | ||
| fi | ||
| ls ~/.m2/repository | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| import { mkdtempSync } from 'fs'; | ||
| import { tmpdir } from 'os'; | ||
| import { join } from 'path'; | ||
| import { restore, save } from '../src/cache'; | ||
| import * as fs from 'fs'; | ||
| import * as os from 'os'; | ||
| import * as core from '@actions/core'; | ||
| import * as cache from '@actions/cache'; | ||
|
|
||
| describe('dependency cache', () => { | ||
| const ORIGINAL_RUNNER_OS = process.env['RUNNER_OS']; | ||
| const ORIGINAL_GITHUB_WORKSPACE = process.env['GITHUB_WORKSPACE']; | ||
| const ORIGINAL_CWD = process.cwd(); | ||
| let workspace: string; | ||
| let spyInfo: jest.SpyInstance<void, Parameters<typeof core.info>>; | ||
| let spyWarning: jest.SpyInstance<void, Parameters<typeof core.warning>>; | ||
|
|
||
| beforeEach(() => { | ||
| workspace = mkdtempSync(join(tmpdir(), 'setup-java-cache-')); | ||
| switch (os.platform()) { | ||
| case 'darwin': | ||
| process.env['RUNNER_OS'] = 'macOS'; | ||
| break; | ||
| case 'win32': | ||
| process.env['RUNNER_OS'] = 'Windows'; | ||
| break; | ||
| case 'linux': | ||
| process.env['RUNNER_OS'] = 'Linux'; | ||
| break; | ||
| default: | ||
| throw new Error(`unknown platform: ${os.platform()}`); | ||
| } | ||
| process.chdir(workspace); | ||
| // This hack is necessary because @actions/glob ignores files not in the GITHUB_WORKSPACE | ||
| // https://git.io/Jcxig | ||
| process.env['GITHUB_WORKSPACE'] = projectRoot(workspace); | ||
| }); | ||
|
|
||
| beforeEach(() => { | ||
| spyInfo = jest.spyOn(core, 'info'); | ||
| spyWarning = jest.spyOn(core, 'warning'); | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| process.chdir(ORIGINAL_CWD); | ||
| process.env['GITHUB_WORKSPACE'] = ORIGINAL_GITHUB_WORKSPACE; | ||
| process.env['RUNNER_OS'] = ORIGINAL_RUNNER_OS; | ||
| }); | ||
|
|
||
| describe('restore', () => { | ||
| let spyCacheRestore: jest.SpyInstance< | ||
| ReturnType<typeof cache.restoreCache>, | ||
| Parameters<typeof cache.restoreCache> | ||
| >; | ||
|
|
||
| beforeEach(() => { | ||
| spyCacheRestore = jest | ||
| .spyOn(cache, 'restoreCache') | ||
| .mockImplementation((paths: string[], primaryKey: string) => Promise.resolve(undefined)); | ||
| }); | ||
|
|
||
| it('throws error if unsupported package manager specified', () => { | ||
| return expect(restore('ant')).rejects.toThrowError('unknown package manager specified: ant'); | ||
| }); | ||
|
|
||
| describe('for maven', () => { | ||
| it('warns if no pom.xml found', async () => { | ||
| await restore('maven'); | ||
| expect(spyWarning).toBeCalledWith( | ||
| `No file in ${projectRoot( | ||
| workspace | ||
| )} matched to [**/pom.xml], make sure you have checked out the target repository` | ||
| ); | ||
| }); | ||
| it('downloads cache', async () => { | ||
| createFile(join(workspace, 'pom.xml')); | ||
|
|
||
| await restore('maven'); | ||
| expect(spyCacheRestore).toBeCalled(); | ||
| expect(spyWarning).not.toBeCalled(); | ||
| expect(spyInfo).toBeCalledWith('maven cache is not found'); | ||
| }); | ||
| }); | ||
| describe('for gradle', () => { | ||
| it('warns if no build.gradle found', async () => { | ||
| await restore('gradle'); | ||
| expect(spyWarning).toBeCalledWith( | ||
| `No file in ${projectRoot( | ||
| workspace | ||
| )} matched to [**/*.gradle*,**/gradle-wrapper.properties], make sure you have checked out the target repository` | ||
| ); | ||
| }); | ||
| it('downloads cache based on build.gradle', async () => { | ||
| createFile(join(workspace, 'build.gradle')); | ||
|
|
||
| await restore('gradle'); | ||
| expect(spyCacheRestore).toBeCalled(); | ||
| expect(spyWarning).not.toBeCalled(); | ||
| expect(spyInfo).toBeCalledWith('gradle cache is not found'); | ||
| }); | ||
| it('downloads cache based on build.gradle.kts', async () => { | ||
| createFile(join(workspace, 'build.gradle.kts')); | ||
|
|
||
| await restore('gradle'); | ||
| expect(spyCacheRestore).toBeCalled(); | ||
| expect(spyWarning).not.toBeCalled(); | ||
| expect(spyInfo).toBeCalledWith('gradle cache is not found'); | ||
| }); | ||
| }); | ||
| }); | ||
| describe('save', () => { | ||
| let spyCacheSave: jest.SpyInstance< | ||
| ReturnType<typeof cache.saveCache>, | ||
| Parameters<typeof cache.saveCache> | ||
| >; | ||
|
|
||
| beforeEach(() => { | ||
| spyCacheSave = jest | ||
| .spyOn(cache, 'saveCache') | ||
| .mockImplementation((paths: string[], key: string) => Promise.resolve(0)); | ||
| }); | ||
|
|
||
| it('throws error if unsupported package manager specified', () => { | ||
| return expect(save('ant')).rejects.toThrowError('unknown package manager specified: ant'); | ||
| }); | ||
|
|
||
| describe('for maven', () => { | ||
| it('uploads cache even if no pom.xml found', async () => { | ||
| await save('maven'); | ||
| expect(spyCacheSave).toBeCalled(); | ||
| expect(spyWarning).not.toBeCalled(); | ||
| expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); | ||
| }); | ||
| it('uploads cache', async () => { | ||
| createFile(join(workspace, 'pom.xml')); | ||
|
|
||
| await save('maven'); | ||
| expect(spyCacheSave).toBeCalled(); | ||
| expect(spyWarning).not.toBeCalled(); | ||
| expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); | ||
| }); | ||
| }); | ||
| describe('for gradle', () => { | ||
| it('uploads cache even if no build.gradle found', async () => { | ||
| await save('gradle'); | ||
| expect(spyCacheSave).toBeCalled(); | ||
| expect(spyWarning).not.toBeCalled(); | ||
| expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); | ||
| }); | ||
| it('uploads cache based on build.gradle', async () => { | ||
| createFile(join(workspace, 'build.gradle')); | ||
|
|
||
| await save('gradle'); | ||
| expect(spyCacheSave).toBeCalled(); | ||
| expect(spyWarning).not.toBeCalled(); | ||
| expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); | ||
| }); | ||
| it('uploads cache based on build.gradle.kts', async () => { | ||
| createFile(join(workspace, 'build.gradle.kts')); | ||
|
|
||
| await save('gradle'); | ||
| expect(spyCacheSave).toBeCalled(); | ||
| expect(spyWarning).not.toBeCalled(); | ||
| expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/)); | ||
| }); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| function createFile(path: string) { | ||
| core.info(`created a file at ${path}`); | ||
| fs.writeFileSync(path, ''); | ||
| } | ||
|
|
||
| function projectRoot(workspace: string): string { | ||
| if (os.platform() === 'darwin') { | ||
| return `/private${workspace}`; | ||
| } else { | ||
| return workspace; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| .gradle | ||
| **/build/ | ||
| !src/**/build/ | ||
|
|
||
| # Ignore Gradle GUI config | ||
| gradle-app.setting | ||
|
|
||
| # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) | ||
| !gradle-wrapper.jar | ||
|
|
||
| # Cache of project | ||
| .gradletasknamecache |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| plugins { | ||
| id 'java' | ||
| } | ||
| repositories { | ||
| mavenCentral() | ||
| } | ||
| dependencies { | ||
| implementation 'org.codehaus.groovy:groovy:1.8.6' | ||
| } | ||
| tasks.register('downloadDependencies') { | ||
| doLast { | ||
| def total = configurations.compileClasspath.inject (0) { sum, file -> | ||
| sum + file.length() | ||
| } | ||
| println total | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| target/ | ||
| pom.xml.tag | ||
| pom.xml.releaseBackup | ||
| pom.xml.versionsBackup | ||
| pom.xml.next | ||
| release.properties | ||
| dependency-reduced-pom.xml | ||
| buildNumber.properties | ||
| .mvn/timing.properties | ||
| # https://github.com/takari/maven-wrapper#usage-without-binary-jar | ||
| .mvn/wrapper/maven-wrapper.jar |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
| <groupId>io.github.actions</groupId> | ||
| <artifactId>setup-java-maven-example</artifactId> | ||
| <version>1.0.0-SNAPSHOT</version> | ||
| <packaging>jar</packaging> | ||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.junit.jupiter</groupId> | ||
| <artifactId>junit-jupiter-api</artifactId> | ||
| <version>5.7.2</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| </project> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.