Skip to content

Commit e67904b

Browse files
committed
Add key prefix parameter
1 parent fa6234b commit e67904b

10 files changed

Lines changed: 44 additions & 16 deletions

File tree

action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ inputs:
2323
description: AWS region for the S3 bucket.
2424
required: false
2525
default: us-west-2
26+
key-prefix:
27+
description: >
28+
Optional path prefix prepended to all S3 object keys. Useful for
29+
namespacing objects within a shared bucket.
30+
required: false
2631
ref:
2732
description: >
2833
Git ref used to search for a base bundle. On pull_request restores, the

action/src/helpers.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ function backendArgs() {
6565
if (bucket) {
6666
args.push("--bucket", bucket);
6767
if (region) args.push("--region", region);
68+
const keyPrefix = core.getInput("key-prefix");
69+
if (keyPrefix) args.push("--key-prefix", keyPrefix);
6870
} else {
6971
// Default to GitHub Actions cache when no explicit backend is configured.
7072
args.push("--github-actions");

cmd/gradle-cache/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type CLI struct {
3636
type backendFlags struct {
3737
Bucket string `help:"S3 bucket name."`
3838
Region string `help:"AWS region." default:"us-west-2" env:"AWS_REGION"`
39+
KeyPrefix string `help:"Optional path prefix prepended to all S3 object keys." name:"key-prefix"`
3940
CachewURL string `help:"Cachew server URL (e.g. http://localhost:8080). Mutually exclusive with --bucket." name:"cachew-url"`
4041
GithubActions bool `help:"Use the GitHub Actions Cache backend." name:"github-actions"`
4142
}
@@ -82,6 +83,7 @@ func (c *RestoreCmd) Run(ctx context.Context, metrics gradlecache.MetricsClient)
8283
Bucket: c.Bucket,
8384
Region: c.Region,
8485
CachewURL: c.CachewURL,
86+
KeyPrefix: c.KeyPrefix,
8587
CacheKey: c.CacheKey,
8688
GitDir: c.GitDir,
8789
Ref: c.Ref,
@@ -113,6 +115,7 @@ func (c *RestoreDeltaCmd) Run(ctx context.Context, metrics gradlecache.MetricsCl
113115
Bucket: c.Bucket,
114116
Region: c.Region,
115117
CachewURL: c.CachewURL,
118+
KeyPrefix: c.KeyPrefix,
116119
CacheKey: c.CacheKey,
117120
Branch: c.Branch,
118121
GradleUserHome: c.GradleUserHome,
@@ -141,6 +144,7 @@ func (c *SaveCmd) Run(ctx context.Context, metrics gradlecache.MetricsClient) er
141144
Bucket: c.Bucket,
142145
Region: c.Region,
143146
CachewURL: c.CachewURL,
147+
KeyPrefix: c.KeyPrefix,
144148
CacheKey: c.CacheKey,
145149
Commit: c.Commit,
146150
GitDir: c.GitDir,
@@ -169,6 +173,7 @@ func (c *SaveDeltaCmd) Run(ctx context.Context, metrics gradlecache.MetricsClien
169173
Bucket: c.Bucket,
170174
Region: c.Region,
171175
CachewURL: c.CachewURL,
176+
KeyPrefix: c.KeyPrefix,
172177
CacheKey: c.CacheKey,
173178
Branch: c.Branch,
174179
GradleUserHome: c.GradleUserHome,

dist/main/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33589,6 +33589,8 @@ function backendArgs() {
3358933589
if (bucket) {
3359033590
args.push("--bucket", bucket);
3359133591
if (region) args.push("--region", region);
33592+
const keyPrefix = core.getInput("key-prefix");
33593+
if (keyPrefix) args.push("--key-prefix", keyPrefix);
3359233594
} else {
3359333595
// Default to GitHub Actions cache when no explicit backend is configured.
3359433596
args.push("--github-actions");

dist/post/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33589,6 +33589,8 @@ function backendArgs() {
3358933589
if (bucket) {
3359033590
args.push("--bucket", bucket);
3359133591
if (region) args.push("--region", region);
33592+
const keyPrefix = core.getInput("key-prefix");
33593+
if (keyPrefix) args.push("--key-prefix", keyPrefix);
3359233594
} else {
3359333595
// Default to GitHub Actions cache when no explicit backend is configured.
3359433596
args.push("--github-actions");

dist/pre/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33589,6 +33589,8 @@ function backendArgs() {
3358933589
if (bucket) {
3359033590
args.push("--bucket", bucket);
3359133591
if (region) args.push("--region", region);
33592+
const keyPrefix = core.getInput("key-prefix");
33593+
if (keyPrefix) args.push("--key-prefix", keyPrefix);
3359233594
} else {
3359333595
// Default to GitHub Actions cache when no explicit backend is configured.
3359433596
args.push("--github-actions");

gradlecache/gradlecache_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func TestS3Key(t *testing.T) {
204204
},
205205
}
206206
for _, tt := range tests {
207-
if got := s3Key(tt.commit, tt.cacheKey, tt.bundleFile); got != tt.want {
207+
if got := s3Key("", tt.commit, tt.cacheKey, tt.bundleFile); got != tt.want {
208208
t.Errorf("s3Key(%q, %q, %q) = %q, want %q",
209209
tt.commit, tt.cacheKey, tt.bundleFile, got, tt.want)
210210
}
@@ -1460,7 +1460,7 @@ func TestS3BundleStoreRoundTrip(t *testing.T) {
14601460
cacheKey := "apos-beta"
14611461
payload := []byte("bundle contents")
14621462

1463-
legacyKey := "test-bucket/" + s3Key(commit, cacheKey, bundleFilename(cacheKey))
1463+
legacyKey := "test-bucket/" + s3Key("", commit, cacheKey, bundleFilename(cacheKey))
14641464
fs.mu.Lock()
14651465
fs.objects[legacyKey] = payload
14661466
fs.mu.Unlock()

gradlecache/restore.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ type RestoreConfig struct {
204204
Region string
205205
// CachewURL is the cachew server URL. Mutually exclusive with Bucket.
206206
CachewURL string
207+
// KeyPrefix is an optional path prefix prepended to all S3 object keys.
208+
KeyPrefix string
207209
// CacheKey is the bundle identifier (e.g. "my-project:assembleRelease").
208210
CacheKey string
209211
// GitDir is the path to the git repository for history walking. Defaults to ".".
@@ -296,7 +298,7 @@ func Restore(ctx context.Context, cfg RestoreConfig) error {
296298
}
297299
log := cfg.Logger
298300

299-
store, err := newStore(cfg.Bucket, cfg.Region, cfg.CachewURL)
301+
store, err := newStore(cfg.Bucket, cfg.Region, cfg.CachewURL, cfg.KeyPrefix)
300302
if err != nil {
301303
return err
302304
}

gradlecache/save.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type RestoreDeltaConfig struct {
2727
Bucket string
2828
Region string
2929
CachewURL string
30+
KeyPrefix string
3031
CacheKey string
3132
Branch string
3233
GradleUserHome string
@@ -63,7 +64,7 @@ func RestoreDelta(ctx context.Context, cfg RestoreDeltaConfig) error {
6364
return errors.Errorf("caches directory not found at %s — run restore first: %w", cachesDir, err)
6465
}
6566

66-
store, err := newStore(cfg.Bucket, cfg.Region, cfg.CachewURL)
67+
store, err := newStore(cfg.Bucket, cfg.Region, cfg.CachewURL, cfg.KeyPrefix)
6768
if err != nil {
6869
return err
6970
}
@@ -120,6 +121,7 @@ type SaveConfig struct {
120121
Bucket string
121122
Region string
122123
CachewURL string
124+
KeyPrefix string
123125
CacheKey string
124126
Commit string
125127
GitDir string
@@ -173,7 +175,7 @@ func Save(ctx context.Context, cfg SaveConfig) error {
173175
return errors.Errorf("caches directory not found at %s: %w", cachesDir, err)
174176
}
175177

176-
store, err := newStore(cfg.Bucket, cfg.Region, cfg.CachewURL)
178+
store, err := newStore(cfg.Bucket, cfg.Region, cfg.CachewURL, cfg.KeyPrefix)
177179
if err != nil {
178180
return err
179181
}
@@ -267,6 +269,7 @@ type SaveDeltaConfig struct {
267269
Bucket string
268270
Region string
269271
CachewURL string
272+
KeyPrefix string
270273
CacheKey string
271274
Branch string
272275
GradleUserHome string
@@ -345,7 +348,7 @@ func SaveDelta(ctx context.Context, cfg SaveDeltaConfig) error {
345348
return nil
346349
}
347350

348-
store, err := newStore(cfg.Bucket, cfg.Region, cfg.CachewURL)
351+
store, err := newStore(cfg.Bucket, cfg.Region, cfg.CachewURL, cfg.KeyPrefix)
349352
if err != nil {
350353
return err
351354
}

gradlecache/store.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type bundleStore interface {
3333
putStream(ctx context.Context, commit, cacheKey string, r io.Reader) (int64, error)
3434
}
3535

36-
func newStore(bucket, region, cachewURL string) (bundleStore, error) {
36+
func newStore(bucket, region, cachewURL, keyPrefix string) (bundleStore, error) {
3737
if cachewURL != "" {
3838
return newCachewClient(cachewURL), nil
3939
}
@@ -46,42 +46,47 @@ func newStore(bucket, region, cachewURL string) (bundleStore, error) {
4646
if err != nil {
4747
return nil, err
4848
}
49-
return &s3BundleStore{client: client, bucket: bucket}, nil
49+
return &s3BundleStore{client: client, bucket: bucket, keyPrefix: keyPrefix}, nil
5050
}
5151

5252
// ── S3 bundle store ─────────────────────────────────────────────────────────
5353

5454
type s3BundleStore struct {
55-
client *s3Client
56-
bucket string
55+
client *s3Client
56+
bucket string
57+
keyPrefix string // optional path prefix prepended to all object keys
5758
}
5859

5960
func (s *s3BundleStore) stat(ctx context.Context, commit, cacheKey string) (bundleStatInfo, error) {
60-
obj, err := s.client.stat(ctx, s.bucket, s3Key(commit, cacheKey, bundleFilename(cacheKey)))
61+
obj, err := s.client.stat(ctx, s.bucket, s3Key(s.keyPrefix, commit, cacheKey, bundleFilename(cacheKey)))
6162
if err != nil {
6263
return bundleStatInfo{}, err
6364
}
6465
return bundleStatInfo{Size: obj.Size, etag: obj.ETag}, nil
6566
}
6667

6768
func (s *s3BundleStore) get(ctx context.Context, commit, cacheKey string, info bundleStatInfo) (io.ReadCloser, error) {
68-
return s.client.get(ctx, s.bucket, s3Key(commit, cacheKey, bundleFilename(cacheKey)), s3ObjInfo{Size: info.Size, ETag: info.etag})
69+
return s.client.get(ctx, s.bucket, s3Key(s.keyPrefix, commit, cacheKey, bundleFilename(cacheKey)), s3ObjInfo{Size: info.Size, ETag: info.etag})
6970
}
7071

7172
func (s *s3BundleStore) put(ctx context.Context, commit, cacheKey string, r io.ReadSeeker, size int64) error {
72-
return s.client.put(ctx, s.bucket, s3Key(commit, cacheKey, bundleFilename(cacheKey)), r, size, "application/zstd")
73+
return s.client.put(ctx, s.bucket, s3Key(s.keyPrefix, commit, cacheKey, bundleFilename(cacheKey)), r, size, "application/zstd")
7374
}
7475

7576
func (s *s3BundleStore) putStream(ctx context.Context, commit, cacheKey string, r io.Reader) (int64, error) {
76-
return s.client.putStreamingMultipart(ctx, s.bucket, s3Key(commit, cacheKey, bundleFilename(cacheKey)), r, "application/zstd")
77+
return s.client.putStreamingMultipart(ctx, s.bucket, s3Key(s.keyPrefix, commit, cacheKey, bundleFilename(cacheKey)), r, "application/zstd")
7778
}
7879

7980
func bundleFilename(cacheKey string) string {
8081
return strings.ReplaceAll(cacheKey, ":", "-") + ".tar.zst"
8182
}
8283

83-
func s3Key(commit, cacheKey, bundleFile string) string {
84-
return commit + "/" + cacheKey + "/" + bundleFile
84+
func s3Key(prefix, commit, cacheKey, bundleFile string) string {
85+
key := commit + "/" + cacheKey + "/" + bundleFile
86+
if prefix != "" {
87+
return prefix + "/" + key
88+
}
89+
return key
8590
}
8691

8792
// ── Cachew client ───────────────────────────────────────────────────────────

0 commit comments

Comments
 (0)