Hello EO-Masters!
This time a short blog for the developers among you.
What you can expect:
Configure a Maven project to build and deploy it locally
Using GitHub actions to deploy it to a GitHub repository
Introduction
If you are building Maven artifacts and want to deploy them to the public, you are facing the issue that you need to fulfil some requirements if you want to deploy to the Maven Central repository.
For example, among others, you need to sign the files with GPG/PGP and the groupId you use, must follow the reversed domain name system of a domain you own.
These requirements are made up for good reasons and I don't want to question them. But sometimes you simply want to make the artifacts available to others without the overhead.
One option you have is to set up your own server, which is also a hassle. You can also use GitHub packages, but these artifacts are only accessible with GitHub tokens. So only something for internal use and nothing that you want to expect your users to use.
A Simple Maven Repository at GitHub
A simple solution is to use GitHub for the artifacts. This is not a new idea I brought up. You can find several guides which explain this procedure. For example, here on DZone: Using GitHub as a Maven Repository. But the guides I found are not complete. Still manually steps are needed. I extended the approach to have a fully automated deployment.
I first summarise the DZone article here, for details, please read the linked article, and then show how to complete it.
The core idea is to create a separate repository for your artifacts and to configure the deployment step of your actual project to place the artifacts in a local directory.
<distributionManagement>
<repository>
<id>internal</id>
<url>file://${project.build.directory}/mvn-repo</url>
</repository>
</distributionManagement>
After running
mvn deploy
You have the artifacts in the target directory, and you can copy them into the root of the new Maven repository and push it to GitHub.
This repository can now be used by other projects by adding it to the pom.xml file.
<repositories>
<repository>
<id>mvn-repo</id>
<url>https://raw.githubusercontent.com/eomasters-repos/mvn-repo/main/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
Advanced Local Deployment
I've followed this guide and it is good, but in the end, it stops too early.
There are two short comings.
I don't want to copy the artifact manually into the other repository
The deployment should happen automatically
Maven Repository as Deploy Target
The first thing to fix is the target location for the deployment.
We could directly use the local location of the mvn-repo in our pom.xml, but this would affect other users who want to checkout and build our project. This wouldn't be good.
Instead, we introduce a property and use it in the repository definition:
<properties>
<deploy.dir>${project.build.directory}/mvn-repo</deploy.dir></properties>
<distributionManagement>
<repository>
<id>internal</id>
<url>file://${deploy.dir}</url>
</repository>
</distributionManagement>
This doesn't change our actual configuration, but it allows us to overwrite the property within a profile. The best location to define this profile is the settings.xml. This way others are not bothered with this profile.
<profiles>
<profile>
<id>eom-deploy</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<deploy.dir>file://C:/Users/marco/IdeaProjects/mvn-repo</deploy.dir>
</properties>
</profile>
</profiles>
Now this property is only set to the local location of our mvn-repo on our system. In all other cases the artifact is still deployed into the target directory of our project.
Deploying directly into the mvn-repo ensures also that all the metadata.xml file are updated correctly. Which are not when we manually copy the artifacts.
Automatic Deployment on Release
Still, the issue remains, that you must push manually the deployed artifacts. This can be fixed with GitHub Actions.
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that enables you to automate your build, test, and deployment pipeline directly from GitHub.
Create the directories .github/workflows in your project root and add a file named mvn-deploy.yml.
name: Maven Deploy
on:
release:
types: [published]
branches: [ "master" ]
# workflow_dispatch:
Triggers the execution of this script every time a new release is published for the master branch.
The event workflow_dispatch is disabled here. It can be useful for testing the script. When enabled, a button appears on GitHub to trigger manually the execution of the script.
jobs:
Deploy:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout mvn-repo
uses: actions/checkout@v4
with:
repository: eomasters-repos/mvn-repo
path: mvn-repo
token: ${{ secrets.REPO_PUSH_TOKEN }}
Here the actual job is defined. First it is said that it shall run on latest Ubuntu, and the necessary permissions are set.
As first step in this job we check out the mvn-repo. An API-token is needed. See Create a personal access token (classic) and use ist as secret in the GitHub Action. As scope for the token only repo is needed.
- name: Checkout code
uses: actions/checkout@v4
with:
path: this-repo
It is also necessary that we specify the path where it should be checked out to.
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'liberica'
cache: 'maven'
settings-path: ${{ github.workspace }}
Here we setup Java.
- name: Local Artifact Deployment
run: |
cd ${{ github.workspace }}/this-repo
mvn -B deploy -Ddeploy.dir=${{ github.workspace }}/mvn-repo --file pom.xml
This executes the local deployment to the mvn-repo. Instead of using a profile to specify the deploy.dir property, we define it at the command line call.
- name: Push artifacts
run: |
cd ${{ github.workspace }}/mvn-repo
git config --local user.name Github Action
git config user.email ${{ github.repository }}@github.com
git add .
git commit -m "${{ github.repository }} ${{ github.ref }} deployed"
git push
Finally, we push the deployed artifacts. As username "Github Action" is used and as email
the repository name + @github.com.
The commit message is also configured to contain the repository name and the release tag.
And that's it. Quite nice and easy.
I should mention that this is not the intended way of using GitHub repositories. If you want to host a big repository with many artifacts you better think of using something like JitPack, setting up a Nexus server or deploying directly to Maven Central. You should also take into your considerations, by how many other projects your artifacts are used. If there are a lot, you better use one of the full-grown solutions.
But for a small repository this is fine. And that's good enough for me at the moment.
You can see this in action:
Used by
What do you think. Did you know this before? Is this a solution you might use?
Tschüss & Goodbye
Marco
Comments