Javi
08/20/2024, 1:22 PMJavi
08/20/2024, 1:26 PM.git directory... but it would look really awful and mind-blowing to understand why it is doing that without any comment.Vampire
08/20/2024, 1:35 PMValueSource instead to read the files and then only the output of the ValueSource becomes CC input, but then this action is evaluated on each build run even if CC is reused (to determine whether the CC entry can be reused) and if the CC entry cannot be reused it even is executed a second time in that build, so that action should optimally run quite fast.Javi
08/20/2024, 1:40 PMValueSourceJavi
08/20/2024, 1:40 PMVampire
08/20/2024, 1:44 PMJavi
08/20/2024, 1:48 PMVampire
08/20/2024, 1:49 PMJavi
08/20/2024, 1:49 PMJavi
08/20/2024, 1:50 PMVampire
08/20/2024, 1:50 PMVampire
08/20/2024, 1:50 PMVampire
08/20/2024, 1:50 PMJavi
08/20/2024, 1:52 PM.git directory and the config cache is being reused, so the problem is on another placeVampire
08/20/2024, 2:21 PMJavi
08/20/2024, 2:45 PMJavi
08/20/2024, 2:46 PM- `.git`
- plugin class 'com.javiersc.semver.project.gradle.plugin.SemverProjectPlugin'
- `.git/.probe-b36c736a-3835-4d22-966c-c5e63f3259ef`
- class `org.eclipse.jgit.util.FileUtils`
- `.git/.probe-c1e96c28-ea16-4382-ab17-24e287b661a5`
- class `org.eclipse.jgit.util.FileUtils`Vampire
08/20/2024, 2:57 PM.git/.probe... files are accessed by JGit classes and probably created by https://github.com/eclipse-jgit/jgit/blob/cb0935ab6dbcb2c54f0ea67585e608987c87284e/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java#L508 or https://github.com/eclipse-jgit/jgit/blob/cb0935ab6dbcb2c54f0ea67585e608987c87284e/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java#L575 I guess you still do use JGit somewhere at configuration time.
That you locally do not find those probe files is also clear as JGit deletes those probe files after the probing.Javi
08/20/2024, 2:58 PMVampire
08/20/2024, 2:58 PMJavi
08/20/2024, 2:58 PMVampire
08/20/2024, 2:58 PMJavi
08/20/2024, 2:58 PMVampire
08/20/2024, 2:59 PMVampire
08/20/2024, 2:59 PMVampire
08/20/2024, 3:00 PMJavi
08/20/2024, 3:01 PMJavi
08/20/2024, 3:47 PMJavi
08/20/2024, 5:24 PMVampire
08/20/2024, 7:27 PMorg.gradle.configuration-cache.inputs.unsafe.ignore.file-system-check to exclude that file, but as the name suggests, it is unsafe and questionable. :-)Javi
08/20/2024, 7:37 PMVampire
08/20/2024, 7:40 PMorg.gradle.configuration-cache.internal.debug can also shed some light?Vampire
08/20/2024, 7:47 PMI can't reproduce it locally, I don't even know what are those files tbh.
Why not? I told you
Javi
08/20/2024, 7:50 PMWhy not? I told youI am doing exactly the same as I do on CI and the issue is not happening
Check your local CC report, I'd guess you have these entries there tooI haven't those entries, the associated files do not exist on my machine.
Javi
08/20/2024, 7:51 PMVampire
08/20/2024, 7:53 PMVampire
08/20/2024, 7:53 PMVampire
08/20/2024, 7:53 PMVampire
08/20/2024, 7:54 PMVampire
08/20/2024, 7:54 PMJavi
08/20/2024, 7:56 PMVampire
08/20/2024, 8:00 PMVampire
08/20/2024, 8:04 PMreadFromConfig returns a non-empty value.
So I'd say you can very well prevent those files to be generated by doing some config.Vampire
08/20/2024, 8:04 PMJavi
08/20/2024, 8:15 PMprovider wouldn't be a problem, no?Vampire
08/20/2024, 8:16 PMJavi
08/20/2024, 8:19 PMVampire
08/20/2024, 8:20 PMJavi
08/20/2024, 8:21 PMVampire
08/20/2024, 8:22 PMJavi
08/20/2024, 10:10 PMVampire
08/20/2024, 10:12 PMJavi
08/20/2024, 10:14 PMJavi
08/20/2024, 11:45 PMJavi
08/21/2024, 12:46 AMpublic class SemverProjectPlugin : Plugin<Project> {
override fun apply(target: Project) {
target.tasks.register("printSemver") {
it.doNotTrackState("foo")
}
//target.config()
}
}
and I am not even adding JGit as dependency... the issue is still thereJavi
08/21/2024, 12:47 AMVampire
08/21/2024, 8:09 AMDo you know if there is a feature request about getting the trace of this kind of issues in the config cache report?None I'm aware of.
and I am not even adding JGit as dependency... the issue is still thereMaybe set a breakpoint at the lines I linked you to and debug the build to see where it is executed?
Javi
08/21/2024, 8:54 AMJavi
08/21/2024, 8:55 AMJavi
08/21/2024, 9:05 AMJavi
08/21/2024, 9:16 AMorg.gradle.configuration-cache.inputs.unsafe.ignore.file-system-checkJavi
08/21/2024, 9:16 AMJavi
08/21/2024, 11:02 AMval gradleVersionProvider: Provider<String> = VersionValueSource.register(this)
version = VersionProperty(gradleVersionProvider)
Those lanes are provoking the issue.
The registration of the value source is
fun register(project: Project): Provider<String> =
project.providers.of(VersionValueSource::class) { valueSourceSpec ->
val parameters: Params = valueSourceSpec.parameters
val semverExtension: SemverExtension = project.semverExtension
val gitDir: Provider<File> =
project.provider { semverExtension.gitDir.get().asFile }
parameters.versionMapper.set(semverExtension.versionMapper)
parameters.gitDir.set(gitDir)
val commitsMaxCount: Int =
project.commitsMaxCount.orNull ?: semverExtension.commitsMaxCount.get()
parameters.commitsMaxCount.set(commitsMaxCount)
parameters.projectTagPrefix.set(project.projectTagPrefix.get())
parameters.tagPrefixProperty.set(project.tagPrefixProperty.get())
parameters.stageProperty.set(project.stageProperty.orNull)
parameters.scopeProperty.set(project.scopeProperty.orNull)
parameters.creatingSemverTag.set(project.isCreatingSemverTag)
parameters.checkClean.set(project.checkCleanProperty.get())
}
I am not using JGit in any parameter, so I have no clue what it can be happeningJavi
08/21/2024, 11:23 AMversion = VersionProperty(gradleVersionProvider)
If I comment that line it works
val gradleVersionProvider: Provider<String> = VersionValueSource.register(this)
version = "1.0.0"
//version = VersionProperty(gradleVersionProvider)
VersionProperty is just
public class VersionProperty(
private val version: Provider<String>,
) : Provider<String> by version {
override fun toString(): String = "${version.orNull}"
}
But as that version: Provider<String> comes from a value source, it is possible to get it on configuration time without affecting the configuration cache, right?Javi
08/21/2024, 11:24 AMversion.toString() in configuration phase would break it?Javi
08/21/2024, 11:31 AMAdam
08/21/2024, 2:00 PMAdam
08/21/2024, 2:01 PMis it possible to add some directories as configuration cache input but ignore some subdirectoriesIf you have a ValueSource, I don't think adding some directories as a CC cache input would give any benefit. ValueSources are always recomputed, even if re-using CC.
Adam
08/21/2024, 2:04 PMval gitDir: Provider<File> =
project.provider { semverExtension.gitDir.get().asFile }
I think about it this way. Basically Gradle intercepts all <http://java.io|java.io>.* calls that access the file system. The exception being if the call is made inside of a ValueSource. And the way Gradle detects that is basically by looking at the stacktrace. But because this call is not technically made inside of a ValueSource, but the configuration of parameters for the ValueSource, it will be treated as a CC input.
But I don't know if that's right or not, the behaviour is undocumented.Javi
08/21/2024, 2:11 PM.git folder with org.gradle.configuration-cache.inputs.unsafe.ignore.file-system-checks?Adam
08/21/2024, 2:35 PM.get().asFileAdam
08/21/2024, 2:36 PMparameters.gitDir.set(semverExtension.gitDir) ?Adam
08/21/2024, 2:55 PM@RequiresOptIn flag https://kotlinlang.org/docs/opt-in-requirements.html and then using it to mark all code that touches JGit. That should help track it, to make sure that JGit is only called from within a ValueSource's obtain(), or a task action.Vampire
08/21/2024, 3:10 PM.probe... files because JGit persists the probe results.
It remembers them in memory and also on disk.
So if you kill the daemon (or use --no-daemon) and make sure that neither git config -l | grep filesystem nor git config --file ~/.config/git/config -l | grep filesystem nor git config --file ~/.config/jgit/config -l | grep filesystem returns any value, you will get the probe values in the CC report.
You can for example use git config --file ~/.config/jgit/config -l | grep filesystem | cut -d = -f 1 | xargs -i git config --file ~/.config/jgit/config --unset "{}" to kill all entries from that file.
The problem is, that JGit does this probing in a different thread by using CompletableFuture.supplyAsync. By this is "circumvents" the ValueSource encapsulation, as only those access are not end up as CC inputs that are done on that same thread that does the configuration. If something is done on a different thread, Gradle cannot see whether this is done in the scope of a ValueSource#obtain or not and thus the file ends up as CC input.Javi
08/21/2024, 3:19 PMwhat about just passing it in like parameters.gitDir.set(semverExtension.gitDir) ?That should be possible, but the
get().asFile is inside of a provider {}, so it shouldn't affect, no?
You should have just debugged the code places I gave you.I tried, but the sources were broken on the IDE, so I could not download/attach them. And the sources I was the owner (the plugin itself), didn't help me.
The problem is, that JGit does this probing in a different thread by usingIs there any way to force using the same thread the. By this is "circumvents" theCompletableFuture.supplyAsyncencapsulation, as only those access are not end up as CC inputs that are done on that same thread that does the configuration. If something is done on a different thread, Gradle cannot see whether this is done in the scope of aValueSourceor not and thus the file ends up as CC input.ValueSource#obtain
ValueSource uses?Vampire
08/21/2024, 3:28 PMVampire
08/21/2024, 3:29 PMprivate static final field in JGitVampire
08/21/2024, 3:30 PMVampire
08/21/2024, 3:32 PM~/.config/jgit/config to the cache config and you will probably start to see CC reusesJavi
08/21/2024, 3:33 PMVampire
08/21/2024, 3:33 PMJavi
08/21/2024, 3:33 PMVampire
08/21/2024, 3:33 PMVampire
08/21/2024, 3:34 PMVampire
08/21/2024, 3:36 PMVampire
08/21/2024, 3:36 PMJavi
08/21/2024, 3:48 PMCalculating task graph as configuration cache cannot be reused because the file system entry '../../../.config/jgit/config' has been created.Vampire
08/21/2024, 3:55 PMJavi
08/21/2024, 4:31 PMJavi
08/21/2024, 4:34 PMVampire
08/21/2024, 4:59 PMVampire
08/21/2024, 5:39 PMcannot not be reused because the file system entry '...' has been created. means that in the run when the CC entry was stored the file was checked for existence but did not exist and now the file does exist so the entry is discarded.
The same happens when you locally run without the file, then again with the file being created by the previous run, but the third call reuses the CC entry.
Your GHA summaries also show that on the 2. and 3. run no cache entries were saved but only entries restored.
This is due to the caculated cache key not being different and so on 2. and 3. run the same cache entry from the 1. run being restored as cache entries are immutable on GHA.
If you amend the commit without actual changes and push again, you should get the same message but a new cache stored.
If you then rerun, the entry should be reused.
If you need the rerun to work, - looking at the setup-gradle action source - you can probably use the GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION environment variable to cleverly influence this.
github.com/gradle/actions/blob/main/docs/setup-gradle.md#cache-keys describes the cache key construction. That environment variable if set is used, otherwise the git-sha as last part of that constructed key.
So if you set this environment variable to ${{ github.sha }}-${{ hashFiles('~/.config/jgit/config') }} I guess it should work immediately on the first rerun even on the same commitVampire
08/21/2024, 5:49 PMVampire
08/21/2024, 5:50 PMVampire
08/21/2024, 5:50 PMVampire
08/21/2024, 5:51 PMVampire
08/21/2024, 5:51 PMJavi
08/21/2024, 6:14 PMJust make a new commit and rerun on that.That works 🙂
Javi
08/21/2024, 6:14 PM