fix: support cache-mode and make low-trust runs cache read-only (#1412)

Low-trust runs like `pull_request_target` on the default branch could poison caches that `push` runs restore. As on GitHub, they now only restore unless `cache-mode` allows saving.

This and the Gitea change can be deployed in any order.

Refs:
https://gitea.com/gitea/actionslib/pulls/33
https://github.com/go-gitea/gitea/pull/40343

_Written by Claude (Opus 5.5)._
Reviewed-on: https://gitea.com/gitea/runner/pulls/1412
Reviewed-by: bircni <[email protected]>
Co-authored-by: silverwind <[email protected]>
This commit is contained in:
silverwind authored and bircni committed 2026-11-13 09:33:32 +00:00
1 parent c2046d597c
commit 4f59e3e418
8 files changed
+127 -26

No files matched your search

+19 -5
View File
@@ -120,15 +120,29 @@ func TestCacheCredential(t *testing.T) {
Event: map[string]any{"repository": repository, "number": float64(3)},
}
assert.Equal(t, artifactcache.JobCredential{
Repo: "owner/repo", Ref: "refs/pull/3/head", BaseRef: "refs/heads/release", DefaultRef: "refs/heads/main", PublicURL: "http://cache",
}, cacheCredential(review, "http://cache"))
Repo: "owner/repo", Ref: "refs/pull/3/head", BaseRef: "refs/heads/release", DefaultRef: "refs/heads/main", CacheMode: "write", PublicURL: "http://cache",
}, cacheCredential(review, "http://cache", ""))
review.EventName, review.Ref = "pull_request_target", "refs/heads/release"
assert.Equal(t, "refs/heads/release", cacheCredential(review, "").Ref)
assert.Equal(t, "refs/heads/release", cacheCredential(review, "", "").Ref)
assert.Equal(t, "write", cacheCredential(review, "", "").CacheMode)
assert.Equal(t, artifactcache.JobCredential{
Repo: "owner/repo", Ref: "refs/heads/feature", DefaultRef: "refs/heads/main",
}, cacheCredential(&model.GithubContext{Repository: "owner/repo", Ref: "refs/heads/feature", Event: map[string]any{"repository": repository}}, ""))
Repo: "owner/repo", Ref: "refs/heads/feature", DefaultRef: "refs/heads/main", CacheMode: "write",
}, cacheCredential(&model.GithubContext{Repository: "owner/repo", Ref: "refs/heads/feature", Event: map[string]any{"repository": repository}}, "", ""))
for _, tc := range [][3]string{
{"pull_request_target", "", "read"},
{"issue_comment", "", "read"},
{"pull_request_comment", "", "read"},
{"push", "", "write"},
{"issue_comment", "write", "write"},
{"push", "none", "none"},
} {
cred := cacheCredential(&model.GithubContext{EventName: tc[0], Ref: "refs/heads/main", Event: map[string]any{"repository": repository}}, "", tc[1])
assert.Equal(t, "refs/heads/main", cred.Ref, tc)
assert.Equal(t, tc[2], cred.CacheMode, tc)
}
}
func TestRunner_ExternalCacheServer_RegisterRevoke(t *testing.T) {