Gradle build cache
Gradle remote build cache for GitHub Actions, served by Magic Cache from your own S3 bucket. One action input, no Develocity or cache node to run.
Magic Cache serves Gradle’s HTTP build cache ↗ from the RunsOn agent on every runner. Task outputs are stored in the cache bucket of your stack and shared between jobs, branches and pull requests while they build. Gradle 7.6 or later.
Availability#
Since v3.6.0, on runners with Magic Cache (extras=s3-cache), with Flex and Fleet. The Overview covers how build tool caches are scoped and stored.
Enable it#
jobs: build: runs-on: runs-on=${{ github.run_id }}/runner=16cpu-linux-x64/extras=s3-cache steps: - uses: runs-on/action@v2 with: remote_cache: gradle - uses: actions/checkout@v5 - uses: gradle/actions/setup-gradle@v6 # the distribution and dependencies - run: ./gradlew build --build-cacheBuilds use the remote cache when they have the build cache on, with org.gradle.caching=true in gradle.properties or --build-cache. The action writes its init script in Gradle’s user home; when GRADLE_USER_HOME is unset, it sets it to ~/.gradle, so that container jobs, whose HOME is not the account’s home, find the script. A build that configures an enabled remote cache of its own, such as Develocity’s, keeps it.
The build cache holds task outputs, not Gradle’s distribution, dependencies or compiled build scripts: keep setup-gradle for those. setup-gradle saves its cache from the default branch only, so on a pull request, every push rebuilds what earlier pushes changed. remote_cache: gradle keeps those outputs in the pull request’s scope, and shares them between parallel jobs.
On android/nowinandroid ↗ (assembleDemoDebug testDemoDebugUnitTest) on a 16 vCPU runner, the build took about 170 seconds without a cache:
| Build step | No cache | remote_cache: gradle | setup-gradle | Both |
|---|---|---|---|---|
| Cold | 172–182 s | 174–177 s | – | – |
| Same commit again, on a new runner | 168–173 s | 74–76 s | 19 s | 21 s |
- Storing costs nothing measurable: a cold build stores every task output as it runs.
- Without
setup-gradle, most of the remaining time is spent downloading dependencies, whichsetup-gradlecaches.
The init script names the job’s cache address, which changes from one job to the next, so a configuration cache ↗ restored from another job is not reused.