From cf5457958a1c2c947ba830e78d4bf1a017491f26 Mon Sep 17 00:00:00 2001 From: James Rich Date: Sun, 2 Aug 2026 19:41:08 -0500 Subject: [PATCH] ci: restrict Develocity cache writes to trusted events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #36, which shipped with cache writes gated only on CI plus a non-empty DEVELOCITY_ACCESS_KEY. A same-repository pull request DOES receive repository secrets, so PR builds on this repo are currently writing entries into the shared cache that main and the merge queue then read. The self-hosted HttpBuildCache that #36 replaced gated on GITHUB_EVENT_NAME and excluded pull_request; that protection was lost in the port. Restore it. Cache population is unaffected — push and merge_group runs still write, and those are the runs whose outputs correspond to code that actually landed. pull_request runs become pull-only and keep the full read benefit. Verified against a CI-shaped environment: CI=true GITHUB_EVENT_NAME=pull_request -> pull-only CI=true GITHUB_EVENT_NAME=push -> writes enabled CI=true GITHUB_EVENT_NAME=merge_group -> writes enabled Local builds are excluded by isCI; fork PRs have no key at all. Signed-off-by: James Rich --- gradle/develocity.settings.gradle | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gradle/develocity.settings.gradle b/gradle/develocity.settings.gradle index f47e727..49583ea 100644 --- a/gradle/develocity.settings.gradle +++ b/gradle/develocity.settings.gradle @@ -48,7 +48,13 @@ buildCache { } remote(develocityBuildCache) { enabled = true - // Only authenticated CI writes, so unmerged and fork code cannot poison the cache. - push = isCI && accessKey != null && !accessKey.isEmpty() + // Write only from trusted events. Local dev is excluded by isCI, and + // pull_request runs are excluded here: a same-repository PR DOES receive + // repository secrets, so gating on the access key alone would let + // unmerged code write entries into the shared cache. Fork PRs have no + // key and are excluded twice over. + def eventName = System.getenv("GITHUB_EVENT_NAME") + def trustedForPush = eventName == "push" || eventName == "merge_group" + push = isCI && trustedForPush && accessKey != null && !accessKey.isEmpty() } }