skip to content

How would you gate isPush and isEnabled on Gradle's startParameter rather than reading environment variables directly inside the buildCache block? Why prefer that?

level: seniorimportance: should knowfreq 35%

answer

  1. settings.startParameter = invocation model
  2. isOffline → disable remote
  3. projectProperties["cachePush"] gate
  4. isBuildCacheEnabled mirrors --build-cache
  5. read-only, don't mutate

basics

~20 s

settings.startParameter exposes the actual invocation flags (e.g. isOffline, task names, --build-cache). You read those inside buildCache {} to decide isPush/isEnabled, so the policy reacts to how the build was launched rather than to ambient env state.

solid answer

~40 s

`Settings.startParameter` is Gradle's model of the current invocation — the requested tasks, whether `--offline` was passed, the configured cache flags, system properties, project properties, and excluded tasks. Gating cache behavior on it means your policy keys off *what was actually requested* in this build, not just an environment variable that may or may not be set. A common pattern: turn the remote cache off when offline, and only push when a specific seeding task or a `seedCache` property is present. ```kotlin buildCache { remote<HttpBuildCache> { val sp = startParameter isEnabled = !sp.isOffline isPush = sp.projectProperties["cachePush"] == "true" } } ``` The advantage over raw `System.getenv` is that `startParameter` reflects Gradle's own command-line semantics (`--offline`, `-P`, `--build-cache`), so the cache policy stays consistent with how the user actually invoked Gradle, and it's testable.

code

kotlin · 9 lines
kotlin
// settings.gradle.kts
buildCache {
  remote<HttpBuildCache> {
    url = uri("https://cache.example.com/cache/")
    val sp = settings.startParameter
    isEnabled = sp.isBuildCacheEnabled && !sp.isOffline
    isPush = sp.projectProperties["cachePush"] == "true"
  }
}

go deeper

for a junior

Aware that an env or property flag decides push vs pull; details optional.

for a middle

Can gate isPush on a project property and isEnabled on offline state.

for a senior

Explains startParameter fields, prefers explicit invocation-based gating, respects offline and --build-cache.

for a principal

Designs the invocation contract (flags/tasks) used org-wide so seed vs pull is deterministic and configuration-cache safe across repos.

## What startParameter is Every Gradle build has a `StartParameter` object describing the invocation. In `settings.gradle(.kts)` you reach it as `settings.startParameter` (or just `startParameter` inside the script). It carries: - `taskNames` / `excludedTaskNames` — the tasks requested and excluded. - `isOffline` — whether `--offline` was passed. - `isBuildCacheEnabled` — the effective `--build-cache`/`--no-build-cache` / `org.gradle.caching` state. - `projectProperties` and `systemPropertiesArgs` — `-P` and `-D` values. - log level, `isRerunTasks`, `isContinueOnFailure`, etc. ## Why gate cache policy on it Reading `System.getenv("CI")` works, but it only knows about the ambient environment. `startParameter` knows about **how this specific Gradle invocation was launched**. That lets you write policy that is precise and self-consistent: - **Respect offline mode.** If someone runs `--offline`, hitting a remote HTTP cache is wrong; gate `isEnabled = !startParameter.isOffline`. - **Push only for an explicit seed.** Rather than "push on any CI build," require an explicit `-PcachePush=true` (or a dedicated `:seedBuildCache` task name in `taskNames`). Your main-branch seed job passes the flag; PR jobs don't — all expressed through invocation, not branch-detection logic scattered in YAML. - **Consistency with `--build-cache`.** You can read `startParameter.isBuildCacheEnabled` so your remote config follows the same on/off intent the user expressed on the command line. ## Example ```kotlin // settings.gradle.kts buildCache { remote<HttpBuildCache> { url = uri("https://cache.example.com/cache/") val sp = settings.startParameter // never touch the network in offline mode isEnabled = sp.isBuildCacheEnabled && !sp.isOffline // push only when explicitly requested (seed job passes -PcachePush=true) isPush = sp.projectProperties["cachePush"] == "true" } } ``` ## Trade-offs and pitfalls - **Mutating startParameter is discouraged.** You can technically set fields on it programmatically, but treating it as read-only input for *decisions* is the clean pattern; mutating it to force behavior surprises other plugins. - **Don't double-source truth.** Pick one signal (a project property, or an env var mapped to one) and gate consistently, rather than mixing `getenv` in one place and `startParameter` in another. - **Configuration cache.** Reading `startParameter` and `projectProperties` is configuration-cache friendly when done in settings; avoid reading mutable ambient state in a way that the configuration cache can't track. The net effect: cache participation becomes a function of the explicit invocation, making the seed-vs-pull split deterministic and easy to reason about per environment.

  • How does a CI seed job actually trigger the push under this scheme?
    It invokes Gradle with the explicit flag, e.g. `./gradlew build -PcachePush=true`. PR jobs omit the flag, so isPush stays false and they only pull.
  • Why gate isEnabled on startParameter.isOffline?
    In offline mode Gradle must not reach the network; an HTTP remote cache would fail or hang. Disabling it keeps --offline builds working and honors user intent.
  • Is mutating startParameter to force --build-cache a good idea inside settings?
    Generally no. Treat it as read-only input for decisions; mutating it can surprise other plugins and obscure where behavior comes from.

saying these in an interview costs you the question

  • Claiming startParameter is only available in build.gradle, not settings (it is available in both).
  • Saying you should always push on CI regardless of branch/flag — defeats the point of explicit gating.

context