skip to content

How do you define an additional named distribution (beyond 'main') with the Distribution plugin, and how does the name affect the generated tasks and archive files?

level: middleimportance: must knowfreq 45%

answer

  1. distributions NamedDomainObjectContainer
  2. main pre-registered, no classifier
  3. name => <name>DistZip / -<name> archive
  4. distributionBaseName Property<String>
  5. assembleDist = main only

basics

~10 s

Apply the distribution plugin and add an entry to the distributions { } container, e.g. create("custom"). Gradle generates customDistZip/customDistTar tasks and archives named <project>-custom.zip.

solid answer

~40 s

The `distribution` plugin exposes a `distributions` NamedDomainObjectContainer. The plugin pre-registers a `main` distribution; you add more with `distributions { create("docs") { ... } }`. The distribution **name** becomes a classifier in both the task names and the archive name. For `main`, tasks are `distZip`/`distTar` and the archive is `<baseName>-<version>.zip`. For a distribution named `docs`, you get `docsDistZip`/`docsDistTar` tasks producing `<baseName>-<version>-docs.zip`. You configure `distributionBaseName` to override the base name and a `contents { }` CopySpec to declare what goes inside. The aggregate `assembleDist` task builds the main distribution; each named distribution's `*DistZip`/`*DistTar` is wired into the general `assemble` lifecycle so `./gradlew build` packages them all.

code

kotlin · 13 lines
kotlin
plugins { id("distribution") }

distributions {
    create("docs") {
        distributionBaseName.set("handbook")
        contents {
            from("src/docs")
            into("manual")
        }
    }
}
// => tasks docsDistZip / docsDistTar
// => build/distributions/handbook-<version>-docs.zip

go deeper

for a junior

Knows you apply the distribution plugin and add entries to distributions { }, and that it produces zip/tar archives.

for a middle

Can explain the naming rules (name => task prefix and -name classifier, main is special), distributionBaseName, and contents CopySpec.

for a senior

Understands lifecycle wiring (assembleDist vs assemble, installDist), the NamedDomainObjectContainer model, and laziness considerations.

for a principal

Can standardize a distribution convention across a monorepo (shared convention plugin defining named distributions, reproducible archives, publishing them as artifacts).

## The Distribution plugin model The core `distribution` plugin (`plugins { id("distribution") }`) is built to ship arbitrary archives — not just runnable apps. It adds a `distributions` container of type `NamedDomainObjectContainer<Distribution>`. Out of the box it registers one distribution named `main`. Each `Distribution` has three configurable pieces: - **name** — the identity in the container; drives task and archive naming. - **distributionBaseName** — a `Property<String>` that defaults to the project name; the leading part of the archive file name. - **contents** — a `CopySpec` describing the files the archive contains. ## Naming rules The distribution name is used as a **classifier**: | Distribution | Zip task | Tar task | Archive file | |---|---|---|---| | `main` | `distZip` | `distTar` | `app-1.0.zip` (no classifier) | | `docs` | `docsDistZip` | `docsDistTar` | `app-1.0-docs.zip` | Note the special case: the `main` distribution does **not** add a classifier, so its archive is just `<baseName>-<version>.zip`. Any other name appends `-<name>`. ## Defining one ```kotlin plugins { id("distribution") } distributions { create("docs") { distributionBaseName.set("my-handbook") contents { from("src/docs") into("manual") } } } ``` This produces `docsDistZip` / `docsDistTar` and archives like `my-handbook-1.0-docs.zip`, whose root contains a `manual/` folder. ## Lifecycle wiring - `assembleDist` assembles the **main** distribution only. - `installDist` installs the main distribution into `build/install/<name>` (also `install<Name>Dist` for named ones). - Each `*DistZip`/`*DistTar` is registered as an artifact and hooked into `assemble`, so `build` produces all of them. Because `create()` is lazy (the container uses `register`-style semantics under the hood for the configuration block), configuration runs only when the distribution is realized — but explicit `create` does realize it. Prefer `distributions.register(...)` semantics aren't directly exposed; you use `create`.

  • Why does the `main` distribution archive not include a classifier in its name?
    By convention `main` is the primary/default distribution, so the plugin omits the `-main` classifier to keep the canonical archive name clean: `<baseName>-<version>.zip`. Only non-main names are appended as classifiers.
  • Which task builds all distributions when you run `./gradlew build`?
    Each distribution's `*DistZip`/`*DistTar` is wired into the `assemble` lifecycle task, and `build` depends on `assemble`, so every distribution's zip and tar are produced. `assembleDist` is narrower — it builds only the main distribution.

saying these in an interview costs you the question

  • Claiming named distributions reuse the `distZip` task name (they get a `<name>` prefix).
  • Saying `assembleDist` builds every distribution — it builds only `main`.

context