[Legacy OSSRH] Open-source your Java Library by publishing to Maven Central using GitHub Actions
This article is outdated, Sonatype migrated away from the legacy method of publishing via OSSRH. https://central.sonatype.org/register/central-portal/#create-an-account
I have written an updated tutorial on how to deploy your Java library to Maven Central. https://www.dhirubhai.net/pulse/publishing-your-java-library-maven-central-using-yi-leng-yao-183zf/
If you have an awesome Java library that you want to leverage as a dependency in other projects, share with your team, friends or the broader developer community. Consider open-source the library by publishing it to Maven Central via GitHub Actions, so the artifact will be publicly accessible and usable by other developers around the world.
Premise
You have a Java library on hosted on GitHub, and you would like to host the artifact generated from this library on a open source hosting service, allowing other Java projects to import your library as a dependency.
Requirements
(Optional) Create and Host your Maven repository
You can skip this step if you already have a Java library hosted on GitHub.
Maven is a build automation and dependency management tool for Java projects. We will be using maven to bootstrap our Java library, compile the library into an artifact and publish to Maven Central.
To bootstrap your Java library.
mvn archetype:generate -DgroupId=<group-id> -DartifactId=<project name> -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
you need to provide the group id and project name.
Create a GitHub repository and add your Java library to the repository.
Create your OSSRH Account and Project
OSSRH stands for "Open Source Software Repository Hosting." It refers to the Nexus Repository Manager provided by Sonatype, which serves as an open-source platform to host you Java library. We will use OSSRH interchangebly with Maven Central and Staging.
Maven Central: is the primary repository of artifacts for the Java community. It’s where most Java developers pull their dependencies from.
Maven Staging: is the temporary hosting area of your artifact for testing purposes before promoting your artifact to Maven Central.
If you do not have an OSSRH Account or Project let’s create one.
Creating your repository usually takes less than 2 business, I would like to give a shoutout to Joel Orlina from Sonatype for their swift response in setting up the OSSRH repo.
You can read more about setting up your OSSRH project here.
Maven Plugin Setup
Add the following in your pom.xml
Licensing
<licenses>
<license>
<name>MIT License</name>
<url>https://www.opensource.org/licenses/mit-license.php</url>
</license>
</licenses>
Developer Information
<developers>
<developer>
<name>Your name</name>
<organization>Organization name</organization>
<organizationUrl>Organization url</organizationUrl>
</developer>
</developers>
Make sure to replace placeholders like Your name, Organization name, and Organization url , with your actual details.
SCM Information
<scm>
<connection>scm:git:git://github.com/{username}/{git repository name}.git</connection>
<developerConnection>scm:git:ssh://github.com:{username}/{git repository name}.git</developerConnection>
<url>https://github.com/{username}/{git repository}/tree/main</url>
</scm>
Make sure to replace placeholders like username and git repository name , with your actual details.
Distribution Management
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
Javadoc and Sources Plugin
<!-- Plugin for Javadoc and Sources -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<links>
<link>https://docs.oracle.com/en/java/javase/17/docs/api/</link>
</links>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Nexus Staging Plugin
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.13</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>${env.AUTO_RELEASE_AFTER_CLOSE}</autoReleaseAfterClose>
</configuration>
</plugin>
This will deploy the build artifacts of your Java library to to the Sonatype Nexus repository.
The <autoReleaseAfterClose> configuration
GPG Plugin for Artifact Signing
<!-- GPG Signed Components -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
<passphrase>${env.GPG_PASSPHRASE}</passphrase>
</configuration>
</execution>
</executions>
</plugin>
Signing build artifacts with GPG is a requirement for publishing to Maven Central for security and authenticity.
Here the <passphrase>${env.GPG_PASSPHARASE}</passphrase> is passed in as an environment variable when the GitHub action is executed. The specifics of setting this environment variable will be explored in the upcoming section when we configure the GitHub Action.
Maven Settings for OSSRH Deployment
To set up Maven for OSSRH deployment, incorporate the provided settings.xml into your repository:
<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="https://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"
xmlns="https://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
<servers>
<server>
<id>ossrh</id>
<username>${env.MAVEN_USERNAME}</username>
<password>${env.MAVEN_PASSWORD}</password>
</server>
</servers>
</settings>
This configuration allows maven to fetch the MAVEN_USERNAME and MAVEN_PASSWORD from the GitHub action environment variables, granting the action the necessary permissions to deploy to the Maven staging repository.
Publish your Library with GitHub Actions
领英推荐
name: Publish Package to Maven Central
on:
pull_request:
branches:
- main
- develop
types: [closed]
jobs:
publish:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Step 1 - Checkout code
uses: actions/checkout@v3
- name: Step 2 - Import GPG key
run: |
echo "${{ secrets.GPG_PUBLIC_KEY }}" | gpg --import
echo "${{ secrets.GPG_SECRET_KEY }}" | gpg --import --no-tty --batch --yes
- name: Step 3 - Set up Maven Central Repository
uses: actions/setup-java@v3
with:
java-version: "17"
distribution: "temurin"
server-id: ossrh
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
# Set AUTO_RELEASE_AFTER_CLOSE based on branch and adjust version if develop
- name: Step 4 - Prepare Environment Variables and Adjust Version if Develop Branch
run: |
if [[ "${{ github.base_ref }}" == "main" ]]; then
echo "AUTO_RELEASE_AFTER_CLOSE=true" >> $GITHUB_ENV
else
echo "AUTO_RELEASE_AFTER_CLOSE=false" >> $GITHUB_ENV
# Extract current version, append -SNAPSHOT and update the pom.xml
VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec)
NEW_VERSION="${VERSION}.$(date +'%Y%m%d%H%M%S')-SNAPSHOT"
mvn versions:set -DnewVersion=$NEW_VERSION
fi
- name: Step 5 - Publish package
run: mvn --batch-mode deploy
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
The provided configuration initiates a GitHub Action when a PR merges into either the main or develop branch (create a develop branch in your GitHub repository is you have not).
if [[ "${{ github.base_ref }}" == "main" ]]; then
echo "AUTO_RELEASE_AFTER_CLOSE=true" >> $GITHUB_ENV
else
echo "AUTO_RELEASE_AFTER_CLOSE=false" >> $GITHUB_ENV
# Extract current version, append -SNAPSHOT and update the pom.xml
VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec)
NEW_VERSION="${VERSION}.$(date +'%Y%m%d%H%M%S')-SNAPSHOT"
mvn versions:set -DnewVersion=$NEW_VERSION
fi
The above configuration will set the configuration <autoReleaseAfterClose> to true when you merge to main and false if your merge to develop.
So merging your PR to
This strategy allows to do testing and verification on Maven staging by merging your PR to the develop branch. Once testing is done, merging a PR to the main branch will make your library public by publishing to Maven Central.
Since you cannot overwrite an artifact version on Maven staging or Central, this code NEW_VERSION”${VERSION}.$(date+'%Y%m%d%H%M%S')-SNAPSHOT” will append timestamp and “SNAPSHOT” to a version number. This guarantees a distinct version each time you deploy to Maven staging for testing.
The following secret keys are needed to publish to OSSRH (Maven Central or Staging)
Setting up Secret Keys
Accessing OSSRH Credentials
Log into https://s01.oss.sonatype.org/ , then go to Profile, and click on Access User Token
After clicking on “Access User Token”, you’ll see two pieces of information:
GPG Key Generation
GPG keys are essential for signing your artifact before publishing to OSSRH, ensuring its authenticity and integrity.
Download and install GPG from https://gnupg.org/download/index.html#sec-1-2 .
Run the following command to generate your GPG keys, remember to use the email associated with your OSSRH account, and remember your passphrase.
gpg --gen-key
Then run the following commands to export GPG_PUBLIC_KEY and GPG_SECRET_KEY.
gpg --armor --export YOUR_EMAIL_USED_WHEN_GENERATING_THE_KEY > public-key.gpg
gpg --armor --export-secret-key YOUR_EMAIL_USED_WHEN_GENERATING_THE_KEY > secret-key.gpg
Setting Up Github Secrets
On your GitHub repository go to Settings then Secrets and variables , then click Actions
Then click on New repository secret
Then fill the the secret for the secret keys, and click on add secrets
Deployment Workflow
Now we are ready to deploy your package.
Deploy to Staging
Open a PR that merges to the develop branch.
After merging the PR, a GitHub Action is initiated to deploy to Maven Staging. The artifact’s URL can be located within the logs of this GitHub Action.
You can also find your published artifact on Maven staging by going to https://s01.oss.sonatype.org/ and searching for your groupid.
To pull artifacts from Maven staging into another Java repository, modify the pom.xml of that repository. First, add the Maven staging repository:
<repositories>
<!-- other repositories if any -->
<repository>
<id>ossrh-staging</id>
<url>https://s01.oss.sonatype.org/content/repositories/staging/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
Then, include your artifact as a dependency:
<dependencies>
<!-- other dependencies if any -->
<dependency>
<groupId>your.group.id</groupId>
<artifactId>your-artifact-id</artifactId>
<version>your-version</version>
</dependency>
</dependencies>
Deploy to Maven Central
After thoroughly testing your code, open a PR targeting the main branch. Once merged, this will activate a GitHub Action to deploy to Maven Central.
Upon successful completion of the GitHub action, you can locate your artifact on Maven staging at https://s01.oss.sonatype.org/. Typically, within 10 minutes, your artifact will be available on Maven Central. Simply visit https://central.sonatype.com/ or https://mvnrepository.com/ and a search with yourgroupId.
Congratulations! Your library is now accessible to the global developer community.
Here is the related GitHub repo for reference:
Happy Developing! ??.
Related Medium article
Technical Architect Backend @ OLX | Standup Comedian
8 个月How do i get OSSRH Credentials? for https://s01.oss.sonatype.org/?