1. Overview
In this tutorial, we’ll learn how to create a Maven artifact and make it publicly available. We’ll discuss the project structure, building the JAR file with Maven, and publishing it to GitHub Packages.
After that, we’ll see how clients can install our package from the GitHub repository as a Maven dependency.
2. Creating the Maven Project
We’ll create a small library of utility functions for unit testing. We’ll start by setting up a Maven project and configuring the main properties in the pom.xml.
Since we’re publishing to GitHub Packages, we’ll use the io.github.<github_username> pattern for the groupId. Apart from this, we’ll set default properties like the artifactId, version, project name, and description, packaging as jar, and the Java version:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.etrandafir93</groupId>
<artifactId>utilitest</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Utilitest</name>
<description>A collection of test helpers for AssertJ, Mockito and Awaitility</description>
<url>https://github.com/etrandafir93/utilitest</url>
<properties>
<java.version>11</java.version>
</properties>
<!-- license, distribution, dependenceis, build... etc. -->
</project>
3. Adding a License
A license for an open-source project is a legal agreement that defines how the project’s code can be used, modified, and distributed by others. We can add a license to our Maven project, by adding the
<licenses>
<license>
<name>MIT License</name>
<url>http://www.opensource.org/licenses/mit-license.php</url>
</license>
</licenses>
As we can see, we’ve chosen the MIT License, which allows anyone to use, modify, and distribute the software – as long as the original license and copyright notice are included. Alternatively, we could have chosen a license like Apache 2.0, GPL, or any other from opensource.org.
Additionally, we’ll add the LICENSE file at the root of our project:
utilitest
├── src
│ ├── main
│ └── test
├── LICENSE
└── pom.xml
4. Publishing to GitHub Packages
Next, we must configure Maven to build and publish our artifacts to GitHub. To do this, we’ll add a
- “id” – set to “github“
- “name” – the name of the personal account or organization that owns the repository
- “url” – the URL for publishing packages, typically in the format https://maven.pkg.github.com/{owner}/{repository}
Let’s add the
<distributionManagement>
<repository>
<id>github</id>
<name>etrandafir93</name>
<url>https://maven.pkg.github.com/etrandafir93/utilitest</url>
</repository>
</distributionManagement>
After that, we’ll need to generate a personal access token on GitHub, from the developer settings page:
We can configure the token’s scope and expiration date. After that, we’ll update our .m2/settings.xml adding the GitHub username and the newly generated access token in the
<servers>
<server>
<id>github</id>
<username>etrandafir93</username>
<password>{access_token}</password>
</server>
</servers>
Moreover, we’ll add the repository URL within the
<profiles>
<profile>
<id>github</id>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/etrandafir93/utilitest</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
That’s it! With this setup, we can now deploy artifacts to GitHub Packages using the mvn deploy command:
> mvn deploy
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< io.github.etrandafir93:utilitest >------------------
[INFO] Building Utilitest 1.0.0-SNAPOSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[ .... ]
Uploaded to github: https://maven.pkg.github.com/etrandafir93/utilitest/io/github/etrandafir93/utilitest/ 1.0.0-SNAPOSHOT/utilitest-1.0.0-SNAPOSHOT.pom (3.7 kB at 1.1 kB/s)
Uploaded to github: https://maven.pkg.github.com/etrandafir93/utilitest/io/github/etrandafir93/utilitest/ 1.0.0-SNAPOSHOT/utilitest-1.0.0-SNAPOSHOT.jar (4.5 kB at 1.4 kB/s)
Uploaded to github: https://maven.pkg.github.com/etrandafir93/utilitest/io/github/etrandafir93/utilitest/ maven-metadata.xml (368 B at 343 B/s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.463 s
[INFO] Finished at: 2024-09-21T19:44:10+02:00
[INFO] ------------------------------------------------------------------------
As shown in the logs, the package was successfully uploaded to GitHub. Moreover, we should be able to see our uploaded package by checking the GitHub webpage:
5. Installing the Maven Dependency
By default, artifacts uploaded to GitHub Packages inherit the visibility of the parent repository. Since our repository is public, we can easily install the new library as a Maven dependency.
Even though the package is public, GitHub requires clients to authenticate with a personal access token. The process to generate and configure it is the same as before, but this time, the token’s scope can be limited to read-only access.
Additionally, we’ll need to specify the repository URL in our .m2/settings.xml or directly in the pom.xml:
<repository>
<id>github</id>
<name>etrandafir93</name>
<url>https://maven.pkg.github.com/etrandafir93/*</url>
</repository>
Finally, we can add the Maven dependency and start using our new library:
<dependency>
<groupId>io.github.etrandafir93</groupId>
<artifactId>utilitest</artifactId>
<version>1.0.0-SNAPOSHOT</version>
<scope>test</scope>
</dependency>
6. Conclusion
In this article, we learned how to create Maven projects, build them as JARs, and publish them as GitHub packages.
We looked at the project structure, configuring the pom.xml file, and licensing. After that, we configured the GitHub repository and generated an access token for publishing the packages. Finally, we demonstrated how users can install the published artifacts as Maven dependencies.