Compare the Central Portal and the legacy OSSRH staging endpoints. What URLs/targets does each use and how does a Gradle build point at them?
answer
- OSSRH = hosted Nexus staging URL
- s01.oss.sonatype.org/service/local/staging/deploy/maven2
- Portal = central.sonatype.com bundle upload
- no per-user deploy URL on Portal
- OSSRH being retired, Portal for new
basics
~10 sLegacy OSSRH used per-account Nexus staging URLs like s01.oss.sonatype.org/service/local/staging/deploy/maven2. The new Central Portal uploads a bundle to central.sonatype.com via its Publisher API. New accounts use the Portal; OSSRH is being retired.
solid answer
~40 sHistorically you published to **OSSRH** (OSS Repository Hosting), a Sonatype-run **Nexus** instance. Releases went to a staging URL such as `https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/` (older accounts used `oss.sonatype.org`), and snapshots to `.../content/repositories/snapshots/`. In a Gradle build you'd configure a `maven` repository in `publishing.repositories` pointing at those URLs. Sonatype has moved to the **Central Portal** (`central.sonatype.com`), which doesn't expose a per-user Nexus deploy URL — instead you upload a fully-assembled, signed **bundle** through the Portal Publisher API (commonly via a community Gradle plugin or the `publishing` setup that the plugin retargets). New namespaces are Portal-only and OSSRH is being decommissioned, so greenfield builds should target the Portal; legacy builds keep the OSSRH `url(...)` until migrated.
code
kotlin · 9 lines// Legacy OSSRH release staging URL in a Gradle publishing repository
publishing {
repositories {
maven {
name = "ossrh"
url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
}
}
}go deeper
Recognize that artifacts go through a Sonatype staging step before reaching Central; naming one URL is enough.
Distinguish OSSRH (Nexus staging URLs) from the Portal (bundle upload to central.sonatype.com) and how each is configured.
Explain the retirement of OSSRH and why greenfield projects should use the Portal/plugin path.
Plan a migration of many modules from OSSRH to the Portal, including credential and CI changes and the cutover window.
## Two generations of the same pipeline Getting an artifact onto Maven Central has always meant: assemble a signed bundle, push it to a **staging** area, have it validated, then **release** it to the public `repo1.maven.org` mirror. What changed is the staging system. ## Legacy OSSRH (Nexus-based) OSSRH was a hosted Sonatype **Nexus Repository Manager**. Each project had: - A **release staging deploy** endpoint, e.g. `https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/` (newer hosts on `s01.`; older accounts on `https://oss.sonatype.org/...`). - A **snapshots** repository, e.g. `https://s01.oss.sonatype.org/content/repositories/snapshots/`. In Gradle you declared it explicitly: ```kotlin publishing { repositories { maven { name = "ossrh" url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") // credentials configured separately } } } ``` A release then created a **staging repository** you had to close (runs validation) and release (promotes to Central) — often automated by the `io.github.gradle-nexus.publish-plugin`. ## The Central Portal (current) The Central Portal at `central.sonatype.com` replaces the per-user Nexus deploy URL with a **Publisher API**. You don't `PUT` artifacts to a staging path; instead you assemble the entire signed bundle locally and upload it as a **deployment** to the Portal, which validates and lets you publish. Because the Portal flow differs from a plain Maven deploy URL, you typically use a plugin that knows the Portal API — for example community plugins such as `com.vanniktech.maven.publish` (which can target the Portal) or Sonatype's own Portal-publishing support. ## How a Gradle build targets each - **OSSRH**: a literal `maven { url = uri("…s01.oss.sonatype.org…") }` repository (or the nexus-publish plugin that injects it). - **Portal**: a plugin configured with Portal credentials that performs the bundle upload to `central.sonatype.com`; there is no hand-written staging `url(...)` to a Nexus. ## Why it matters which one you're on Sonatype is **retiring OSSRH**. New namespaces are created in the Portal and cannot use the old Nexus deploy URLs at all. Existing OSSRH projects are being migrated. So in an interview the key point is: recognize the `s01.oss.sonatype.org` URL as legacy OSSRH, recognize `central.sonatype.com` + bundle upload as the Portal, and know that new work should use the Portal. ## Quick recognition cheat sheet ```text s01.oss.sonatype.org/service/local/staging/deploy/maven2 -> OSSRH release staging (legacy) .../content/repositories/snapshots -> OSSRH snapshots (legacy) central.sonatype.com + Publisher API bundle upload -> Central Portal (current) ```
- Why can't you just give the Central Portal a plain Maven deploy URL like you did with OSSRH?The Portal uses a Publisher API that accepts a complete, pre-assembled signed bundle as a deployment, rather than exposing a Nexus staging path you PUT individual files to. So you use a plugin that speaks the Portal API instead of a literal url(...).
- How do you recognize a legacy OSSRH configuration in an existing build?Look for a maven repository whose url contains oss.sonatype.org / s01.oss.sonatype.org with /service/local/staging/deploy/maven2 or /content/repositories/snapshots, often paired with the gradle-nexus publish plugin.
saying these in an interview costs you the question
- Claiming the Central Portal still uses oss.sonatype.org staging URLs.
- Saying you upload individual files to the Portal via a Maven deploy URL.
- Treating OSSRH and the Portal as identical with just a renamed host.