How to publish artifacts to Maven Central via Gradle

Publishing artifacts on Maven Central is a close equivalent to publishing Python packages on PyPI (aka the cheese shop). If you have published packages on PyPI before, you will find these steps a bit more advanced than those you tackled in Python.

0. First things first
1. Sign up
2. Apply for your namespace
3. Get the GPG key
4. Save your secrets
5. Set up your project to upload
6. Upload
7. Publish on Maven Central
8. Use it

0. First things first

No one can publish to Maven Central directly. You have to publish your artifacts to an approved repository, then release them to Maven Central.
 
Sonatype OSS Nexus​ is an approved repository hosting service run by Sonatype (the company that runs Maven Central) which provides hosting free of charge specifically for open-source projects.

 

1. Sign up

Hopefully, you know about namespaces, packages and groupIds, right? To upload an artifact into a Sonatype repo, your artifact should be created using a specific namespace in order to prevent naming collisions. The package and groupId are also required. You must apply for a namespace from Sonatype. To apply for a namespace, you will need to raise an issue (see below) on the Sonatype Jira instance. In order to do that, you will first need to sign up for a Sonatype Jira account.

Tips

  • Sign up with your company email if you are going to apply for a groupId which will be the domain name of your company.
  • Remember your user name and password. It is not only used for raising issues. It is used for uploading your artifacts as well.

 

2. Apply for your namespace

Create an issue here to apply for your namespace (it should be a reversed domain name). Your issue will be manually reviewed by a Sonatype employee. It should be fast, within 2 hours.

Tips

After your application is approved, you will gain permission to the following URLs:

 

3. Get the GPG key

If you use Mac, you should download and install GPG Suite. Then open the app. The generate new key pair dialogue box should automatically open, otherwise press New on the tope menu in the app to create your key pair.

  • Name is the user name that you used when you registered on Sonatype.
  • Email is the email address that you used when you registered on Sonatype.
  • Enter a unique password twice to confirm it. Remember this password too, you are going need it.
  • Advanced options can be left as they are.

Needs confirmation: I don’t know whether the user name and email need to match, but I matched them both just in case.

After successfully creating your key, either accept the option to Upload Public Key in the dialogue box displayed or right-click your key in the key list in the app and select Send Public Key to Key Server to publish your public key.
 
To find your Key ID double-click your key in the key list in the app, select the Key tab if not already selected, note it down.
 
In Terminal on your Mac, use this command to get the secret key ring file:
gpg --export-secret-keys YOUR-KEY-ID > secret-keys.gpg

Enter the passphrase you used when you created the key in the Pinentry Mac dialogue box when it is displayed. The secret-keys.gpg file will be located in the folder where you ran GPG export command above. Take note of the path to this file, it will be needed later.
 
If you use Windows or other systems, you just need to get the following 3 things in order to push any further:

  • Key ID of your newly generated key pair.
  • The key password for this key pair.
  • The secret key ring file called secret-keys.gpg.

4. Save your secrets

Create your ​gradle.properties file or open it if you already have one and add the following code:

nexusUsername=YOUR_SONATYPE_USER_NAME
nexusPassword=YOUR_SONATYPE_USER_PASSWORD

signing.keyId=KEY_ID
signing.password=KEY_PASSWORD
signing.secretKeyRingFile=/PATH/TO/SECRET/RING/FILE

Tips

  • Add the gradle.properties to your project root folder rather than in the .gradle  or gradle folders. Why? I am using Intellij IDEA and my IDEA gradle settings file could not be found if I put it either of those two folders. I had to put it in the project root.
  • ADD THE gradle.properties FILE TO YOUR PROJECT’S .gitignore. You never want to release this to the repo (it has your key password).

 

5. Set up your project to upload

There is an official guide here using the Maven gradle plugin, but I choose to use ​com.bmuschko.nexus because I found it easier to understand and use.
 
Below is the full code listing of the build.gradle ​com.bmuschko.nexus plugin. Add it to your current gradle code:


buildscript {
  repositories {
     jcenter()
  }
  dependencies {
     classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1'
  }
}

apply plugin: 'com.bmuschko.nexus'

archivesBaseName = 'teachUpload-jvm'
group = "com.yourCompany.package"
version = "0.1"

modifyPom {
 project {
   name 'teachUpload'
   description 'Teaching how to use gradle.'
   url 'https://bitbucket.org/objdict/objjson'
   inceptionYear '2018'

   scm {
     url 'https://bitbucket.org/objdict/objjson'
     connection 'scm:https://bitbucket.org/objdict/objjson.git'
     developerConnection 'scm:git://bitbucket.org/objdict/objjson.git'
   }

   licenses {
     license {
       name 'The Apache Software License, Version 2.0'
       url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
       distribution 'repo'
     }
   }

   developers {
     developer {
       id 'albertgao'
       name 'Albert Gao'
       email 'albert.gao@salect.co.nz'
     }
   }
 }
}

extraArchive {
 sources = true
 tests = true
 javadoc = true
}

nexus {
 sign = true
 repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
 snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
}

Tips

  • You don’t need to create the sourceJar in the build.gradle settings file above. The ​com.bmuschko.nexus plugin will add it for you.

6. Upload

The above code should add an uploadArchives task to your gradle (it might reside in the upload category (if you can’t find it in your IntelliJ IDEA gradle side-panel)).

Double click it to execute the uploadArchives task.
 
You might see the following error when you first upload:
Could not find metadata com.yourCompany.package:teachUpload-jvm/maven-metadata.xml in remote (https://oss.sonatype.org/service/local/staging/deploy/maven2/)

  • This is not an error, just information – this is your first time, so no meta file previously existed on the server.
  • Your package will have already been uploaded if this is the only information displayed.

Congratulations! After completing all of these steps, your package should finally have been uploaded onto Sonatype OSS Nexus.

 

7. Publish on Maven Central

There are two ways to get your artifacts onto Maven Central:

  1. Auto-publish via gradle
  2. Manually publish via Nexus website

7.1 Auto-publish via gradle

We are going to need to use another gradle plugin called Gradle Nexus Staging plugin.

Just add the following gradle code:


plugins {
    id 'io.codearte.nexus-staging' version '0.11.0'
}
nexusStaging {
    // optional if packageGroup == project.getGroup()
    packageGroup = "org.mycompany" 

    // when not defined will be got from server using "packageGroup"
    stagingProfileId = "yourStagingProfileId"
}

Now several gradle tasks will exist:

  • closeRepository – closes an open repository with the uploaded artifacts. There should be just one open repository available in the staging profile (possible old/broken repositories can be dropped with Nexus GUI)
  • releaseRepository – releases a closed repository (required to put artifacts to Maven Central aka The Central Repository)
  • closeAndReleaseRepository – closes and releases a repository (an equivalent to closeRepository and then releaseRepository)
  • getStagingProfile – gets and displays a staging profile id for a given package group. This is a diagnostic task to get the value and put it into the configuration closure as stagingProfileId.

Now you should already have uploaded your artifacts to the Nexus repo. All you need to do now is to run the closeAndReleaseRepository, and your artifacts will be added to Maven Central (within 10 min ~ 2 hours).

Tips:

  • If you have a multiple project gradle setup. You just need to add this plugin at the root level.

7.2 Manually publish via Nexus website

The reason we still need this publishing option is that sometimes there are some errors during the auto-publishing phase. After publishing, check the status on the website. Follow the steps below to publish manually if the auto option is unsuccessful.

  1. Open the Nexus Repository Manager.
  2. Click the Log In button in the upper right corner of the screen.
  3. On the right-hand side, click Staging Repositories.
  4. Search your project by following this search pattern: if for example, your groupId is com.google, then enter comgoogle.
  5. Select the correct item and click the Close button to close it – this action finalizes the upload.
  6. Click the Refresh button to get the latest updates (remember this trick, no ajax yet).
  7. If see any errors:
    • You can inspect them at the Activity panel.
    • You will need to:
      •  Drop this upload
      • Find and fix the errors in your local folder
      • Run the uploadArchives task again
      • Then finalize the upload by pressing the Close button again and then continue
  8. If you see NO errors:
    • Click the Release button to publish

Congratulations! Your artifact should have finally been uploaded to Maven Central.

8. Use it

In the build.gradle file in your project, add the following if you want to use this package:


repositories {
    mavenCentral()
}

dependencies {
    compile "com.yourCompany.package:teachUpload-jvm:0.1"
}

The pattern in our example is: groupId:archiveBaseName:versionNumber
where:

          groupId = com.yourCompany.package
          archiveBaseName = teachUpload-jvm
          versionNumber = 0.1

 

End

Hopefully now you get it and everything is set up! Enjoy. 🙂

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s