Enterprise Java

Deploy to Maven Central Repository

Do you need to make your Java library publicly accessible? Is your project hosted on GitHub? Do you like idea of “all-in-one deploy to Maven Central Repository” button? I am going to show how to set it up with usage of maven-release-plugin. Source code is hosted on GitHub, so SSH access to source control will be also described.

There are various steps needed to set up environment for your project. I followed a lot of steps from official SonaType guide, therefore I will refer to it when needed. But this guide also describes a lot of techniques that are not needed for configuring “deploy to Maven Central repository” button.
 
 

Consideration

My first approach was to create Jenkins job that would represent the “Deploy to Maven Central” button. This idea is much cleaner for me  than pushing from my development machine. I was trying it hardly but couldn’t make Jenkins SSH Agent plugin to register my SSH identity when maven-release-plugin is pushing version update to GitHub. Therefore very simple Linux Bash script is involved in two steps.

1. Create SonaType JIRA ticket for registration of your groupId

SonaType drives one of the biggest Nexus repositories. It is needed to deploy Java artifact there before it can be synced into Maven Central repository. In order to release Java library into SonaType Nexus repository, JIRA ticket is needed. SonaType guide includes detailed description how to create it.

Pick up Maven groupId reflecting your top level domain. It is typically same as main Java package (e.g. com.google, not com.google.guava). This is because you don’t want to create JIRA ticket for each project/library under your domain/main package/groupId.  Here is more reading about Java package naming convention.

2. Inherit your Maven artifact from SonaType OSS pom.xml

SonaType parent POM contains

  • URL to SonaType Nexus repository
  • Configuration of Maven plugins
    • Enforcer plugin
    • Release plugin – this one is most important
    • Source plugin – generates JAR with sources
    • JavaDoc plugin – generates JAR with JavaDoc comments
    • GPG plugin – signs artefact with GnuPG tool (this is required by Maven Central Repository)
<parent>
	<groupId>org.sonatype.oss</groupId>
	<artifactId>oss-parent</artifactId>
	<version>9</version>
</parent>

Existence of this parent POM is handy because otherwise you would need to specify all plugins in your POM. The only problem is that plugin versions are slightly out of date, so I decided to override some versions in my POM this way:

<pluginManagement>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-gpg-plugin</artifactId>
			<version>1.5</version>
		</plugin>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-release-plugin</artifactId>
			<version>2.4.2</version>
		</plugin>
	</plugins>
</pluginManagement>

Crucial version update here is GPG plugin one, because updated version have handy features described section about GPG signing.

3. Configure GPG signing of Maven artefact

This is needed because of security policy of Maven Central repository. Include various sub-steps:

<profiles>
  <profile>
    <id>sonatype-oss-release</id>
    <properties>
      <gpg.keyname>F21879F3</gpg.keyname>
      <gpg.passphrase>*********</gpg.passphrase>
      <gpg.defaultKeyring>false</gpg.defaultKeyring>
      <gpg.useagent>true</gpg.useagent>
      <gpg.lockMode>never</gpg.lockMode>
      <gpg.homedir>/home/lkrnac/.gnupg</gpg.homedir>
      <gpg.publicKeyring>/home/lkrnac/.gnupg/pubring.gpg</gpg.publicKeyring>
      <gpg.secretKeyring>/home/lkrnac/.gnupg/secring.gpg</gpg.secretKeyring>
    </properties>
  </profile>
</profiles>

F21879F3 is my public GPG key ID. gpg –list-keys command would list it for you. Passphase is password for your private GPG key. .gnupg folder is typically generated in your home directory.

4. Set up your credentials for SonaType Nexus repository

Needed for push to SonaType Nexus repository. Same as SonaType JIRA credentials. Again in settings.xml:

<servers>
  <server>
    <id>sonatype-nexus-snapshots</id>
    <username>lkrnac</username>
    <password>*************</password>
  </server>
  <server>
    <id>sonatype-nexus-staging</id>
    <username>lkrnac</username>
    <password>*************</password>
  </server>
</servers>

5. Fill pom.xml mandatory sections

6. Set up SSH access to GitHub

Follow these sub-steps:

7. Create “Deploy to Maven Central” button

Maven-release-plugin needs to push/check-in version update to source control system and tag the revision. In my case the code is hosted on GitHub. Therefore I need to register my SSH identity (generated in previous step) before invoking maven-release-plugin’s goals. This is done by bash script maven-central-deploy.sh located alongside pom.xml:

!/bin/bash
# Deploy maven artefact in current directory into Maven central repository 
# using maven-release-plugin goals

read -p "Really deploy to maven cetral repository  (yes/no)? "

if ( [ "$REPLY" == "yes" ] ) then
  ssh-add ~/.ssh/lubos.krnac
  ssh-add -l
  mvn release:clean release:prepare release:perform -B -e | tee maven-central-deploy.log
  ssh-add -D
else
  echo 'Exit without deploy'
fi

Make the script executable by

chmod +x maven-central-deploy.sh

 8. Push the “Deploy to Maven Central” button

Just run

./maven-central-deploy.sh

confirm and enter SSH private key passphase if required.

9. Release artifact via SonaType Nexus repository

When the artifact is pushed to SonaType Nexus repository. You need to release it. Finally you would need to add comment to the SonaType JIRA issue you created at the beginning and wait until somebody reviews your artifact and sets up the sync to Maven Central. Of course JIRA part would need to be done only once.

Link

  • Example project configured this way is hosted on GitHub. (It’s tiny testing library).

 

Reference: Deploy to Maven Central Repository from our JCG partner Lubos Krnac at the Lubos Krnac Java blog blog.

Lubos Krnac

Lubos is a Java/JavaScript developer/Tech Lead and Automation enthusiast. His religion is to constantly improve his developments skills and learn new approaches. He believes TDD drives better design and nicely decoupled code. Past experience includes C++, Assembler and C#.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button