Wiki

Clone wiki

Okapi / Publishing to Maven Central

Since you already publish the artifacts you probably use Sonatype, and you already have all the requirements taken care of. https://central.sonatype.org/publish/publish-guide/

But musically all requirements map directly to some plugins in our maven suportpom/pom.xml https://central.sonatype.org/publish/requirements/#create-a-ticket-with-sonatype

They are activated by profils, to not force everybody to generate documentation every time (for example), which more than doubles the build time.

Everything is "captured" in one maven command: mvn deploy ${MAVEN_CLI_OPTS} -DskipTests \ --activate-profiles sonatype_deploy,with_javadoc,with_sources,gpg_sign (Line 104 of ci/gitlab/gitlab-ci.yml) That task also invokes gpg-import.sh (see below)

The profiles are in the superpom/pom.xml, at the end (search for <profile) Most just activate standard maven plugins

But for PGP we use org.kohsuke:pgp-maven-plugin Which uses a Java implementation of PGP. The original maven plugin invokes the native one. And that was always a hit and miss. And you need it installed, and in the path, and that is OS dependent.

For the deployment proper I went with org.sonatype.plugins:nexus-staging-maven-plugin Which has more "knobs" than the standard maven one. For example I set autoReleaseAfterClose to false. So that the artifacts go to Sonatype, but I need to go there and explicitly say "publish to central" I don't know... Just another level of safety. Only needed when releasing.

The plugines are configured in <pluginManagement> Just take the plugin name from profile and search for it.

Back to CI (https://bitbucket.org/okapiframework/okapi/src/dev/ci/gitlab/)

The other "clunkiness" when doing it in CI is how to hide the secrets (pgp key, sonatype password)

For GPG, we store the private key file encrypted, in ci/gitlab/code-signing-key.asc.enc Then we decode it with ci/gitlab/scripts/gpg-import.sh

The rest of the "glue" is in ci/gitlab/.m2/settings.xml That's where gpg.passphrase and gpg.secretkey are initialized (used in the plugin)

The MAVEN_REPO_USER, MAVEN_REPO_PASS, GPG_PASSPHRASE (in settings.xml) and OPENSSL_ENC_KEY & OPENSSL_ENC_IV used to decrypt the pgp key are "secrets" in GitLab

They are stored in the Okapi Framework group, not per project, so that we can share them across projects. Go to https://gitlab.com/okapiframework, Settings -- CI -- Variables -- Expand GitLab will "inject" them in the running docker instances, but they are not visible anywhere else (scripts, dockerfiles, etc)

Finally, we do the deploy task during the nightly builds You can see it in the GitLab CI Pipelines: https://gitlab.com/okapiframework/okapi/-/pipelines The deployment step results in "snapshot" or "release" based on conditions in gitlab-ci.yml (basically branch name + tag)

Bot some of that is part of the refactoring that I want to do for the build system and CI For example we deploy for every CL, which is a waste, and time consuming. But only run integration tests in nightly, and only AFTER deploy, which is wrong. We want them before deploy. And for every CL, now, that hey are faster.

The artifacts got to Sonatype, and the presence of -SNAPSHOT in the version decides in what Sonatype repo it goes.

The very last step is for release. Someone needs to go to Sonatype and say "yes, forward this to Maven Central" That's documented in deployment/instructions.html, the "Publish the maven artifacts to Maven Central" section

===

Setting up this whole thing is very clunky. But once it is set up iit s smooth: artifacts are automatically pushed to Sonatype in certain conditions (branch, nightly, release tag), go to the right repo based on version, and to release you just login to Sonatype and confirm

To help con figuring things, I would recommend: Set autoReleaseAfterClose to false, to make sure nothing ends up in Maven Central by mistake Play with a small "dummy" project to make everything fast when working on this. (replace the real sources with dummy "hello world" kind of stuff) So you don't wait for 10 minutes for every small change (CI is slow, and deployment is slow).

What I also did was use a GitLab docker image + a Nexus (Sonatype) docker image, did everything locally, and only changed server URLs at the end. That takes time to setup, but you can iterate a lot faster.

Updated