Daniel Svensson
10/23/2025, 1:57 PMbuild job that compiles everything, and then a couple of downstream jobs that does some stuff with the built artifacts. The build job starts with restoring ~/.gradle/shared_cache/modules-2 and sets the GRADLE_RO_DEP_CACHE environment variable to this and saves that path to CI cache at the end after having rsync'd any delta. Downstream jobs restore that shared cache and maintains their own cache of ~/.gradle/caches/modules-2 with for example runtime dependencies that aren't available in the shared cache. While this works nice I noticed that it's still pretty slow and with --info I noticed what it looks like http lookups of manifests for the dependency verification feature. I was under the impression that this would be a no-op given that I have a warm cache with all my dependencies now, so I put that to the test and added --offline argument to the build and this made the build fail with checksum is missing from verification metadata . So how do I avoid dependency verification needing network access? If I search my local ~/.gradle directory for .asc files, the modules-2 directory is the only one that matches, so these should be available in the cache already. Is this a current limitation that GRADLE_RO_DEP_CACHE doesn't allow for resolving dependency verification signatures? I'm using a checked-in keyring, and have keyservers disabled in the verification-metadata.xml with the goal of not needing network access.Vampire
10/23/2025, 2:04 PMand saves that path to CI cache at the endWhy? You configure it as RO - i.e. read-only - cache, so it should not change during Gradle execution. The RO cache is more for cases where you map one directory into multiple concurrently build agents like into multiple Docker images at once or similar so that it can safely be used concurrently as it does not change but is read-only. To store int he end and restore at next beginning I wouldn't use RO cache.
after having rsync'd any deltaWhere do you get a delta from? You might get additional things form the non-RO cache, but that does not clean up old unused ones. And as I said probably does not make much sense if you don't use it concurrently anyway.
Daniel Svensson
10/23/2025, 2:06 PMVampire
10/23/2025, 2:16 PMVampire
10/23/2025, 2:17 PM$GRADLE_USER_HOME/caches/modules-* excluding *.lock and gc.properties and you should be fine.Vampire
10/23/2025, 2:19 PMBefore downloading an artifact, Gradle attempts to retrieve the artifact’s checksum by downloading an associated,.sha512,.sha256, or.sha1file (attempting each in order)..md5
If the checksum is available, Gradle skips the download if an artifact with the same ID and checksum already exists. However, if the checksum cannot be retrieved from the remote server, Gradle proceeds to download the artifact but will ignore it if it matches an existing one.So it seems to be expected that the checksum is downloaded if you don't have it in the verification data, independent of whether you use RO or RW cache, probably because the checksum file could be manipulated too if the artifact file was manipulated.
Daniel Svensson
10/23/2025, 2:19 PM--refresh-dependencies command would bypass the cache, and not sure if it would do what I wanted anyways.Daniel Svensson
10/23/2025, 2:22 PM_Just cache $GRADLE_USER_HOME/caches/modules-* excluding *.lock and gc.properties and you should be fine._So this is the issue... downstream jobs would restore that, and then fetch their runtime dependencies every invocation, after fetching they would be "indistinguishable" from what the build job cached.
Vampire
10/23/2025, 2:24 PMTo be able to have a separation between build job and downstream jobs caches. Don't want each job to have its own cache of everything, and want all jobs to hit cache.You can still not store a cache in the downstream jobs but restore the build job's cache, can't you?
If it was possible to resolve all dependencies with one command in the build job, that would remove the need to maintain separate caches.There could always be stuff downloaded at task execution time. But other than that, you could just resolve all resolvable configurations, or use the
--write-verification-metadata which also resolves all resolvable configurations.Daniel Svensson
10/23/2025, 2:25 PMverification-metadata.xml? Well that's annoying. The reason I don't have that is to be able to approve DependaBot PRs from trusted projects. If having checksums in that file then each dependency bump needs manual intervention. It's a trade-off, while it would add something, having signature verification is at least a big step up from nothing.Vampire
10/23/2025, 2:26 PMooooh... so "If the checksum is available" == checksum inI guess so, never used verification myself yet.?verification-metadata.xml
Daniel Svensson
10/23/2025, 2:26 PMVampire
10/23/2025, 2:26 PMDaniel Svensson
10/23/2025, 2:26 PMDaniel Svensson
10/23/2025, 2:30 PM<verify-metadata>false</verify-metadata> .. maybe a decent tradeoff, as the jars are still verified.Vampire
10/23/2025, 2:30 PMThe reason I don't have that is to be able to approve DependaBot PRs from trusted projectsMaybe dump Dependabot and use Renovate instead. Renovate is like Dependabot on steroids. I generally dislike such bots in general, but if at all, then I would always use Renovate. Not sure whether it can handle the checksums, but worth a try.
Vampire
10/23/2025, 2:33 PMif (verifiesChecksums || hashTypes.length) {
logger.debug(
'Dependency metadata verification enabled or checksums present - generating checksums',
);
}
Daniel Svensson
10/23/2025, 2:39 PMDaniel Svensson
10/23/2025, 3:22 PMGRADLE_RO_DEP_CACHE turned out to be pointless. While it reduced the network traffic, just caching the complete ~/.gradle/caches (with some manual pruning of .zip/.tar.gz) finishes the build minutes earlier than only caching modules-2 via that shared ro-cache.