Skip to content

Commit b0cbac4

Browse files
committed
Exclude cc-keystore from cache bundles
The configuration cache encryption keystore is derived from GRADLE_ENCRYPTION_KEY and is machine-specific. Caching it causes failures when restored on a worker with a different key.
1 parent afd0143 commit b0cbac4

2 files changed

Lines changed: 53 additions & 4 deletions

File tree

cmd/gradle-cache/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,18 @@ var cacheExclusions = []string{
891891
".tmp",
892892
"gc.properties",
893893
"*.lock",
894+
895+
// cc-keystore is the configuration cache encryption keystore, generated
896+
// per-machine from the GRADLE_ENCRYPTION_KEY environment variable. It must
897+
// not be cached because it is tied to the specific key used to create it —
898+
// restoring it on a worker with a different (or missing) key causes Gradle
899+
// to fail when reading the configuration cache.
900+
//
901+
// To use configuration cache encryption in CI, set GRADLE_ENCRYPTION_KEY to
902+
// a stable secret value in the build environment rather than relying on the
903+
// keystore file. Gradle will regenerate the keystore automatically from the
904+
// environment variable on each worker.
905+
"cc-keystore",
894906
}
895907

896908
// wrapperZipExclusion is a path-based tar --exclude pattern that removes

cmd/gradle-cache/main_test.go

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,36 @@ import (
1616

1717
// ─── Pure unit tests ────────────────────────────────────────────────────────
1818

19+
func TestIsExcludedCache(t *testing.T) {
20+
excluded := []string{
21+
"daemon",
22+
".tmp",
23+
"gc.properties",
24+
"cc-keystore",
25+
"foo.lock",
26+
"gradle-cache.lock",
27+
}
28+
for _, name := range excluded {
29+
if !isExcludedCache(name) {
30+
t.Errorf("expected %q to be excluded", name)
31+
}
32+
}
33+
34+
allowed := []string{
35+
"modules-2",
36+
"transforms-4",
37+
"wrapper",
38+
"caches",
39+
"foo.jar",
40+
"build.gradle.kts",
41+
}
42+
for _, name := range allowed {
43+
if isExcludedCache(name) {
44+
t.Errorf("expected %q to NOT be excluded", name)
45+
}
46+
}
47+
}
48+
1949
func TestBundleFilename(t *testing.T) {
2050
tests := []struct {
2151
cacheKey string
@@ -428,6 +458,9 @@ func TestTarZstdRoundTrip(t *testing.T) {
428458
gradleHome := filepath.Join(srcDir, "gradle-home")
429459
must(t, os.MkdirAll(filepath.Join(gradleHome, "caches", "modules"), 0o755))
430460
must(t, os.WriteFile(filepath.Join(gradleHome, "caches", "modules", "entry.bin"), []byte("gradle data"), 0o644))
461+
// cc-keystore should be excluded
462+
must(t, os.MkdirAll(filepath.Join(gradleHome, "caches", "8.14.3", "cc-keystore"), 0o755))
463+
must(t, os.WriteFile(filepath.Join(gradleHome, "caches", "8.14.3", "cc-keystore", "keystore.bin"), []byte("secret"), 0o644))
431464

432465
// wrapper/ source (under gradle-home) — includes a .zip that should be excluded
433466
must(t, os.MkdirAll(filepath.Join(gradleHome, "wrapper", "dists", "gradle-8.14.3-bin", "abc123"), 0o755))
@@ -470,10 +503,14 @@ func TestTarZstdRoundTrip(t *testing.T) {
470503
}
471504
}
472505

473-
// Verify wrapper zip was excluded from the archive.
474-
excludedZip := filepath.Join(dstDir, "wrapper/dists/gradle-8.14.3-bin/abc123/gradle-8.14.3-bin.zip")
475-
if _, err := os.Stat(excludedZip); err == nil {
476-
t.Error("wrapper zip should have been excluded from archive")
506+
// Verify excluded files are absent from the archive.
507+
for _, rel := range []string{
508+
"wrapper/dists/gradle-8.14.3-bin/abc123/gradle-8.14.3-bin.zip",
509+
"caches/8.14.3/cc-keystore/keystore.bin",
510+
} {
511+
if _, err := os.Stat(filepath.Join(dstDir, rel)); err == nil {
512+
t.Errorf("%s should have been excluded from archive", rel)
513+
}
477514
}
478515

479516
// Verify file contents round-trip correctly.

0 commit comments

Comments
 (0)