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?
answer
- ./gradlew tasks --group publishing
- --all to see everything
- --dry-run prints task graph
- pin CI to specific task
- new repo silently joins publish
basics
~10 sList 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 sBecause 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./gradlew tasks --group publishing
./gradlew publish --dry-run # see which granular tasks would run
./gradlew publishMavenJavaPublicationToReleasesRepository # the precise fixgo deeper
Know ./gradlew tasks lists available tasks, including publishing ones.
Use --group publishing and --dry-run to enumerate and preview generated publish tasks.
Diagnose accidental multi-repo publishing and pin CI to explicit granular tasks.
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.