Gradle Build Authoring
Author or modify Gradle build definitions, build logic, project structure, and delivery wiring. Optimize for lazy, decoupled, configuration-cache-compatible builds.
Positive Triggers (when to activate)
- Authoring or modifying build.gradle(.kts), settings.gradle(.kts), convention plugins, modules, or subprojects.
- Adding or changing dependency declarations, version catalogs, repositories, or plugin management.
- Configuring JDK toolchains, Kotlin compiler options, test frameworks, publishing, or CI wiring.
- Declaring or modifying composite builds (included builds via
includeBuild, build-logic wiring). - Creating custom tasks, worker actions, build services, value sources, service injection, or project-isolation-compatible build logic.
- Assessing build health, running best-practice audits, or handling Gradle doctor / build health check / performance audit requests.
- Modifying advanced Gradle configuration and build performance settings.
Negative Triggers (when NOT to activate)
- Operation/execution (running builds, running tests, diagnosing failures, and read-only dependency inspection/update discovery) belongs to
using-gradle; authoring/modifying build definitions (including dependency declarations and version catalogs) belongs toauthoring-gradle-builds. Trivial one-line everyday dependency edits (catalog entry + declaration + version bump) are a sanctioned overlap inusing-gradle; anything structural (plugins, repositories, modules, toolchains, publishing, CI) isauthoring-gradle-buildsonly. - Researching internal Gradle APIs (use
using-gradle's research workflow). - Probing runtime project code (use
interacting-with-project-runtime). - Verifying Compose UI (use
verifying-compose-ui). - Advanced dependency engineering — variant-aware resolution diagnostics, dependency verification implementation (verification-metadata.xml authoring, PGP key and checksum workflows, verification repair, and CI verification workflows), component metadata rules, dependency substitution rules and composite-build diagnosis, capability conflicts, lock modes beyond basics, advanced version catalogs, and repository governance modes (use
advanced-gradle-dependencies). Composite-build authoring stays here. Basic dependency declaration, version-catalog basics, and basic locking stay here.
More info: Search the User Guide with gradle_docs(query="tag:userguide <term>") or best practices with gradle_docs(query="tag:best-practices <term>"). Read gradle/wrapper/gradle-wrapper.properties before any version-sensitive authoring.
Before You Modify
- Read
gradle/wrapper/gradle-wrapper.properties; identify the wrapper version. - Consult the compatibility quick-reference below; verify version-sensitive claims with
gradle_docs(query="tag:userguide <term>"). - When the change is version-sensitive (wrapper upgrade, API migration, deprecation fix), consult the upgrading page for the wrapper's major version via
gradle_docs(path="userguide/upgrading_version_<N>.md")and checkgradle_docs(query="tag:release-notes")for breaking changes. See Upgrading and Release Notes. - Read
settings.gradle.kts,gradle/libs.versions.toml, applied plugins, and convention plugins. Check for existing conventions before proposing changes. - Load the narrowest authored reference: links in the directives and workflows above are loaded in context; for the remaining actions, use the Decision Routing table.
- Treat
references/best-practices/_index.mdand its corpus detail as optional rationale, consulted on demand rather than as a mandatory pre-load.
Compatibility Quick-Reference
| Behavior | Gradle 9 | Gradle 8.x | Gradle 7.x / fallback |
|---|---|---|---|
| Version catalogs | Stable; prefer them | Stable; prefer them | 7.4+ stable; 7.0-7.3 preserve an existing catalog cautiously, otherwise use buildSrc, applied scripts, or ext |
| Configuration cache | Stable and opt-in; stable ≠ every plugin/build compatible, 9.x strictness still evolving; enable when compatible | Stable from 8.1; 8.0 pre-stable | Incubating/experimental; use only for explicit migration experiments |
| Project isolation | Incubating as of 9.7; opt in with --isolated-projects or org.gradle.isolated-projects=true (legacy unsafe names deprecated); an explicit false from either property disables it; not the production default |
Do not enable as a baseline; use decoupled logic | Use decoupled logic + provider wiring; no isolation support |
| Dependency notation | Map notation deprecated since 9.1 and fails in Gradle 10; use single-string GAV or catalog accessors | Use single-string GAV or catalog accessors | Use single-string GAV or catalog accessors |
| Toolchain auto-provisioning | Supported through a resolver plugin configured in settings | Supported; resolver plugin availability is version-specific | 7.5 auto-download; 7.6 pluggable resolver repositories; earlier versions require a local JDK |
| JVM required to run Gradle | 17+ | Java 8 minimum; maximum varies by minor | Java 8 minimum; 7.0-7.2 cannot run on Java 17, 7.3+ can |
Kotlin DSL / compilerOptions |
Prefer Kotlin DSL; use typed compilerOptions for current KGP |
Prefer Kotlin DSL; verify KGP API version | Kotlin DSL is supported; use version-compatible compiler options and hedge unverified KGP boundaries |
Constitution
- Prefer Kotlin DSL for new authoring (
gradle_docs(path="userguide/best_practices_general.md"); use Groovy only when the project requires it). - Register lazily: use Custom Tasks,
tasks.register,tasks.named, andconfigureEach, not eagertasks.create(gradle_docs(path="userguide/task_configuration_avoidance.md")). - Use version catalogs when present; centralize versions and aliases (
gradle_docs(path="userguide/best_practices_dependencies.md"); catalogs are stable from 7.4). - Check existing conventions first; use declarative
plugins {}and settingspluginManagement {}(gradle_docs(path="userguide/plugins.md"),gradle_docs(path="userguide/best_practices_structuring_builds.md")). - Never use
allprojectsorsubprojects; apply explicit Convention Plugins and keep projects decoupled (gradle_docs(path="userguide/best_practices_structuring_builds.md"),gradle_docs(path="userguide/isolated_projects.md")). - Never use
ProjectorTask.projectinside task actions; inject Advanced Configuration services and model task inputs (gradle_docs(path="userguide/configuration_cache_requirements.md"),gradle_docs(path="userguide/service_injection.md")). - Never resolve configurations in the configuration phase; resolve through task inputs or task execution (
gradle_docs(path="userguide/best_practices_tasks.md")). - Do not call
Provider.get()while configuring unrelated work; wire Managed Types and Providers withProviderandPropertyvalues lazily (gradle_docs(path="userguide/properties_providers.md"),gradle_docs(path="userguide/best_practices_tasks.md")). - Prohibit
afterEvaluate; use providers,pluginManager.withPlugin, and lazy APIs. Permit it only for a documented correctness-critical ordering constraint, with anafterEvaluate-justification:comment (gradle_docs(path="userguide/best_practices_general.md")).
Always-Loaded Best-Practice Footguns
These compact rules are loaded before any authoring reference. Links provide detailed rationale or, where available, the corpus detail; use the linked reference for the procedural guidance.
- Model initialization, configuration, and execution separately. Phase boundaries are easy to blur, and the resulting ordering and performance bugs are often silent. See Build Lifecycle.
- Keep expensive work out of configuration. Unselected tasks still pay configuration-time costs, which makes this mistake hard to spot from a successful build. See Build Lifecycle.
- Use configuration avoidance throughout the model. Eager APIs look harmless but silently realize tasks and domain objects before they are needed. See Custom Tasks.
- Propagate laziness with providers and managed properties. Provider-looking values can still be realized too early, losing provenance and cache inputs. See Managed Types and Providers.
- Read providers only at an execution boundary. Configuration-time reads can work in simple builds while breaking laziness or cache behavior in larger ones. See Custom Tasks.
- Use provider-backed managed model types. Ad hoc mutable fields hide validation, lifecycle, and caching semantics that Gradle must observe. See Managed Types and Providers.
- Use public APIs and injected services only. Internal types often appear convenient until an upgrade exposes an undocumented compatibility break. See Advanced Configuration.
- Wire cross-project behavior through model relationships. Callback-based mutation depends on evaluation order and becomes hostile to project isolation. See Convention Plugins.
- Avoid
afterEvaluateandprojectsEvaluatedas configuration mechanisms (version-sensitive). Their timing can appear to repair ordering while masking a model relationship that should be explicit; read the wrapper first. See Build Lifecycle. - Distinguish
set(null)from an absent provider. Both represent "no value" at a glance, but only one lets a convention apply. See Managed Types and Providers. - Never resolve or iterate at configuration time. Configuration-phase resolution, iteration, or eager file-tree walking realizes values early and breaks laziness, the configuration cache, and project isolation. See File Operations and Managed Types and Providers.
- Do not capture realized files or
Project. Retaining an eagerFile/Pathor theProjectobject freezes values that must stay lazy and is incompatible with the configuration cache and isolated projects. See File Operations. - Prefer provider wiring over declaration copying. Connect task and extension properties with providers (
set(...),from(...),map/flatMap) so changes propagate without re-realizing values. See Managed Types and Providers.
Decision Routing
| Authoring action | Reference |
|---|---|
| Configure a JDK toolchain or resolver | JDK Toolchains |
| Configure Kotlin compiler options | Kotlin Compiler Options |
| Configure test frameworks or test behavior | Testing Configuration |
| Publish artifacts or configure Central Portal delivery | Artifact Publishing |
| Customize published variants, components, or artifacts | Artifact Publishing |
| Wire CI/CD builds | CI/CD Builds |
| Configure build scan publication or Develocity policy | Build Scans |
| Enable or update dependency locking | Dependency Locking |
| Parallelize task work with Worker API | Worker API |
| Configure continuous builds | Continuous Builds |
Declare or modify composite builds (included builds, includeBuild, build-logic) |
Composite Builds |
| Understand build lifecycle, phases, task graph, or hook ordering | Build Lifecycle |
| Develop a binary plugin, test with TestKit, or publish a plugin | Plugin Development |
| Configure Java source sets, annotation processing, or mixed languages | Java Builds |
| Model configurations, feature variants, capabilities, or variant sharing | Configurations and Variants |
| Declare custom task property annotations or model task inputs/outputs | Task Properties |
| Copy, sync, delete, or lazily handle files in a task | File Operations |
| Create, get, or work with a plugin extension | Extensions |
| Assess build health, run a best-practice audit, or handle Gradle doctor / health check / performance audit requests | Build Health Assessment |
| Research Gradle internals, plugin use and development, or dependency source | Research |
Cross-Skill Handoffs
- Build execution, task running, test running, failure diagnosis, or read-only dependency inspection ->
using-gradle. - Enabling/persisting the build cache or configuration cache (gradle.properties/CLI flags, local/remote cache config, CI rollout, cache cleanup) and reading runtime cache/isolation outcomes ->
using-gradle. This skill authors cacheability and config-cache-safe logic; it does not own enablement. - Enabling isolated-projects flags/diagnostics and interpreting diagnostics output ->
using-gradle. - Runtime probing or arbitrary JVM/Kotlin execution ->
interacting-with-project-runtime. - Compose UI rendering or verification ->
verifying-compose-ui. - Advanced Dependency Engineering ->
advanced-gradle-dependencies. Routes advanced dependency depth out, including dependency verification implementation (verification-metadata.xml authoring, PGP key and checksum workflows, verification repair, and CI verification workflows), component metadata rules, dependency substitution rules and composite-build diagnosis, capability conflicts, lock modes beyond basics, advanced version catalogs, and repository governance modes. Composite-build authoring stays here. Basic dependency declaration, version-catalog basics, and basic locking stay here.
Workflows
Create Module
- Read the wrapper version, settings, project layout, catalogs, and applied conventions.
- Load Modules and Settings as the single authoritative procedural reference; add the project and its build logic without root-wide mutation.
- Use existing convention plugins and version aliases; add only module-specific configuration.
- Hand off to
using-gradleto verify project discovery and the module's lifecycle tasks.
Add Dependency
- Determine whether the change is structural; hand off read-only GAV discovery to
using-gradle. - Load Dependencies and Catalogs as the single authoritative procedural reference; update the catalog when one exists and declare the alias in the consuming project.
- Centralize repositories in settings and apply content filters when multiple repositories are required.
- Hand off to
using-gradleto verify dependency resolution and the affected configuration.
Build Health Assessment (Doctor)
Use when assessing build health, running a best-practice audit, or handling Gradle doctor / build health check / performance audit requests. Load Build Health Assessment as the single authoritative procedure; it carries both the assessment steps and the report material. Its Knowledge sources hierarchy governs the assessment.
Best-Practices Consultation
Use the authored reference linked in the relevant directive or workflow as the single authoritative procedural load when one is provided; for the remaining authoring actions, use the Decision Routing table. Consult references/best-practices/_index.md and its corpus detail only when rationale is needed or the authored reference points there; then use gradle_docs(query="tag:userguide <term>") when deeper rationale or the authoritative version-scoped source is required. The escalation path remains Index $\rightarrow$ Detail $\rightarrow$ Gradle Docs, but it does not force a second competing procedural load. The corpus is read-only: route to it, and do not restate its detail in this hub. For the doctor workflow, the knowledge-source hierarchy is defined in references/build-health-assessment.md and is not restated here.