skip to content

How would you make plugin validation a reliable quality gate across an organisation's internal plugins?

level: principalimportance: nice to knowfreq 18%

answer

  1. shared convention plugin sets policy once
  2. failOnWarning + enableStricterValidation everywhere
  3. CI-enforced check
  4. external validation for consumed plugins
  5. remote-cache correctness prerequisite

basics

~10 s

Apply java-gradle-plugin everywhere, enable failOnWarning and enableStricterValidation through a shared convention plugin, run validatePlugins in CI on every plugin repo, and validate published artifacts for third-party plugins.

solid answer

~40 s

Treat plugin validation as a centralized, non-optional gate. Put the configuration in a **shared convention plugin** that every internal plugin project applies, so `failOnWarning = true` and `enableStricterValidation = true` are enforced uniformly via `tasks.withType<ValidatePlugins>().configureEach { }` rather than copy-pasted per repo. Wire it into `check` (it already is) and require `./gradlew check` green in CI for every plugin. For plugins you *consume* but don't author, add **external validation** in CI to certify them from their built artifacts before adoption. Add Build Scans/reporting so `TypeValidationProblem`s are visible, and keep a small allowlist process for legitimate exceptions (justified `@Internal`). The goal: every task type shipped or consumed in the org has provably correct input/output metadata, so the (possibly remote) build cache is trustworthy and incremental builds never silently produce stale outputs.

code

kotlin · 7 lines
kotlin
// my-org.plugin-conventions.gradle.kts (applied by every internal plugin)
plugins { `java-gradle-plugin` }

tasks.withType<org.gradle.plugin.devel.tasks.ValidatePlugins>().configureEach {
    failOnWarning = true
    enableStricterValidation = true
}

go deeper

for a junior

Out of depth — knowing validation should run in CI is enough.

for a middle

Suggest enabling failOnWarning and running validatePlugins in CI.

for a senior

Add a shared convention plugin, stricter validation, and external validation for dependencies.

for a principal

Own it as governance: one policy, CI-enforced, supply-chain validation, tied to remote-cache correctness, with a reviewed exception process.

## The problem at scale In an org with dozens of internal Gradle plugins and many consumed third-party ones, a single mis-annotated task type can poison incremental-build and (remote) cache correctness across every downstream repo. Ad-hoc validation per repo doesn't scale and drifts. ## Strategy ### 1. Centralize via a convention plugin Author one **convention plugin** (a precompiled script or binary plugin) that all internal plugin builds apply. It sets the validation policy once: ```kotlin // my-org.plugin-conventions.gradle.kts plugins { `java-gradle-plugin` } tasks.withType<org.gradle.plugin.devel.tasks.ValidatePlugins>().configureEach { failOnWarning = true enableStricterValidation = true } ``` Now the policy is uniform and updated in one place; repos can't silently weaken it. ### 2. Make it a CI gate `validatePlugins` already runs under `check`. Require `./gradlew check` to pass in CI for every plugin repo. Because validation is fast static analysis and cacheable, the cost is negligible. ### 3. Validate consumed plugins (supply chain) For third-party/downstream plugins you depend on, run **external validation** against their built artifacts in a certification job. Refuse to onboard a plugin that fails. This protects your cache correctness from dependencies you don't control. ### 4. Observability and exceptions - Surface `TypeValidationProblem`s via Build Scans / CI reports so failures are diagnosable. - Keep a **narrow, reviewed exception process**: legitimate non-tracked state is `@Internal` with justification — never a blanket disable of `failOnWarning`. ### 5. Tie to cache strategy If you run a **remote build cache**, correct task metadata is a hard prerequisite — a mis-annotated task can serve wrong cached outputs to everyone. Validation is the gate that keeps the shared cache trustworthy. ## Governance summary - One convention plugin = one policy. - failOnWarning + enableStricterValidation everywhere. - CI-enforced `check`. - External validation for consumed plugins. - Reviewed exceptions only. This turns plugin validation from a per-author nicety into an org-wide correctness guarantee.

  • Why centralize the policy in a convention plugin instead of per repo?
    A single convention plugin means the policy is defined once, applied uniformly, and updated centrally; repos can't silently weaken failOnWarning, and there is no copy-paste drift.
  • How does this connect to a remote build cache?
    A remote cache shares outputs across the org. If one task type is mis-annotated it can serve wrong cached results to everyone, so validated metadata is a hard prerequisite for trusting the shared cache.
  • How do you handle legitimate non-tracked properties under a fail-on-warning policy?
    Annotate them @Internal with justification through a reviewed exception process — never disable failOnWarning wholesale.

saying these in an interview costs you the question

  • Proposing to disable failOnWarning per repo to 'unblock' builds instead of fixing annotations.
  • Ignoring consumed third-party plugins in the validation strategy.

context