From 910b061d4d71ad2d7a2a777230a98a00638d34e0 Mon Sep 17 00:00:00 2001 From: Daz DeBoer Date: Tue, 25 Aug 2026 09:44:41 -0600 Subject: [PATCH] Add cache-provider: external to skip Gradle User Home caching (#1059) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users relying on an external mechanism to save/restore Gradle User Home (e.g. Develocity Artifact Cache) previously had to set cache-disabled: true, which is confusing since caching isn't actually disabled — it's just not managed by this action — and the Job Summary misleadingly reported caching as "Disabled". cache-provider: external skips Gradle User Home restore/save (same as cache-disabled) but reports a distinct "External" status in the Job Summary, explaining that caching is handled by another provider. --------- Co-authored-by: Claude Sonnet 5 --- .github/workflows/demo-job-summary.yml | 17 ++++++ .../workflows/integ-test-caching-config.yml | 24 ++++++++ dependency-submission/action.yml | 1 + docs/setup-gradle.md | 13 ++++- setup-gradle/action.yml | 1 + sources/src/cache-service-loader.ts | 19 +++++-- sources/src/cache-service.ts | 14 ++++- sources/src/caching-report.ts | 11 +++- sources/src/configuration.ts | 9 ++- .../test/jest/cache-service-loader.test.ts | 55 +++++++++++++++++++ sources/test/jest/caching-report.test.ts | 10 ++++ 11 files changed, 162 insertions(+), 12 deletions(-) diff --git a/.github/workflows/demo-job-summary.yml b/.github/workflows/demo-job-summary.yml index 2229587e..f238d587 100644 --- a/.github/workflows/demo-job-summary.yml +++ b/.github/workflows/demo-job-summary.yml @@ -132,6 +132,23 @@ jobs: working-directory: .github/workflow-samples/kotlin-dsl run: ./gradlew assemble + cache-provider-external: + needs: build-distribution + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Initialize integ-test + uses: ./.github/actions/init-integ-test + + - name: Setup Gradle + uses: ./setup-gradle + with: + cache-provider: external + - name: Build kotlin-dsl project + working-directory: .github/workflow-samples/kotlin-dsl + run: ./gradlew assemble + basic-caching: needs: build-distribution runs-on: ubuntu-latest diff --git a/.github/workflows/integ-test-caching-config.yml b/.github/workflows/integ-test-caching-config.yml index 1495a812..cee2d030 100644 --- a/.github/workflows/integ-test-caching-config.yml +++ b/.github/workflows/integ-test-caching-config.yml @@ -134,6 +134,30 @@ jobs: script: | core.setFailed('No Build Scan detected') + # Test that build scans are captured when caching is external + caching-config-cache-provider-external: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Initialize integ-test + uses: ./.github/actions/init-integ-test + + - name: Setup Gradle + uses: ./setup-gradle + with: + cache-provider: external + - name: Build using Gradle wrapper + id: gradle + working-directory: .github/workflow-samples/groovy-dsl + run: ./gradlew help + - name: Check Build Scan url is captured + if: ${{ !steps.gradle.outputs.build-scan-url }} + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + core.setFailed('No Build Scan detected') + # Test seed the cache with cache-write-only and verify with cache-read-only caching-config-seed-write-only: env: diff --git a/dependency-submission/action.yml b/dependency-submission/action.yml index e325751a..73c87630 100644 --- a/dependency-submission/action.yml +++ b/dependency-submission/action.yml @@ -31,6 +31,7 @@ inputs: Specifies the caching implementation to use. 'enhanced' (default) uses the full-featured commercial caching service (gradle-actions-caching). 'basic' uses a simple open-source caching implementation based on GitHub Actions cache. + 'external' disables Gradle User Home caching by this action, for use when Gradle User Home is already saved and restored by another mechanism (e.g. Develocity Artifact Cache). required: false default: 'enhanced' diff --git a/docs/setup-gradle.md b/docs/setup-gradle.md index d3dd22ef..2cf0fa21 100644 --- a/docs/setup-gradle.md +++ b/docs/setup-gradle.md @@ -133,6 +133,7 @@ You choose which provider to use via the `cache-provider` input: - **`enhanced`** (default): Uses the full-featured commercial `gradle-actions-caching` library. Provides advanced features like fine-grained cache entries, intelligent cache cleanup, and deduplication. See [Enhanced Caching](#enhanced-caching) for details. - **`basic`**: A fully open-source (MIT) caching implementation built on the standard GitHub Actions cache (`@actions/cache`). Uses the same caching strategy as `actions/setup-java` with `cache: gradle`. See [Basic Caching](#basic-caching) for details. +- **`external`**: Disables Gradle User Home caching by this action, for use when another mechanism already saves and restores Gradle User Home. See [Using an external cache provider](#using-an-external-cache-provider) for details. ```yaml # Use the open-source basic cache provider @@ -185,7 +186,17 @@ Specifically: - Avoid using `actions/cache` configured to cache the Gradle User Home, [as described in this example](https://github.com/actions/cache/blob/main/examples.md#java---gradle). - Avoid using `actions/setup-java` with the `cache: gradle` option, [as described here](https://github.com/actions/setup-java#caching-gradle-dependencies). -Using either of these mechanisms may interfere with the caching provided by this action. If you choose to use a different mechanism to save and restore the Gradle User Home, you should disable the caching provided by this action, as described above. +Using either of these mechanisms may interfere with the caching provided by this action. If you choose to use a different mechanism to save and restore the Gradle User Home, you should disable the caching provided by this action, as described above, or [use `cache-provider: external`](#using-an-external-cache-provider) if that mechanism is a dedicated Gradle User Home cache. + +#### Using an external cache provider + +If Gradle User Home is already saved and restored by another mechanism — for example the [Develocity Artifact Cache](https://github.com/gradle/actions-caching) — set `cache-provider: external` rather than `cache-disabled: true`. + +Both settings stop `setup-gradle` from restoring or saving Gradle User Home, but `cache-provider: external` reflects the actual reason: caching is still happening, just not through this action. It also updates the Job Summary to say that caching was handled externally, rather than implying that caching was turned off. + +```yaml +cache-provider: external +``` ## Enhanced Caching diff --git a/setup-gradle/action.yml b/setup-gradle/action.yml index 864def28..6130fa36 100644 --- a/setup-gradle/action.yml +++ b/setup-gradle/action.yml @@ -14,6 +14,7 @@ inputs: Specifies the caching implementation to use. 'enhanced' (default) uses the full-featured commercial caching service (gradle-actions-caching). 'basic' uses a simple open-source caching implementation based on GitHub Actions cache. + 'external' disables Gradle User Home caching by this action, for use when Gradle User Home is already saved and restored by another mechanism (e.g. Develocity Artifact Cache). required: false default: 'enhanced' diff --git a/sources/src/cache-service-loader.ts b/sources/src/cache-service-loader.ts index f7e7166f..920d1e9a 100644 --- a/sources/src/cache-service-loader.ts +++ b/sources/src/cache-service-loader.ts @@ -5,14 +5,18 @@ import {pathToFileURL} from 'url' import {CacheConfig, CacheProvider} from './configuration' import {BasicCacheService} from './cache-service-basic' import {BuildResult} from './build-results' -import {CacheOptions, CacheReport, CacheService} from './cache-service' +import {CacheOptions, CacheReport, CacheService, CacheStatus} from './cache-service' import {ProviderNote} from './caching-report' const ENHANCED_CACHE_MESSAGE = `Enhanced Caching: This build is using the proprietary 'gradle-actions-caching' provider for optimized caching support. See https://github.com/gradle/actions/blob/main/DISTRIBUTION.md for terms of use and opt-out instructions.` const BASIC_CACHE_MESSAGE = `Basic Caching: This build uses the basic open-source caching provider. For faster builds and advanced features, consider switching to the Enhanced Caching provider. See https://github.com/gradle/actions/blob/main/DISTRIBUTION.md for details.` +const EXTERNAL_CACHE_MESSAGE = `External Caching: Gradle User Home is managed by an external caching provider. This action will not restore or save Gradle User Home.` + class NoOpCacheService implements CacheService { + constructor(private readonly status: CacheStatus) {} + async restore(_gradleUserHome: string, _cacheOptions: CacheOptions): Promise { return } @@ -22,14 +26,19 @@ class NoOpCacheService implements CacheService { _buildResults: BuildResult[], _cacheOptions: CacheOptions ): Promise { - return {status: 'disabled', entries: []} + return {status: this.status, entries: []} } } export async function getCacheService(cacheConfig: CacheConfig): Promise { + if (cacheConfig.getCacheProvider() === CacheProvider.External) { + logCacheMessage(EXTERNAL_CACHE_MESSAGE) + return new NoOpCacheService('external') + } + if (cacheConfig.isCacheDisabled()) { logCacheMessage('Cache is disabled: will not restore state from previous builds.') - return new NoOpCacheService() + return new NoOpCacheService('disabled') } if (cacheConfig.getCacheProvider() === CacheProvider.Basic) { @@ -43,10 +52,10 @@ export async function getCacheService(cacheConfig: CacheConfig): Promise