From c999154b1f49a1d81018d696d0cbe259d9842be1 Mon Sep 17 00:00:00 2001 From: Daz DeBoer Date: Wed, 18 Mar 2026 14:27:09 -0600 Subject: [PATCH] Remove configuration-cache support (#884) Removes support for configuration-cache extraction and restore from the caching workflow and related source code. Configuration-cache support only worked for a limited set of projects (gradle/actions#21), and we plan to reimplement this properly as part of the `gradle-actions-caching` project. The main impact is simplification of the caching logic, focusing only on common Gradle artifacts. The `ConfigurationCacheEntryExtractor` class and related logic were deleted from `sources/src/caching/gradle-home-extry-extractor.ts`. --- ...integ-test-restore-configuration-cache.yml | 235 ------------------ .../workflows/suite-integ-test-caching.yml | 8 - .../caching/gradle-home-extry-extractor.ts | 114 --------- sources/src/caching/gradle-user-home-cache.ts | 8 +- 4 files changed, 2 insertions(+), 363 deletions(-) delete mode 100644 .github/workflows/integ-test-restore-configuration-cache.yml diff --git a/.github/workflows/integ-test-restore-configuration-cache.yml b/.github/workflows/integ-test-restore-configuration-cache.yml deleted file mode 100644 index da8f6754..00000000 --- a/.github/workflows/integ-test-restore-configuration-cache.yml +++ /dev/null @@ -1,235 +0,0 @@ -name: Test restore configuration-cache - -on: - workflow_call: - inputs: - cache-key-prefix: - type: string - default: '0' - runner-os: - type: string - default: '["ubuntu-latest"]' - skip-dist: - type: boolean - default: false - secrets: - GRADLE_ENCRYPTION_KEY: - required: true - -env: - SKIP_DIST: ${{ inputs.skip-dist }} - GRADLE_BUILD_ACTION_CACHE_KEY_PREFIX: restore-configuration-cache-${{ inputs.cache-key-prefix }} - -permissions: - contents: read - -jobs: - restore-cc-seed-build-groovy: - env: - GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-groovy - strategy: - max-parallel: 1 - fail-fast: false - matrix: - os: ${{fromJSON(inputs.runner-os)}} - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Initialize integ-test - uses: ./.github/actions/init-integ-test - - - name: Setup Gradle - uses: ./setup-gradle - with: - cache-read-only: false # For testing, allow writing cache entries on non-default branches - cache-write-only: true # Ensure we start with a clean cache entry - cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Groovy build with configuration-cache enabled - working-directory: .github/workflow-samples/groovy-dsl - run: gradle test --configuration-cache - - restore-cc-verify-build-groovy: - env: - GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-groovy - GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_1 - needs: restore-cc-seed-build-groovy - strategy: - max-parallel: 1 - fail-fast: false - matrix: - os: ${{fromJSON(inputs.runner-os)}} - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Initialize integ-test - uses: ./.github/actions/init-integ-test - - - name: Setup Gradle - uses: ./setup-gradle - with: - cache-read-only: false - cache-cleanup: on-success - cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Groovy build with configuration-cache enabled - id: execute - working-directory: .github/workflow-samples/groovy-dsl - run: gradle test --configuration-cache - - name: Verify configuration-cache hit - shell: bash - run: | - if [ -e ".github/workflow-samples/groovy-dsl/task-configured.txt" ]; then - echo "Configuration cache was not used - task was configured unexpectedly" - exit 1 - fi - - # Ensure that cache-cleanup doesn't remove all necessary files - restore-cc-verify-no-cache-cleanup-groovy: - env: - GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-groovy - GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_2 - needs: restore-cc-verify-build-groovy - strategy: - max-parallel: 1 - fail-fast: false - matrix: - os: ${{fromJSON(inputs.runner-os)}} - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Initialize integ-test - uses: ./.github/actions/init-integ-test - - - name: Setup Gradle - uses: ./setup-gradle - with: - cache-read-only: true - cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Groovy build with configuration-cache enabled - id: execute - working-directory: .github/workflow-samples/groovy-dsl - run: gradle test --configuration-cache - - name: Verify configuration-cache hit - shell: bash - run: | - if [ -e ".github/workflow-samples/groovy-dsl/task-configured.txt" ]; then - echo "Configuration cache was not used - task was configured unexpectedly" - exit 1 - fi - - # Check that the build can run when no extracted cache entries are restored - restore-cc-gradle-user-home-not-fully-restored: - env: - GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-groovy - GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_x - needs: restore-cc-seed-build-groovy - strategy: - max-parallel: 1 - fail-fast: false - matrix: - os: ${{fromJSON(inputs.runner-os)}} - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Initialize integ-test - uses: ./.github/actions/init-integ-test - - - name: Setup Gradle with no extracted cache entries restored - uses: ./setup-gradle - env: - GRADLE_BUILD_ACTION_SKIP_RESTORE: "generated-gradle-jars|wrapper-zips|java-toolchains|instrumented-jars|dependencies|kotlin-dsl" - with: - cache-read-only: true - cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Check execute Gradle build with configuration cache enabled (but not restored) - working-directory: .github/workflow-samples/groovy-dsl - run: gradle test --configuration-cache - - restore-cc-seed-build-kotlin: - env: - GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-kotlin - strategy: - max-parallel: 1 - fail-fast: false - matrix: - os: ${{fromJSON(inputs.runner-os)}} - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Initialize integ-test - uses: ./.github/actions/init-integ-test - - - name: Setup Gradle - uses: ./setup-gradle - with: - cache-read-only: false # For testing, allow writing cache entries on non-default branches - cache-write-only: true # Ensure we start with a clean cache entry - cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Execute 'help' with configuration-cache enabled - working-directory: .github/workflow-samples/kotlin-dsl - run: gradle help --configuration-cache - - restore-cc-modify-build-kotlin: - env: - GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-kotlin - GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_1 - needs: restore-cc-seed-build-kotlin - strategy: - max-parallel: 1 - fail-fast: false - matrix: - os: ${{fromJSON(inputs.runner-os)}} - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Initialize integ-test - uses: ./.github/actions/init-integ-test - - - name: Setup Gradle - uses: ./setup-gradle - with: - cache-read-only: false # For testing, allow writing cache entries on non-default branches - cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Execute 'test' with configuration-cache enabled - working-directory: .github/workflow-samples/kotlin-dsl - run: gradle test --configuration-cache - - # Test restore configuration-cache from the third build invocation - restore-cc-verify-build-kotlin: - env: - GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-kotlin - GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_2 - needs: restore-cc-modify-build-kotlin - strategy: - max-parallel: 1 - fail-fast: false - matrix: - os: ${{fromJSON(inputs.runner-os)}} - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Initialize integ-test - uses: ./.github/actions/init-integ-test - - - name: Setup Gradle - uses: ./setup-gradle - with: - cache-read-only: true - cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - - name: Execute 'test' again with configuration-cache enabled - id: execute - working-directory: .github/workflow-samples/kotlin-dsl - run: gradle test --configuration-cache - - name: Verify configuration-cache hit - shell: bash - run: | - if [ -e ".github/workflow-samples/kotlin-dsl/task-configured.txt" ]; then - echo "Configuration cache was not used - task was configured unexpectedly" - exit 1 - fi diff --git a/.github/workflows/suite-integ-test-caching.yml b/.github/workflows/suite-integ-test-caching.yml index 40d5d8fd..e1eca685 100644 --- a/.github/workflows/suite-integ-test-caching.yml +++ b/.github/workflows/suite-integ-test-caching.yml @@ -26,14 +26,6 @@ jobs: runner-os: '${{ inputs.runner-os }}' skip-dist: ${{ inputs.skip-dist }} - restore-configuration-cache: - if: ${{ ! github.event.pull_request.head.repo.fork }} - uses: ./.github/workflows/integ-test-restore-configuration-cache.yml - with: - skip-dist: ${{ inputs.skip-dist }} - secrets: - GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - restore-containerized-gradle-home: uses: ./.github/workflows/integ-test-restore-containerized-gradle-home.yml with: diff --git a/sources/src/caching/gradle-home-extry-extractor.ts b/sources/src/caching/gradle-home-extry-extractor.ts index ffb15acd..7637c64b 100644 --- a/sources/src/caching/gradle-home-extry-extractor.ts +++ b/sources/src/caching/gradle-home-extry-extractor.ts @@ -6,10 +6,8 @@ import * as glob from '@actions/glob' import {CacheEntryListener, CacheListener} from './cache-reporting' import {cacheDebug, hashFileNames, isCacheDebuggingEnabled, restoreCache, saveCache, tryDelete} from './cache-utils' -import {BuildResult, loadBuildResults} from '../build-results' import {CacheConfig, ACTION_METADATA_DIR} from '../configuration' import {getCacheKeyBase} from './cache-key' -import {versionIsAtLeast} from '../execution/gradle' const SKIP_RESTORE_VAR = 'GRADLE_BUILD_ACTION_SKIP_RESTORE' const CACHE_PROTOCOL_VERSION = 'v1' @@ -65,15 +63,6 @@ class ExtractedCacheEntryDefinition { this.uniqueFileNames = false return this } - - /** - * Specify that the cache entry, should not be saved for some reason, even though the contents exist. - * This is used to prevent configuration-cache entries being cached when they were generated by Gradle < 8.6, - */ - notCacheableBecause(reason: string): ExtractedCacheEntryDefinition { - this.notCacheableReason = reason - return this - } } /** @@ -362,106 +351,3 @@ export class GradleHomeEntryExtractor extends AbstractEntryExtractor { ] } } - -export class ConfigurationCacheEntryExtractor extends AbstractEntryExtractor { - constructor(gradleUserHome: string, cacheConfig: CacheConfig) { - super(gradleUserHome, 'configuration-cache', cacheConfig) - } - - /** - * Handle the case where Gradle User Home has not been fully restored, so that the configuration-cache - * entry is not reusable. - */ - async restore(listener: CacheListener): Promise { - if (!listener.fullyRestored) { - this.markNotRestored(listener, 'Gradle User Home was not fully restored') - return - } - - if (!this.cacheConfig.getCacheEncryptionKey()) { - this.markNotRestored(listener, 'Encryption Key was not provided') - return - } - - return await super.restore(listener) - } - - private markNotRestored(listener: CacheListener, reason: string): void { - const cacheEntries = this.loadExtractedCacheEntries() - if (cacheEntries.length > 0) { - core.info(`Not restoring configuration-cache state, as ${reason}`) - for (const cacheEntry of cacheEntries) { - listener.entry(cacheEntry.pattern).markNotRestored(reason) - } - - // Update the results file based on no entries restored - this.saveMetadataForCacheResults([]) - } - } - - async extract(listener: CacheListener): Promise { - if (!this.cacheConfig.getCacheEncryptionKey()) { - const cacheEntryDefinitions = this.getExtractedCacheEntryDefinitions() - if (cacheEntryDefinitions.length > 0) { - core.info('Not saving configuration-cache state, as no encryption key was provided') - for (const cacheEntry of cacheEntryDefinitions) { - listener.entry(cacheEntry.pattern).markNotSaved('No encryption key provided') - } - } - return - } - - await super.extract(listener) - } - - /** - * Extract cache entries for the configuration cache in each project. - */ - protected getExtractedCacheEntryDefinitions(): ExtractedCacheEntryDefinition[] { - // Group BuildResult by existing configCacheDir - const groupedResults = this.getConfigCacheDirectoriesWithAssociatedBuildResults() - - return Object.entries(groupedResults).map(([configCachePath, pathResults]) => { - // Create a entry definition for each unique configuration cache directory - const definition = new ExtractedCacheEntryDefinition( - 'configuration-cache', - configCachePath, - true - ).withNonUniqueFileNames() - - // If any associated build result used Gradle < 8.6, then mark it as not cacheable - if ( - pathResults.find(result => { - return !versionIsAtLeast(result.gradleVersion, '8.6.0') - }) - ) { - core.info( - `Not saving config-cache data for ${configCachePath}. Configuration cache data is only saved for Gradle 8.6+` - ) - definition.notCacheableBecause('Configuration cache data only saved for Gradle 8.6+') - } - return definition - }) - } - - private getConfigCacheDirectoriesWithAssociatedBuildResults(): Record { - return loadBuildResults().results.reduce( - (acc, buildResult) => { - // For each build result, find the config-cache dir - const configCachePath = path.resolve(buildResult.rootProjectDir, '.gradle/configuration-cache') - // Ignore case where config-cache dir doesn't exist - if (!fs.existsSync(configCachePath)) { - return acc - } - - // Group by unique config cache directories and collect associated build results - if (!acc[configCachePath]) { - acc[configCachePath] = [] - } - acc[configCachePath].push(buildResult) - return acc - }, - {} as Record - ) - } -} diff --git a/sources/src/caching/gradle-user-home-cache.ts b/sources/src/caching/gradle-user-home-cache.ts index 55fc6504..7dc27cd2 100644 --- a/sources/src/caching/gradle-user-home-cache.ts +++ b/sources/src/caching/gradle-user-home-cache.ts @@ -8,7 +8,7 @@ import {generateCacheKey} from './cache-key' import {CacheListener} from './cache-reporting' import {saveCache, restoreCache, cacheDebug, isCacheDebuggingEnabled, tryDelete} from './cache-utils' import {CacheConfig, ACTION_METADATA_DIR} from '../configuration' -import {GradleHomeEntryExtractor, ConfigurationCacheEntryExtractor} from './gradle-home-extry-extractor' +import {GradleHomeEntryExtractor} from './gradle-home-extry-extractor' import {getPredefinedToolchains, mergeToolchainContent, readResourceFileAsString} from './gradle-user-home-utils' const RESTORED_CACHE_KEY_KEY = 'restored-cache-key' @@ -82,7 +82,6 @@ export class GradleUserHomeCache { async afterRestore(listener: CacheListener): Promise { await this.debugReportGradleUserHomeSize('as restored from cache') await new GradleHomeEntryExtractor(this.gradleUserHome, this.cacheConfig).restore(listener) - await new ConfigurationCacheEntryExtractor(this.gradleUserHome, this.cacheConfig).restore(listener) await this.deleteExcludedPaths() await this.debugReportGradleUserHomeSize('after restoring common artifacts') } @@ -130,10 +129,7 @@ export class GradleUserHomeCache { async beforeSave(listener: CacheListener): Promise { await this.debugReportGradleUserHomeSize('before saving common artifacts') await this.deleteExcludedPaths() - await Promise.all([ - new GradleHomeEntryExtractor(this.gradleUserHome, this.cacheConfig).extract(listener), - new ConfigurationCacheEntryExtractor(this.gradleUserHome, this.cacheConfig).extract(listener) - ]) + await new GradleHomeEntryExtractor(this.gradleUserHome, this.cacheConfig).extract(listener) await this.debugReportGradleUserHomeSize( "after extracting common artifacts (only 'caches' and 'notifications' will be stored)" )