Publishing By Using the Portal Publisher API⚓︎
Intended Usage
This documentation is intended for users looking to implement clients to publish via the Portal Publisher API. If you intend to publish your own components to Maven Central, you might prefer the Maven client.
This documentation supplements the OpenAPI
documentation, which provides an
interactive environment for testing queries via a web-client. For purposes of
this documentation, curl
will be used in examples, but any HTTP client should
be able to interact with the API by following the underlying details.
Authentication / Authorization⚓︎
User Tokens
To generate a user token, visit the Account page and click the "Generate User Token" button.
Requests to the API must be authenticated via a user token header. Given a user
token of a username
of example_username
and a password
of
example_password
, the token would be calculated by base64 encoding the two
values joined with a :
.
$ printf "example_username:example_password" | base64
ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhc3N3b3Jk
The Authorization
header would then be in the form Bearer <the base64
encoded value>
(so Bearer
ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhc3N3b3Jk
).
UserToken Tokens
The API also accepts a non-standard UserToken
Authorization
header with
the same base64 encoded value, but we recommend using the standard Bearer
value and future versions of the API may drop support for UserToken
.
Uploading a Deployment Bundle⚓︎
Assuming a valid bundle has been created, that
bundle can be uploaded to the /api/v1/publisher/upload
endpoint via a POST
request. The endpoint expects a Content-Type
of multipart/form-data
with a
single part that is an application/octet-stream
with the name
of bundle
and a defined filename.
The endpoint has two optional query parameters. The first, name
, allows for
providing a human-readable name for the deployment. The second,
publishingType
, can have one of the following values:
AUTOMATIC
: (default) a deployment will go through validation and, if it passes, automatically proceed to publish to Maven CentralUSER_MANAGED
: a deployment will go through validation and require the user to manually publish it via the Portal UI
An example request to upload a bundle might look like:
$ curl --request POST \
--verbose \
--header 'Authorization: Bearer ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhc3N3b3Jk' \
--form bundle=@central-bundle.zip \
https://central.sonatype.com/api/v1/publisher/upload
And the response might look like:
...
* We are completely uploaded and fine
< HTTP/2 201
< date: Fri, 26 Jan 2024 17:45:29 GMT
< content-type: text/plain;charset=UTF-8
< content-length: 36
< vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers, Accept-Encoding
<
* Connection #0 to host central.sonatype.com left intact
28570f16-da32-4c14-bd2e-c1acc0782365
The value that is returned is the deployment ID, which is needed to perform the operations such as retrieving information about the deployment.
Verify Status of the Deployment⚓︎
Once a deployment bundle has been uploaded and the corresponding deployment ID
has been retrieved, it is possible to request the status of that deployment via
a POST
request to /api/v1/publisher/status
with a query parameter of id
that contains the deployment ID.
An example request might look like:
$ curl --request POST \
--verbose \
--header 'Authorization: Bearer ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhca3N3b3JkCg==' \
'https://central.sonatype.com/api/v1/publisher/status?id=28570f16-da32-4c14-bd2e-c1acc0782365' \
| jq
And the response might look like:
{
"deploymentId": "28570f16-da32-4c14-bd2e-c1acc0782365",
"deploymentName": "central-bundle.zip",
"deploymentState": "PUBLISHED",
"purls": [
"pkg:maven/com.sonatype.central.example/example_java_project@0.0.7"
]
}
The deploymentState
field can have the following values:
PENDING
: A deployment is uploaded and waiting for processing by the validation serviceVALIDATING
: A deployment is being processed by the validation serviceVALIDATED
: A deployment has passed validation and is waiting on a user to manually publish via the Central Portal UIPUBLISHING
: A deployment has been either automatically or manually published and is being uploaded to Maven CentralPUBLISHED
: A deployment has successfully been uploaded to Maven CentralFAILED
: A deployment has encountered an error (additional context will be present in anerrors
field)
Publish or Drop the Deployment⚓︎
If a deployment was uploaded with a publishingType
of USER_MANAGED
and
reached a deploymentState
of VALIDATED
, it is possible to publish the
deployment via a POST
request to /api/v1/publisher/deployment/<deploymentId>
will move it into the PUBLISHING
deployment status, and from there, it will
make it's way to PUBLISHED
and be available on Maven Central.
An example request might look like:
$ curl --request POST \
--verbose \
--header 'Authorization: Bearer ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhc3N3b3Jk' \
'https://central.sonatype.com/api/v1/publisher/deployment/28570f16-da32-4c14-bd2e-c1acc0782365
And the response might look like:
< HTTP/2 204
< date: Tue, 30 Jan 2024 16:31:14 GMT
< vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
<
* Connection #0 to host central.sonatype.com left intact
If a deployment is in a VALIDATED
or FAILED
deployment state, it is possible
to drop the deployment with a DELETE
request to the
/api/v1/publisher/deployment/<deploymentId>
endpoint. This is useful to clean
up the deployment history for deployments that are not intended to be published.
If you are requesting support for FAILED
build, please do not drop them, as
the files associated with deployments are often useful for such requests.
An example request might look like:
$ curl --request DELETE \
--verbose \
--header 'Authorization: Bearer ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhc3N3b3Jk' \
'https://central.sonatype.com/api/v1/publisher/deployment/28570f16-da32-4c14-bd2e-c1acc0782365
And the response might look like:
...
< HTTP/2 204
< date: Tue, 30 Jan 2024 16:31:14 GMT
< vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
<
* Connection #0 to host central.sonatype.com left intact
Manually Testing a Deployment Bundle⚓︎
Once a bundle has been validated, it can be referenced as a dependency in your build tool of choice. The usecase of this would be to build a release in a CI environment, but perform manual testing in your local environment before releasing the deployment to Central.
There are two endpoints related to this feature,
/api/v1/publisher/deployment/<deploymentId>/download/<relativePath>
and
/api/v1/publisher/deployments/download/<relativePath>
. The first will
reference files from a specific deployment, while the second will reference any
validated deployment containing the requested file.
Maven⚓︎
For Maven, the configuration requires adding a <server>
and a <repository>
to your settings.xml
file with the required values. The <server>
will
require specifying the HTTP header to use with the request, while the repository
will require the URL mentioned above. An example configuration might look like
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>central.manual.testing</id>
<configuration>
<httpHeaders>
<property>
<name>Authorization</name>
<value>Bearer ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhc3N3b3Jk</value>
</property>
</httpHeaders>
</configuration>
</server>
</servers>
<profiles>
<profile>
<id>central.manual.testing</id>
<repositories>
<repository>
<id>central.manual.testing</id>
<name>Central Testing repository</name>
<url>https://central.sonatype.com/api/v1/publisher/deployments/download</url>
</repository>
</repositories>
</profile>
</profiles>
</settings>
and using this configuration would require running mvn <command>
-Pcentral.manual.testing
to request dependencies.
Gradle⚓︎
For Gradle, the documentation for declaring a repository does a good job of explaining how one might configure their build for this feature. An example configuration might look like
build.gradle
repositories {
maven {
name = "centralManualTesting"
url "https://central.sonatype.com/api/v1/publisher/deployments/download/"
credentials(HttpHeaderCredentials)
authentication {
header(HttpHeaderAuthentication)
}
}
mavenCentral()
}
gradle.properties
centralManualTestingAuthHeaderName=Authorization
centralManualTestingAuthHeaderValue=Bearer ZXhhbXBsZV91c2VybmFtZTpleGFtcGxlX3Bhc3N3b3Jk