How to publish Java Application with Maven to Github Packages

Cal P
5 min readFeb 16, 2024
Migrating one CICD to another

A Brief Introduction

I’ve recently undertaken a migration journey, moving from Bitbucket to GitHub. Alongside that, I transitioned our CI/CD tool from Jenkins and CodePipeline to GitHub Actions. This experience was both interesting and educational, as it came with its share of unexpected gotchas. I’d like to share my insights with you, so you can benefit from my experience and save valuable time in your own migration endeavours.

Let’s Get Started!

Imagine we have a Java library named auth-commons that has a collection of valuable utilities and functions to be leveraged by numerous Spring Boot applications. In this guide, I will walk you through the process of publishing auth-commonsto GitHub Packages and demonstrate how to include it as a dependency in a fresh Spring Boot project.

Publish auth-commons to Github Packages

  1. Modify pom.xml

The <distributionManagement> section in the Maven pom.xml file specifies where project artifacts should be deployed (published).

<distributionManagement>
<repository>
<id>github</id>
<name>Github</name>
<url>https://maven.pkg.github.com/cal0610/medium-auth-commons</url>
</repository>
<snapshotRepository>
<id>github</id>
<url>https://maven.pkg.github.com/cal0610/medium-auth-commons</url>
</snapshotRepository>
</distributionManagement>

2. Create .github/workflows/maven-publish.xml

name: Publish Package

on:
push:
branches:
- '*'

jobs:
build:
runs-on: ubuntu-latest

permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'zulu'

- name: Publish package
run: ./mvnw deploy
env:
GITHUB_TOKEN: ${{ github.token }}
  • name: Publish Package: A title or label for this GitHub Actions workflow.
  • on:: Specifies the event that triggers this workflow, in this case, it's triggered when there's a push event type, indicating a code push event to the repository.
  • branches:: Specifies the branches for which this workflow should be triggered. This wildcard (*) means the workflow will be triggered for pushes to all branches.
  • jobs:: Defines a list of jobs that need to be executed as part of this workflow.
  • build:: A job named "build."
  • runs-on: ubuntu-latest: Specifies that this job should run on the latest version of Ubuntu.
  • permissions:: Specifies permissions for the job.
  • contents: read: Grants read access to repository contents.packages: write: Grants write access to packages in the GitHub repository.
  • steps:: A list of steps to be executed within the job.
  • uses: actions/checkout@v4: This step checks out the source code of the repository.
  • name: Set up JDK 17: Sets up Java Development Kit (JDK) version 17 using the 'zulu' distribution.
  • name: Publish package: This step is named "Publish package" and is used to deploy (publish) a package.
  • run: ./mvnw deploy: Deploys the package.
  • env:: Specifies environment variables.
  • GITHUB_TOKEN: ${{ github.token }}: Sets the GITHUB_TOKEN environment variable to the GitHub token associated with the workflow. This token is used to authenticate and authorize actions performed in the workflow, such as publishing the package to the repository. The GITHUB_TOKEN is generated automatically for each workflow.

Install auth-commons from Github Packages

Create a fresh Spring Boot project using start.spring.io and include auth-commons as one of its dependencies.

  1. Update the pom.xml file to include auth-commons as a dependency. Optionally, you can go to the repository's "Packages" section and copy the dependency XML.
<dependency>
<groupId>com.medium</groupId>
<artifactId>medium-auth-commons</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
Or copy the dependency

2. Create .github/workflows/build.yml in the root directory

name: Maven Package

on:
push:
branches:
- '*'

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'zulu'

- name: Replace Maven Credentials
run: |
sed -i 's/USERNAME/${{ secrets.USERNAME }}/g' .github/settings.xml
sed -i 's/PASSWORD/${{ secrets.PASSWORD }}/g' .github/settings.xml

- name: Install
run: ./mvnw clean install -s .github/settings.xml
env:
GITHUB_TOKEN: ${{ secrets.github.token }}

This workflow closely resembles the previous one, so I’ll skip a detailed explanation. The main distinction is the inclusion of a settings.xml file and the usage of the sed command to substitute the placeholders for USERNAME and PASSWORD with actual values.

Note that this article won't cover the creation of workflows or composite actions to promote code reusability, as it's beyond the scope of the current topic.

3. Create settings.xml in .github directory

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<activeProfiles>
<activeProfile>github</activeProfile>
</activeProfiles>
<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/cal0610/*</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
</profile>
</profiles>
<servers>
<server>
<id>github</id>
<username>USERNAME</username>
<password>PASSWORD</password>
</server>
</servers>
</settings>
  • Ensure that the repository URL adheres to the format: https://maven.pkg.github.com/OWNER/REPO. You have the flexibility to use a wildcard (*) in place of the OWNER, allowing Maven to install dependencies from the repository's owner dynamically. Inside the <server> tag, the username and password fields should be populated with the corresponding values from your personal access token for authentication purposes.

4. In the workflow, I’ve made reference to USERNAME and PASSWORD as secrets to ensure secure handling of credentials without hardcoding them directly into the workflow file. To set up these secrets, please follow the instructions outlined in the official GitHub documentation here.

Repository secrets

4. You’re now ready to push the code up and github actions will execute our build.yml

Successful build
Inspecting the logs

CONCLUSION

Congratulations! We’ve succesfully published a Java library to Github Packages. Further, we’ve installed that library in another Spring Boot application.

FINAL NOTE

In order to build the demo project locally, you will need to modify your ~./m2/settings.xml to include your username and password for the personal access token.

SOURCES

--

--