DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Private Remote Maven Repository With Artipie
  • DevOps: CI/CD Tools to Watch Out for in 2022
  • Look, Ma! No Pods!
  • Release Pipeline Using Azure DevOps

Trending

  • How Large Tech Companies Architect Resilient Systems for Millions of Users
  • Top Book Picks for Site Reliability Engineers
  • Event-Driven Architectures: Designing Scalable and Resilient Cloud Solutions
  • A Developer's Guide to Mastering Agentic AI: From Theory to Practice
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. How to Publish Artifacts to Maven Central

How to Publish Artifacts to Maven Central

Publishing artifacts to Maven Central with GitHub Actions made easy!

By 
Domenico Sibilio user avatar
Domenico Sibilio
·
Jan. 12, 21 · Tutorial
Likes (8)
Comment
Save
Tweet
Share
17.3K Views

Join the DZone community and get the full member experience.

Join For Free


Publishing your first artifact to Maven Central can be as exciting as it can be confusing. We’ll see together how to make your first time as smooth as it should be, while also making sure people can easily contribute to your open source Java libraries. Lastly, we’ll see how to craft a Maven Central-ready CI/CD pipeline via GitHub Actions.

Introduction

Uploading your Java code to Maven Central is an important step towards actively contributing to the Java open source community, and it, therefore, mandates you follow a series of quite strict requirements.

Let’s go over each one of these requirements and streamline the process, shall we?

P.S., you can refer to one of the projects I published to Maven Central as a reference in case any doubts arise: https://github.com/dsibilio/badge-maker

Informative POM

The first thing to do is to make sure that your groupId matches a domain that you own or, alternatively, the domain that is used for sharing your open source project.

Assuming I own the dsibilio.com domain (which I don’t), and I’d be hosting my project over at GitHub, the following would all be valid groupIds:

  • com.dsibilio
  • com.github.dsibilio
  • io.github.dsibilio 

The next thing to do is to make sure that your pom.xml file includes all of the required information:

  • licenses
  • developers
  • SCM

Putting the proper information in the tags is quite intuitive. Here you can find an example of the tags to include in your POM:

XML
 




x
18


 
1
    <licenses>
2
        <license>
3
            <name>The Apache License, Version 2.0</name>
4
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
5
        </license>
6
    </licenses>
7
    <developers>
8
        <developer>
9
            <id>dsibilio</id>
10
            <name>Domenico Sibilio</name>
11
            <email>domenicosibilio@gmail.com</email>
12
        </developer>
13
    </developers>
14
    <scm>
15
        <connection>scm:git:git@github.com:dsibilio/badge-maker.git</connection>
16
        <developerConnection>scm:git:ssh://github.com:dsibilio/badge-maker.git</developerConnection>
17
        <url>https://github.com/dsibilio/badge-maker/tree/main</url>
18
    </scm>


For more examples, you can refer to the Sonatype Metadata Requirements.

Plugins for Days

When publishing artifacts to Maven Central, you have to make sure your source code and Javadoc are uploaded as well. You can achieve this by adding the following section to your pom.xml:

XML
 




xxxxxxxxxx
1
35


 
1
    <build>
2
        <plugins>
3
            <plugin>
4
                <groupId>org.apache.maven.plugins</groupId>
5
                <artifactId>maven-source-plugin</artifactId>
6
                <version>3.2.1</version>
7
                <executions>
8
                    <execution>
9
                        <id>attach-sources</id>
10
                        <goals>
11
                            <goal>jar-no-fork</goal>
12
                        </goals>
13
                    </execution>
14
                </executions>
15
            </plugin>
16
            <plugin>
17
                <groupId>org.apache.maven.plugins</groupId>
18
                <artifactId>maven-javadoc-plugin</artifactId>
19
                <version>3.2.0</version>
20
                <executions>
21
                    <execution>
22
                        <id>attach-javadocs</id>
23
                        <goals>
24
                            <goal>jar</goal>
25
                        </goals>
26
                    </execution>
27
                </executions>
28
            </plugin>
29
            <plugin>
30
                <groupId>org.apache.maven.plugins</groupId>
31
                <artifactId>maven-surefire-plugin</artifactId>
32
                <version>2.22.2</version>
33
            </plugin>
34
        </plugins>
35
    </build>


Furthermore, you need to sign your artifacts before releasing them. I suggest making a different Maven profile for this, as it would make it impossible for other people to contribute to your library as they wouldn’t, and shouldn’t, know your signature's private key/passphrase.

For example:

XML
 




x
31


 
1
    <profiles>
2
        <profile>
3
            <id>ci-cd</id>
4
            <build>
5
                <plugins>
6
                    <plugin>
7
                        <groupId>org.apache.maven.plugins</groupId>
8
                        <artifactId>maven-gpg-plugin</artifactId>
9
                        <version>1.6</version>
10
                        <executions>
11
                            <execution>
12
                                <id>sign-artifacts</id>
13
                                <phase>verify</phase>
14
                                <goals>
15
                                    <goal>sign</goal>
16
                                </goals>
17
                                <configuration>
18
                                    <!-- Prevent gpg from using pinentry programs. Fixes: gpg: signing 
19
                                        failed: Inappropriate ioctl for device -->
20
                                    <gpgArguments>
21
                                        <arg>--pinentry-mode</arg>
22
                                        <arg>loopback</arg>
23
                                    </gpgArguments>
24
                                </configuration>
25
                            </execution>
26
                        </executions>
27
                    </plugin>
28
                </plugins>
29
            </build>
30
        </profile>
31
    </profiles>


This snippet makes it so that the signing process is triggered only when building our library with the flag -Pci-cd. Quite handy!

NOTE: the pinentry-mode=loopback is necessary to avoid GPG prompting manual entry of the GPG passphrase. This is crucial when running your build on a remote agent!

Requesting Access to Maven Central

Make sure your project is looking good. It’s time to request permission to publish it on Maven Central!

You need to register an account over at Sonatype JIRA and create a new issue for this.

Feel free to use the issue I opened as a template, but make sure to fill-in all the required fields with your data.

Repository Setup

Finally, you need to include the Sonatype snapshots/staging repositories in your pom.xml as follows:

XML
 




xxxxxxxxxx
1
10


 
1
    <distributionManagement>
2
        <snapshotRepository>
3
            <id>ossrh</id>
4
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
5
        </snapshotRepository>
6
        <repository>
7
            <id>ossrh</id>
8
            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
9
        </repository>
10
    </distributionManagement>


NOTE: if you need to deploy your artifact through local builds, you should add your Sonatype JIRA credentials to your ~/.m2/settings.xml file as follows:

XML
 




x


 
1
<servers>
2
    <server>
3
      <id>ossrh</id>
4
      <username>sonatypeUser</username>
5
      <password>verySecretPassword</password>
6
    </server>
7
</servers>


GPG Setup

You’ll have to create and distribute a new GPG key, so start by downloading and installing GnuPG (you can also find the Windows-compatible version, Gpg4win).

You should now follow the Sonatype recommendations to generate your key, manage its expiration, and ultimately send it over to the required keyservers!

Some of the keyservers to which you should send your public project include the following:

  • hkp://pool.sks-keyservers.net
  • https://pgp.key-server.io/
  • https://keyserver.ubuntu.com/
  • https://pgp.mit.edu/
  • http://keys.gnupg.net/

IMPORTANT: make sure to remember your GPG passphrase/keep it somewhere safe!

If you don’t intend on using GitHub Actions, you can skip the following section. Your project is good enough as it is, so you can just run mvn clean deploy -Dgpg.passphrase="myPassphrase" -Pci-cd to build and deploy your artifact to Sonatype snapshots/staging repositories and perform the release process.

CI/CD With GitHub Actions

Building and deploying via GitHub Actions is quite easy, but, in this specific scenario, there are a few things to account for.

First of all, you need to obtain your GPG private key. To do so, you should first identify your GPG key and fetch its ID via gpg --list-keys; you can then export the ASCII-armored version of your private key by running

gpg --armor --export-secret-keys YOUR_KEY_ID > private.gpg

and providing your passphrase when prompted.

You can now proceed to add all of the GitHub Secrets that are required for your build to work. Navigate to your repository and go to Settings > Secrets and add the following key/value pairs:

  • MAVEN_GPG_PASSPHRASE: your GPG passphrase.
  • MAVEN_GPG_PRIVATE_KEY: the contents of the private.gpg file you just created.
  • OSSRH_USERNAME: your Sonatype username.
  • OSSRH_TOKEN: your Sonatype password.

Your secrets should end up looking like this:


You’re now ready to add the CI/CD pipeline to your GitHub project. Add the following.github/workflows/maven.yml file to your project. It will take care of building, signing, and deploying your artifact to the Sonatype repository every time someone pushes changes to the main branch.

YAML
 




xxxxxxxxxx
1
30


 
1
# This workflow will build a Java project with Maven
2
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3

          
4
name: Java CI with Maven
5

          
6
on:
7
  push:
8
    branches: [ main ]
9

          
10
jobs:
11
  build:
12
    runs-on: ubuntu-latest
13

          
14
    steps:
15
    - uses: actions/checkout@v2
16
    - name: Set up Maven Central Repository
17
      uses: actions/setup-java@v1
18
      with:
19
        java-version: 1.8
20
        server-id: ossrh
21
        server-username: MAVEN_USERNAME
22
        server-password: MAVEN_PASSWORD
23
        gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
24
        gpg-passphrase: MAVEN_GPG_PASSPHRASE
25
    - name: Deploy with Maven
26
      run: mvn -B clean deploy -Pci-cd
27
      env:
28
        MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
29
        MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
30
        MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}


NOTE: if your version ends with -SNAPSHOT, the artifact will be deployed to the snapshots repository. If it doesn’t, it will instead be uploaded to the staging repository, where you can ultimately decide to release it whenever you want!

Release Process

Assuming you already built and deployed a non-snapshot artifact on Sonatype, you can now double-check that all the requirements are satisfied and proceed with your first release!


To do so, simply login to the Sonatype Repository Manager with your Sonatype credentials and:

- move to the “Staging Repositories” section on the left.

- choose the staging repository to promote.

- “Close” the staging repository.

- “Release” the staging repository.

Et voilà, les jeux sont faits! 

If all the requirements were satisfied, your staging repository should now be deleted. You have to comment on the Sonatype JIRA issue you first opened, confirming that you just performed your first release, and wait for Maven Central to synchronize (should take up to 20 minutes, whereas https://search.maven.org/ can take up to 2 hours to show your newly deployed artifact).

Congratulations on your first release!

Wrap Up

The process to deploy and release artifacts to Maven Central can be quite convoluted, but many of these steps are one-time only and the others are quick and easy to repeat every time you want to release a new library for the world to use!

If you liked what you just read, please follow me on Medium and Twitter for more articles like this. I’d really appreciate it!

Apache Maven Artifact (UML) Open source Repository (version control) Continuous Integration/Deployment Release (computing)

Opinions expressed by DZone contributors are their own.

Related

  • Private Remote Maven Repository With Artipie
  • DevOps: CI/CD Tools to Watch Out for in 2022
  • Look, Ma! No Pods!
  • Release Pipeline Using Azure DevOps

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!