skip to content

A teammate added a new repository but their CI publish step now uploads to the wrong place. How do you discover the available publish tasks and pick the right one?

level: seniorimportance: nice to knowfreq 35%

answer

  1. ./gradlew tasks --group publishing
  2. --all to see everything
  3. --dry-run prints task graph
  4. pin CI to specific task
  5. new repo silently joins publish

basics

~10 s

List tasks with ./gradlew tasks --group publishing (or --all) to see every generated publish<Pub>PublicationTo<Repo>Repository task, then point CI at the specific task for the intended repo instead of the aggregate publish.

solid answer

~30 s

Because publish task names are **derived** from publication and repository names, the fix starts with discovery: `./gradlew tasks --group publishing` lists the aggregates (`publish`, `publishToMavenLocal`) plus each `publish<Pub>PublicationTo<Repo>Repository` and `generatePomFileFor<Pub>Publication`. The root cause is usually that CI runs the aggregate `publish`, which fans out to **every** remote repo — so a newly declared repository silently became an additional target. The robust fix is to pin the CI step to the **specific** granular task for the intended repository (e.g. `publishMavenJavaPublicationToReleasesRepository`). For pre-flight confidence, run `generatePomFileFor<Pub>Publication` and `--dry-run` to see exactly which tasks would execute and what POM would ship, without uploading.

code

bash · 3 lines
bash
./gradlew tasks --group publishing
./gradlew publish --dry-run   # see which granular tasks would run
./gradlew publishMavenJavaPublicationToReleasesRepository  # the precise fix

go deeper

for a junior

Know ./gradlew tasks lists available tasks, including publishing ones.

for a middle

Use --group publishing and --dry-run to enumerate and preview generated publish tasks.

for a senior

Diagnose accidental multi-repo publishing and pin CI to explicit granular tasks.

for a principal

Establish guardrails (explicit targets, conditional repo declaration, review of new repositories) so publishing behavior can't silently change across the org.

## Step 1 — enumerate the generated tasks Task names are generated from your declarations, so never guess them. Use: ```bash ./gradlew tasks --group publishing # human-friendly publishing group ./gradlew tasks --all # everything, including dependencies ``` You'll see entries like `publish`, `publishToMavenLocal`, `publishMavenJavaPublicationToReleasesRepository`, `publishMavenJavaPublicationToSnapshotsRepository`, and `generatePomFileForMavenJavaPublication`. ## Step 2 — understand why the wrong repo got hit The aggregate `publish` `dependsOn`s **all** remote publish tasks. When a teammate adds `maven { name = "extra"; url = … }`, the plugin generates `publish<Pub>PublicationToExtraRepository` and wires it into `publish`. A CI step invoking `./gradlew publish` now uploads there too — that's the surprise. ## Step 3 — preview without uploading ```bash ./gradlew publish --dry-run # prints the task graph, runs nothing ./gradlew generatePomFileForMavenJavaPublication && \ cat build/publications/mavenJava/pom-default.xml ``` `--dry-run` reveals every granular publish task `publish` would trigger; POM generation confirms the exact metadata. ## Step 4 — fix Pin CI to the **specific** task: ```bash ./gradlew publishMavenJavaPublicationToReleasesRepository ``` Now adding repositories can't change what this step uploads. Alternatively, declare repositories conditionally (by branch/version) so the aggregate resolves to the right target. ## Why this is a senior concern Accidental dual-publishing can leak release artifacts to a snapshot/staging endpoint or vice versa. Treating generated task names as the stable interface — discovered, not guessed — and pinning CI to explicit targets is the durable guardrail.

  • What does ./gradlew publish --dry-run show?
    The ordered task execution graph publish would trigger — every granular publish<Pub>PublicationTo<Repo>Repository task — without running any of them.
  • Why is pinning CI to a specific task more robust than running `publish`?
    A newly declared repository auto-joins the aggregate `publish`, changing its behavior; a specific task's target is fixed regardless of new repos.
  • Which command lists tasks that aren't in a visible group?
    ./gradlew tasks --all, which includes dependency/internal tasks beyond the curated group listing.

saying these in an interview costs you the question

  • Hardcoding guessed task names instead of discovering them with `tasks` — names depend on your declarations.
  • Relying on `publish` in CI and assuming a stable single target.

context