nemerosa / versioning

Gradle plug-in to generate version information from the SCM branch (Git or Svn)
MIT License
200 stars 40 forks source link

Support Gradle configuration cache #97

Open sdavids opened 6 months ago

sdavids commented 6 months ago
$ mkdir /tmp/test && cd "$_"
$ gradle init --type java-library --java-version 21 --project-name test --dsl groovy --test-framework junit-jupiter --no-comments --no-incubating --quiet
$ perl -i -l -p -e "print \"    id 'net.nemerosa.versioning' version '2.8.2'\" if $. == 4" lib/build.gradle
$ printf '\nversioning {}\nversion = versioning.info.full\n' >> lib/build.gradle
$ git init --quiet
$ git add -A
$ git commit --quiet -m "initial"
$ ./gradlew --configuration-cache --quiet clean

FAILURE: Build failed with an exception.

* Where:
Build file '/private/tmp/test/lib/build.gradle' line: 32

* What went wrong:
Configuration cache problems found in this build.

2 problems were found storing the configuration cache.
- Build file 'lib/build.gradle': external process started 'git --version'
  See https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes
- Build file 'lib/build.gradle': external process started 'git config --system --edit'
  See https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes

See the complete report at file:///private/tmp/test/build/reports/configuration-cache/2cvh062oate61b7yhx8pzmmbf/3h3vaqnt0bpkufj7xky7uxoi0/configuration-cache-report.html
> Starting an external process 'git --version' during configuration time is unsupported.
> Starting an external process 'git config --system --edit' during configuration time is unsupported.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 2s
$ gradle --version

------------------------------------------------------------
Gradle 8.7
------------------------------------------------------------

Build time:   2024-03-22 15:52:46 UTC
Revision:     650af14d7653aa949fce5e886e685efc9cf97c10

Kotlin:       1.9.22
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          21.0.2 (Eclipse Adoptium 21.0.2+13-LTS)
OS:           Mac OS X 12.7.4 x86_64
$ cat lib/build.gradle

plugins {
    id 'java-library'
    id 'net.nemerosa.versioning' version '2.8.2'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation libs.junit.jupiter

    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

    api libs.commons.math3

    implementation libs.guava
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

tasks.named('test') {
    useJUnitPlatform()
}

versioning {}
version = versioning.info.full

configuration-cache-report.html

    at net.nemerosa.versioning.git.GitInfoService.getInfo(GitInfoService.groovy:37)
    at net.nemerosa.versioning.SCMInfoService$getInfo.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)(3 internal lines hidden)
    at net.nemerosa.versioning.VersioningExtension.computeInfo(VersioningExtension.groovy:195)
    at net.nemerosa.versioning.VersioningExtension.getInfo(VersioningExtension.groovy:182)
    at net.nemerosa.versioning.VersioningExtension_Decorated.getInfo(Unknown Source)

https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes

sdavids commented 6 months ago

Interim solution?

It is possible to declare that a particular task is not compatible with the configuration cache via the Task.notCompatibleWithConfigurationCache() method.

Configuration cache problems found in tasks marked incompatible will no longer cause the build to fail.

https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:task_opt_out

dcoraboeuf commented 6 months ago

Hi,

I see in the first snippet that you're using the version 2.8.2? Is that possible to try with version 3.1.0.

As for the cache configuration issue, I don't know how the call to the external command (git) could be cached and if it even makes sense. So I agree with you that the least bad approach would maybe to mark it as not compatible with the cache.

What do you think?

sdavids commented 5 months ago
$ mkdir /tmp/test && cd "$_"
$ gradle init --type java-library --java-version 21 --project-name test --dsl groovy --test-framework junit-jupiter --no-comments --no-incubating --quiet
$ perl -i -l -p -e "print \"    id 'net.nemerosa.versioning' version '3.1.0'\" if $. == 4" lib/build.gradle
$ printf '\nversioning {}\nversion = versioning.info.full\n' >> lib/build.gradle
$ git init --quiet
$ git add -A
$ git commit --quiet -m "initial"
$ ./gradlew --configuration-cache --quiet clean

FAILURE: Build failed with an exception.

* Where:
Build file '/private/tmp/test/lib/build.gradle' line: 32

* What went wrong:
Configuration cache problems found in this build.

2 problems were found storing the configuration cache.
- Build file 'lib/build.gradle': external process started '/usr/local/bin/git --version'
  See https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes
- Build file 'lib/build.gradle': external process started '/usr/local/bin/git config --system --show-origin --list -z'
  See https://docs.gradle.org/8.7/userguide/configuration_cache.html#config_cache:requirements:external_processes

See the complete report at file:///private/tmp/test/build/reports/configuration-cache/2cvh062oate61b7yhx8pzmmbf/ebyxie6m7vpbm2q7bw5v4bf88/configuration-cache-report.html
> Starting an external process '/usr/local/bin/git --version' during configuration time is unsupported.
> Starting an external process '/usr/local/bin/git config --system --show-origin --list -z' during configuration time is unsupported.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 5s
sdavids commented 5 months ago

The example provided by the Gradle team wraps the git call inside providers.exec:

def gitVersion = providers.exec {
    commandLine("git", "--version")
}.standardOutput.asText.get()

Maybe calls to SCMInfoService should be wrapped in providers.exec or calls to Grgit and SVNClientManager should be wrapped.

There is Gradle Roadmap item this issue might be added to ...

sdavids commented 3 months ago

https://blog.gradle.org/road-to-gradle-9#configuration-cache-improvements

In Gradle 9.0, the Configuration Cache will be the preferred mode of execution, and turning it off will be deprecated.

sdavids commented 3 months ago

Here is what another project using Grgit did:

https://github.com/n0mer/gradle-git-properties/pull/164

1fexd commented 5 hours ago

I was able to work around this by wrapping my calls to versioning.info in a provider:

val provider = project.provider {
    // Intentionally skip cache (not sure if necessary though)
    val info = versioning.computeInfo()
    runCatching { info.tag ?: info.full }.getOrDefault("0.0.0")
}

project.version = provider.get()