Skip to content

Instantly share code, notes, and snippets.

@slominskir
Last active February 28, 2023 12:37
Show Gist options
  • Save slominskir/5fcd5cf84182bf1542c07cbca953904a to your computer and use it in GitHub Desktop.
Save slominskir/5fcd5cf84182bf1542c07cbca953904a to your computer and use it in GitHub Desktop.
Gradle Maven Publish Notes

We rely on the Gradle build tool and the "maven-publish" plugin to publish library artifiacts to Maven Repositories.

Where to publish

There are a few common repos:

  1. Maven Central (via Sonatype OSSRH)
  2. GitHub Maven Repo
  3. Gradle Plugin Portal

Authorization

Repos require authorization to publish. Maven Central and Gradle Plugin Portal will require you add a TXT record to your DNS server on your domain, else you must use a personal package namespace rooted from io.github such as io.github.your-username. All require that you create an account. GitHub doesn't allow you to choose namespace, it's your GitHub namespace. Therefore no DNS TXT record needed.

Signing

Most Maven repos require that artifacts are signed with GPG via the signing plugin. This turns out to add a ton of complexity.

Publication Plugin

There is a maven-publish plugin that is used by all repos. They use it slightly differently though.

Maven Central

Publishing to maven central can be done with just the signing and maven-publish plugins. Maven Central actually always references other hosting services and the open source hosting service for Maven Central is named OSSRH, so actually you're publishing there. The process actually requires first "staging", then "closing", followed by "releasing", then "dropping". Without additional plugins this means you have to manually login to the OSSRH website and click a bunch of buttons after staging, which is the only step the maven-publish plugin does.

In order to execute the Gradle publishMavenPublicationToOSSRHRepository task you need to have credentials set (usually in ~/.gradle/gradle.properties file). The following properties are needed:

  • ossrh.user
  • ossrh.token
  • signing.keyId
  • signing.password
  • signing.secretKeyRingFile

GitHub Maven Repo

This repo requires that consumers authenticate to obtain artifacts. GitHub artifacts in general doesn't support several other language repos yet (like Python/PIP) so it doesn't quite fit the one-stop-shop feature either. Best just stick with each language de-facto repo for now (Maven Central for Java).

Gradle Plugin Portal

This repo requires use of the com.gradle.plugin-publish plugin.

Note: You can also publish plugins to maven central via the java-gradle-plugin. A single plugin actually consists of two publications: the actual plugin, plus a "marker" publication that acts like a reference/link.

Additional OSSRH Plugin:

This additional plugin handles the "close", "release", and "drop" tasks as well so may be a good choice:

https://github.com/gradle-nexus/publish-plugin

However, this all-in-one plugin doesn't play well with various Gradle features such as multi-project builds and the Gradle plugin publishing plugins.

GitHub Action

Ideally, publication is automated such that it can be done automatically on release. This is complicated by credentials and keys. The signing plugin can be configured to support a PRIVATE_SIGNING_KEY and SIGNING_PASSWORD variables via GitHub Action Secrets feature. This is different than the standard signing approach in which a keyring file is used with a KEY_ID and SIGNING_PASSWORD. If you attempt to standardize on the former approach you'll discover that the long multi-line PRIVATE_SIGNGING_KEY environment variable is problematic in other environment such as Windows.

Windows Long Multi-line Env

If you use the GUI Environment tool or setx you'll run into issues. Instead, launch Powershell then execute:

$var=@'
-----BEGIN PGP PRIVATE KEY BLOCK-----

...
...
...
-----END PGP PRIVATE KEY BLOCK-----
'@

[Environment]::SetEnvironmentVariable('ORG_GRADLE_PROJECT_signingKey', $var, 'User')
[Environment]::GetEnvironmentVariable("ORG_GRADLE_PROJECT_signingkey", "User")

Other Release Tasks

Bump version

The build.gradle file version needs to be bumped, following semantic versioning.

Create GitHub Release

The Release feature on GitHub is a great place to tag and document release notes

Update Javadocs

Make sure to update the gh-pages branch in the repo with the latest Javadocs. If you want to get fancy, create new directory for each version so history of API docs is maintained and an index.html can be used to select version. This can be automated with GitHub Actions as well. See: gh-pages-publish.yml

Instead of using gh-pages, consider https://www.javadoc.io/. It automates this process well, BUT: unclear how permanent/reliable it is.

See Also

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment