Skip to content

Instantly share code, notes, and snippets.

@karlvr
Last active October 25, 2023 12:20
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save karlvr/5a4321f9ddf193ceb122849f8fb806d1 to your computer and use it in GitHub Desktop.
Save karlvr/5a4321f9ddf193ceb122849f8fb806d1 to your computer and use it in GitHub Desktop.
A small bash script to migrate Maven packages from Sonatype Nexus to GitHub Packages

Migrate Maven packages from Sonatype Nexus to GitHub Packages

This gist describes the process we've used to migrate our Maven package repository from Sonatype Nexus to GitHub Packages. The same process could be used for migrating any Maven package repo that is in the standard layout.

We created a special repository on GitHub to hold all of our Maven packages. You might decide to migrate packages to different repositories, in which case invoke the script multiple times.

The script uses find to look for all of the folders containing poms and upload them. You specify the folder to start from, so you upload part of your repository.

A hidden .migrated-github-packages file is created in each folder that's processed so you can interrupt and repeat the process.

  1. Create the maven-releases GitHub repository as a private (or public) repository.
  2. Create a personal access token for your GitHub account with permissions: repo and write:packages.
  3. Create or edit your ~/.m2/settings.xml to include a <repository> and <server> element as in the example file, substituting your username and personal access token.
  4. Run the script migrate-nexus-to-github-packages.sh /srv/nexus/storage/releases <owner> maven-releases github

It is possible to paralellise the script, as GitHub is pretty slow at accepting each package (~30s / package). I recommend parallelising by artifact, as Maven isn't thread safe in the way it writes to its files. I achieved that quite simply by spawning individual scripts, one for each artifact, and running them in the background. Beware that Maven actually uses a bit of memory and CPU, so doing too many artifacts in parallel might overload your system.

#!/bin/bash -eu
basedir="${1:-}" # The directory to start looking for poms from
owner="${2:-}" # The owner username on GitHub
repository="${3:-}" # The repository name on GitHub
serverid="${4:-}" # Matches to <server> in ~/.m2/settings.xml
if [ -z "$basedir" -o -z "$owner" -o -z "$repository" -o -z "$serverid" ]; then
echo "usage: $0 <basedir> <owner> <repository> <serverid>" >&2
exit 1
fi
trap ctrl_c INT
ctrl_c() {
echo "Interrupted" >&2
exit 1
}
# Find poms in artifact and version order
for pom in $(find "$basedir" \( -name '.nexus' \) -prune -false -o -name '*.pom' | sort --version-sort) ; do
dir=$(dirname $pom)
dir=$(cd "$dir" && pwd)
if [ -f "$dir/.migrated-github-packages" ]; then
continue
fi
version=$(basename $dir)
artifact=$(basename $(dirname $dir))
jar="$dir/$artifact-$version.jar"
sources="$dir/$artifact-$version-sources.jar"
javadoc="$dir/$artifact-$version-javadoc.jar"
pomfile="$dir/$artifact-$version.pom"
command="mvn -q org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M1:deploy-file \
-DrepositoryId=$serverid \
-Durl=https://maven.pkg.github.com/$owner/$repository"
if [ -f "$jar" ]; then
command="$command -Dfile=\"$jar\""
elif [ -f "$pomfile" ]; then
command="$command -Dfile=\"$pomfile\""
fi
if [ -f "$sources" ]; then
command="$command -Dsources=\"$sources\""
fi
if [ -f "$javadoc" ]; then
command="$command -Djavadoc=\"$javadoc\""
fi
if [ -f "$pomfile" ]; then
command="$command -DpomFile=\"$pomfile\""
fi
echo "$pomfile"
eval $command
touch "$dir/.migrated-github-packages"
done
<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>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
<repository>
<id>github-REPOSITORY</id>
<name>GitHub OWNER Apache Maven Packages</name>
<url>https://maven.pkg.github.com/OWNER/REPOSITORY</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
</profile>
</profiles>
<servers>
<server>
<id>github</id>
<username>USERNAME</username>
<password>PERSONAL_ACCESS_TOKEN</password>
</server>
</servers>
</settings>
@andyfeller
Copy link

@karlvr : ✨ for writing this up!

Out of curiosity, did you look into any other tools such as https://github.com/microsoft/mvnfeed-cli for migration purposes?

@karlvr
Copy link
Author

karlvr commented Mar 26, 2023

@andyfeller I didn't see that tool, no. In the end I quite enjoyed knowing exactly what was happening with my precious jars and poms :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment