Skip to content

Opt the refreshVersions tasks out of the configuration cache#739

Open
sproctor wants to merge 1 commit into
Splitties:mainfrom
sproctor:fix-configuration-cache-rootdir
Open

Opt the refreshVersions tasks out of the configuration cache#739
sproctor wants to merge 1 commit into
Splitties:mainfrom
sproctor:fix-configuration-cache-rootdir

Conversation

@sproctor

Copy link
Copy Markdown

Problem

refreshVersions intermittently fails with:

Reusing configuration cache.
> Task :refreshVersions FAILED
> lateinit property rootDir has not been initialized

The refreshVersions and refreshVersionsCleanup task actions read state that is initialized during the configuration phase — in particular OutputFile.rootDir, which is set from the plugin's apply block via OutputFile.init(project). When an existing configuration cache entry is reused, the configuration phase is skipped, so that state is never initialized and the task fails at execution time. This explains why the failure only shows up when the cache is reused (and is therefore intermittent), as reported in #738.

Fix

These tasks were never intended to be compatible with the configuration cache: they perform network I/O and rewrite build files (versions.properties, the version catalog, settings files). Their siblings already opt out via skipConfigurationCache() — for example refreshVersionsMigrate, buildSrcLibs, and migrateToRefreshVersionsDependenciesConstants. The two core tasks registered in RefreshVersionsCorePlugin were simply missing that call.

This change adds skipConfigurationCache() (which calls notCompatibleWithConfigurationCache(...)) to both refreshVersions and refreshVersionsCleanup. Gradle then refuses to store an entry for builds that run them, so a stale entry can never be reused in a fresh process.

Test

Adds a Gradle TestKit functional test (ConfigurationCacheRegressionTest) that runs refreshVersions --configuration-cache against a fixture project and asserts the task is reported as incompatible with the configuration cache and that no entry is stored. It fails on the unpatched plugin (an entry is stored) and passes with the fix.

The functional tests live in a dedicated functionalTest source set that runs on Java 21, because TestKit launches the Gradle version under test (9.x), which requires Java 17+, while the rest of the module compiles and unit-tests against Java 8.

Fixes #738

🤖 Generated with Claude Code

The `refreshVersions` and `refreshVersionsCleanup` tasks read state that is
initialized during the configuration phase (notably `OutputFile.rootDir`, set
in the plugin's `apply` block) from their task actions. When a configuration
cache entry is reused in a fresh daemon, the configuration phase is skipped, so
that state is never initialized and the task fails at execution with:

    lateinit property rootDir has not been initialized

This matches the intermittent failure reported in Splitties#738: it only happens when an
existing configuration cache entry is reused.

These tasks were never meant to be configuration-cache compatible (they perform
network I/O and rewrite build files), and their siblings such as
`refreshVersionsMigrate` and `buildSrcLibs` already call
`skipConfigurationCache()`. This applies the same opt-out to the two tasks that
were missing it, so Gradle no longer stores or reuses an entry for them.

Also adds a Gradle TestKit functional test that verifies the tasks are reported
as incompatible with the configuration cache and that no entry is stored. The
functional test suite runs on Java 21 because TestKit launches the Gradle
version under test, which requires Java 17+.

Fixes Splitties#738

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Intermittent failure: lateinit property rootDir has not been initialized

1 participant