I'm building NARs on multiple platforms (Mac and Windows). The build is complicated and can't be done via the Maven NAR plugin as such, but I'm building the nar files myself and using the mvn
command-line tool for deployment.
The typical way to do deployment is in one shot, e.g.
mvn deploy:deploy-file \
-Dfile=foobar.jar \
-Dpackaging=jar \
-Dfiles=foobar-x86_64-MacOSX-gcc-shared.nar,foobar-x86_64-Windows-MSVC-shared.nar \
-Dclassifiers=x86_64-MacOSX-gcc-shared,x86_64-Windows-MSVC-shared \
-Dtypes=nar,nar \
-DgroupId=com.example \
-DartifactId=foobar \
-Dversion=1.0.0-SNAPSHOT \
-Durl=$URL \
-DrepositoryId=nexus
However, because the builds are running on different boxes, the publishing step can't happen in one shot. Ideally, I'd like to be able to "append" the attachments to the primary artifact as the builds finish. ie.,
Run this once:
mvn deploy:deploy-file \
-Dfile=foobar.jar \
-Dpackaging=jar \
-DgroupId=com.example \
-DartifactId=foobar \
-Dversion=1.0.0-SNAPSHOT \
-Durl=$URL \
-DrepositoryId=nexus
Then on the Mac build slave:
mvn deploy:deploy-file \
-Dfiles=foobar-x86_64-MacOSX-gcc-shared.nar \
-Dclassifiers=x86_64-MacOSX-gcc-shared \
-Dtypes=nar \
-DgroupId=com.example \
-DartifactId=foobar \
-Dversion=1.0.0-SNAPSHOT \
-Durl=$URL \
-DrepositoryId=nexus
Then on the Windows build slave:
mvn deploy:deploy-file \
-Dfiles=foobar-x86_64-Windows-MSVC-shared.nar \
-Dclassifiers=x86_64-Windows-MSVC-shared \
-Dtypes=nar \
-DgroupId=com.example \
-DartifactId=foobar \
-Dversion=1.0.0-SNAPSHOT \
-Durl=$URL \
-DrepositoryId=nexus
The first command works fine, of course. But the two build slave commands fail with
The parameters 'file' for goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy-file are missing or invalid
because it thinks it needs the primary artifact.
How can I specify that I'm appending to the publication, not creating an entirely new one?
because the builds are running on different boxes, the publishing step can't happen in one shot.
If you are using a CI server like Jenkins to perform your builds, you can publish the artifacts from each slave and then access them via a downstream job on the master node.
This is how we solve the issue in the ImageJ project: we have our Jenkins aggregate all the build artifacts, then deploy them all at once. First, the ImageJ-launcher job—a multi-configuration project—builds the code using the appropriate slaves, archiving the relevant artifacts (which transfers them to the master node's file system). Then the ImageJ-launcher-deploy job copies the archived artifacts from each configuration into a single directory for deployment in one shot.
In case it helps, here is the portion of the ImageJ-launcher-deploy
shell script responsible for copying the NAR artifacts into one place:
masterDir=workspace/label/master/target &&
axesDirs=configurations/axis-label/*/builds/$buildNumber/archive/target &&
: copy the nar/**/* files from all axes to master &&
for path in $axesDirs/nar/*/bin/*/*
do
file=${path#$axesDirs/} &&
if test -f $masterDir/$file
then
# we ignore everything except Linux in the master
case "$path" in
*/master/*Linux*)
;;
*/master/*)
continue
;;
esac
cmp $path $masterDir/$file && continue
printf 'Artifacts disagree:\n%s\n%s\n\n' $path $masterDir/$file
errors=$(($errors+1))
else
target=$masterDir/$file &&
mkdir -p ${target%/*} &&
cp $path $target
fi
done
You may not even need to copy the artifacts if -Dfiles
supports a list of files in different directories—just build up the list of files in the for
loop, and finish with the mvn deploy:deploy-file
invocation you gave above.
See also this answer for further details on the ImageJ-launcher Jenkins configuration.