------------------------------------------------------------------------ Maven deployment scripts ------------------------------------------------------------------------ The purpose of these scripts is to produce a set of PGP-signed jars and POM files for deployment to Maven Central. http://search.maven.org Because the jogamp projects do not use Maven to manage their own builds (and it would be too much work for very little gain to convert the build system over to Maven), these scripts take an archive of already-released jar files and produce renamed jar files and POM files as output, ready for deployment to the repository. These instructions assume that you know how to set up a PGP agent [0]. In order to get packages onto Maven Central, it's necessary to have an account on one of the large Java "forges". The most-used one seems to be Sonatype. See the repository usage guide [1] for details on getting an account. ------------------------------------------------------------------------ Instructions (deploying a release to Central) ------------------------------------------------------------------------ 1. Obtain the jogamp-all-platforms.7z release for the version of jogamp you wish to deploy to Central. As an example, we'll use 2.3.0. Unpack the 7z file to the 'input' subdirectory, creating it if it doesn't exist: $ mkdir input $ cd input $ wget http://jogamp.org/deployment/v2.3.0/archive/jogamp-all-platforms.7z $ 7z x jogamp-all-platforms.7z 2. Switch back to the old directory: $ cd .. 3. The Central repository requires PGP signatures on all files deployed to the repository. Because we'll be signing a lot of files, we need this to occur in the most automated manner possible. Therefore, we need to tell Maven which PGP key to use and also to tell it to use any running PGP agent we have. To do this, we have to add a profile to $HOME/.m2/settings.xml that sets various properties that tell the PGP plugin what to do. My settings.xml looks something like: jogamp-deployment true jogamp.com (Release signing key) jogamp-deployment That is, I've defined a new profile called "jogamp-deployment" that enables the use of a PGP agent, and uses the string "jogamp.com (Release signing key)" to tell PGP which key to use. You can obviously use the fingerprint of the key here too (or anything else that uniquely identifies it). See: http://www.sonatype.com/books/mvnref-book/reference/profiles.html 4. Now, run make.sh with the desired version number to generate POM files and copy jar files to the correct places: $ ./make.sh 2.3.0 5. The scripts will have created an 'output' directory, containing all the prepared releases. It's now necessary to deploy the releases, one at a time [2]. Assuming that our Sonatype username is 'jogamp' and our password is '********', we now need to edit settings.xml to tell Maven to use them both: jogamp-deployment true jogamp.com (Release signing key) jogamp-deployment sonatype-nexus-staging jogamp ******** That is, we define a new server called 'sonatype-nexus-staging' (this is the name that the scripts use to refer to the remote repository), and state that it wants username 'jogamp' and password '********'. 6. Now we can deploy an individual project to the staging repository: $ ./make-deploy-one.sh gluegen-rt-main 2.3.0 Or deploy all of the projects defined in make-projects.txt: $ ./make-deploy.sh 2.3.0 The scripts will upload all necessary jars, poms, signatures, etc. 7. Now, we need to tell the Sonatype repository that we wish to actually promote the uploaded ("staged") files to a release. This step (unfortunately) doesn't seem to be possible from the command line. Log in to https://oss.sonatype.org using the 'jogamp:********' username and password. Click 'Staging repositories' in the left navigation bar. In the main pane, there should now be a table of repositories. Because we've just uploaded a set of files, there should be one entry (staging repositories are automatically created when files are uploaded). Click the checkbox to the left of the repository name. This will open a 'repository browser' below the main view, showing a tree of files. Inspect the tree of files to be sure that all of the necessary files are present. If all files are there, and assuming that the checkbox is still selected from the previous step, click the 'Close' button above the repository browser - this will 'close' the staging repository (meaning no new files can be added). Then click 'Release' when you absolutely positively want to commit. The release will be made official and the files synced to the Central repository within two hours. If there are still more projects to release, return to step 6. ------------------------------------------------------------------------ Projects ------------------------------------------------------------------------ The way that Maven works demanded a certain structure to the projects produced. The requirements were: 1. The end-user of the jogamp projects released to the repository must not have to do anything beyond adding one or two dependencies to their own projects. Everything must work using only the basic dependency resolution mechanism that Maven supports and must not require anything complex in the way of build scripts. 2. The way that jogamp projects locate their own jar files must work as it always had. The first requirement was reasonably easy to satisfy (and the details of which will be covered shortly). The second requirement was complicated by the fact that Maven unconditionally appends version numbers to jar files (and requires the numbers to be present in order for the dependency resolution to work). After trying various approaches, a small change was made to the jogamp code in order to allow it to cope with version numbers, and the Maven projects were carefully structured to produce jar files with usable names. In other words, we had to essentially write Maven POM files that, when "deployed", produced jar files with the correct names, using a variety of tricks. The other issue was that jogamp implicitly assumed that all of the jar files would be in the same directory, whereas Maven essentially assumes one directory per jar file. We ended up with the following structure: For each part of jogamp that had associated native binaries (contained within jar files), a project was created. Then, using the "classifiers" [3], each of the native jar files were deployed along with the main jar file for each project. Using 'gluegen-rt' as an example: The main jar file as part of jogamp is "gluegen-rt.jar". When "deployed" by Maven, this becomes "gluegen-rt-${VERSION}.jar". Each native jar file associated with gluegen-rt is named "gluegen-rt-natives-${OS}-${ARCH}.jar". We use "classifiers" to get Maven to "deploy" jar files with the correct names: PLATFORMS="linux-amd64 linux-i586 ..." for PLATFORM in ${PLATFORMS} do CLASS="natives-${PLATFORM}" mvn gpg:sign-and-deploy-file \ -Dfile="gluegen-rt-${VERSION}-natives-${PLATFORM}.jar \ -Dclassifier="natives-${PLATFORM}" done Assuming version 2.3.0, this results in: gluegen-rt-2.3.0.jar gluegen-rt-2.3.0-natives-linux-amd64.jar gluegen-rt-2.3.0-natives-linux-i586.jar ... This results in a project with a main jar and a set of native jar files, each with the correct name and version. As the native jar files are implicitly part of the same "project", they're deployed in the same directory as the main jar file, and the jogamp code can locate them without issue. The problem with this approach is that the end-user would have to add an explicit dependency on "gluegen-rt" and each and every one of the associated native jars in their project's POM file! The simplest solution for this problem was to create a second project that contained explicit dependencies on all of the classified jar files of the first. The end-user then simply adds a dependency on this second project instead of the first, and everything is resolved automatically by Maven. This second project also contains an empty "dummy" jar file in order to allow Maven to deploy it to repositories. With that in mind, each part of Maven therefore has an associated "-main" project, meant to be used by end-users. This "-main" project, when added to the dependencies of any project, pulls in all of the real jogamp jars, native or otherwise. ------------------------------------------------------------------------ Test suite ------------------------------------------------------------------------ The scripts now include a basic test suite for checking that the produced packages actually work in Maven. Assuming that the packages have been created with the ./make.sh script above: 1. Generate project files for the tests: $ ./make-tests.sh 2.3.0 2. Deploy packages to a local directory for the unit tests to use: $ ./make-tests-deploy.sh 2.3.0 3. Run the tests. $ ./make-tests-run.sh ------------------------------------------------------------------------ Notes ------------------------------------------------------------------------ We're currently uploading empty jar files for the "sources" and "javadoc" jars required by Central. The rules state that these files are required unconditionally, but may be empty in the case that there aren't sources or javadoc. It'd be nice to provide real sources and javadoc one day. ------------------------------------------------------------------------ Footnotes ------------------------------------------------------------------------ [0] http://www.gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html [1] https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide [2] Sonatype seems to have the restriction that it's only possible to deploy one 'artifactId' at a time - that translates to deploying one jogamp project at a time. [3] https://maven.apache.org/plugins/maven-deploy-plugin/examples/deploying-with-classifiers.html [4] http://www.jcraft.com/jsch/