gpu4j

Publishing gpu4j-core to Maven Central

This guide walks maintainers through the one-time setup and the release process for io.github.craton-co:gpu4j-core. The repository is already configured for Sonatype’s Central Publisher Portal (not the legacy OSSRH JIRA workflow).

ItemValue
Coordinatesio.github.craton-co:gpu4j-core
Release profile-Prelease (sources, Javadoc, GPG, Central upload)
CI workflow.github/workflows/release.yml
Portal publish modeManual (autoPublish is false in pom.xml)

Official references:


Readiness status (checked 2026-08-28)

What is done, and what actually blocks a first publish.

CheckStatus
Required POM metadata (name, description, url, licenses, developers, scm)Present
-sources.jar buildsYes (34 entries)
-javadoc.jar buildsYes (121 entries); failOnError is now true, so a broken Javadoc fails the release instead of shipping a partial jar
Version is a release version (no -SNAPSHOT)Yes: 0.4.0
<scm><tag> matches the tag to pushYes: v0.4.0
Reproducible-build timestampSet; bump it every release (see checklist)
Anything published under io.github.craton-coNo. https://repo1.maven.org/maven2/io/github/craton-co/ returns 404 — the namespace has never carried an artifact
Namespace verified in the PortalUnknown (blocking). Requires signing in to the Portal as the owning org; cannot be checked from a build
GPG signing key presentNo (blocking). No secret key on the release machine; gpg --list-secret-keys is empty
Portal token / GitHub secrets configuredUnknown (blocking). CENTRAL_USERNAME, CENTRAL_PASSWORD, MAVEN_GPG_PRIVATE_KEY, MAVEN_GPG_PASSPHRASE

So: the build is ready; the account is not. Everything mechanical passes (mvn -Prelease -Dgpg.skip=true clean verify produces all three jars). The three outstanding items are all credentials and namespace ownership, covered by "One-time setup" below.

Two consequences worth knowing while that is outstanding:

  • The Maven Central badge in the README renders as "not found", and the install coordinates do not resolve. The README says so.
  • CHANGELOG.md records a 0.2.0 release dated 2026-05-19 with a release-tag link, but no 0.2.0 artifact exists on Central. If that tag was only ever a GitHub release, say so there; the current wording reads as though Central publication happened.

A note on build.qualifier

Both POMs accept -Dbuild.qualifier=, which is appended to the artifact file name. It is empty by default and the release workflow never sets it. Do not set it for a release: the published coordinates come from the POM either way, but the local file names would stop matching what the release workflow uploads to the GitHub Release.


What is already in this repo

The default pom.xml includes the metadata Maven Central requires: name, description, url, licenses, developers, and scm.

The release Maven profile adds:

  • maven-source-plugin-sources.jar
  • maven-javadoc-plugin-javadoc.jar
  • maven-gpg-plugin.asc signatures
  • central-publishing-maven-plugin — bundles artifacts and uploads to the Portal (publishingServerId = central)

Pushing a Git tag v* triggers GitHub Actions, which runs:

mvn -B -ntp -Prelease deploy

One-time setup

1. Create a Central Publisher account

  1. Sign up at central.sonatype.com.
  2. Sign in with GitHub if the org uses it (GitHub login can auto-provision io.github.<username> — see namespace docs).

2. Verify your Maven namespace (groupId)

The project publishes under io.github.craton-co. You must verify that namespace before the first deploy.

  1. Sign in to the Portal with the craton-co GitHub account (or org) that owns github.com/craton-co.
  2. Profile menu → View Namespaces. If io.github.craton-co is not listed, click Add Namespace and enter io.github.craton-co.
  3. Complete verification:
    • GitHub sign-in: Sonatype often auto-provisions io.github.<org-or-user> for the account used at registration — check that the namespace shows Verified.
    • Otherwise: create a temporary public repository named with the Portal verification key (see verify via code hosting).
  4. Confirm the namespace is Verified before running mvn deploy.

Coordinates cannot be renamed after a version is published to Central.

3. Create and register a GPG signing key

Maven Central requires every deployed file to have a .asc signature from an OpenPGP key published on a public keyserver.

# Create a key (use a long-lived maintainer identity)
gpg --full-generate-key

# List key ids
gpg --list-secret-keys --keyid-format=long

# Publish the public key (use the id from the line "sec")
gpg --keyserver keys.openpgp.org --send-keys <KEY_ID>

Upload the same public key to keys.openpgp.org if the keyserver step fails.

For CI: export the private key (ASCII-armored) into a GitHub secret:

gpg --armor --export-secret-keys <KEY_ID>

Store the output in MAVEN_GPG_PRIVATE_KEY. Store the key passphrase in MAVEN_GPG_PASSPHRASE.

4. Generate a Portal user token

Tokens replace username/password for the new Portal API.

  1. Open central.sonatype.com/usertoken.
  2. Generate User Token — copy username and password immediately (they are shown only once).

5. Local ~/.m2/settings.xml (for manual publishes)

Add a server entry whose id matches publishingServerId in pom.xml (central):

<settings>
  <servers>
    <server>
      <id>central</id>
      <username>YOUR_TOKEN_USERNAME</username>
      <password>YOUR_TOKEN_PASSWORD</password>
    </server>
  </servers>
  <profiles>
    <profile>
      <id>gpg</id>
      <properties>
        <gpg.keyname>YOUR_KEY_ID</gpg.keyname>
        <gpg.passphrase>YOUR_KEY_PASSPHRASE</gpg.passphrase>
      </properties>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>gpg</activeProfile>
  </activeProfiles>
</settings>

Do not commit this file. Prefer environment variables in CI (see below).

6. Configure GitHub repository secrets

In Settings → Secrets and variables → Actions for craton-co/gpu4j:

SecretPurpose
CENTRAL_USERNAMEPortal user token username
CENTRAL_PASSWORDPortal user token password
MAVEN_GPG_PRIVATE_KEYArmored private GPG key
MAVEN_GPG_PASSPHRASEGPG key passphrase

actions/setup-java maps CENTRAL_* to MAVEN_USERNAME / MAVEN_PASSWORD and installs the GPG key for the deploy step (see release.yml).


Pre-release checklist

Before tagging:

  1. Version — Set <version> in pom.xml to the release version (no -SNAPSHOT for releases). Central versions are immutable, so a version can only be published once.

  2. scm tag — Point <scm><tag> at the Git tag you will push (e.g. v0.4.0), not HEAD:

    <scm>
      ...
      <tag>v0.4.0</tag>
    </scm>
    
  3. Reproducible-build timestamp — Bump project.build.outputTimestamp in pom.xml to the release date. It is the SOURCE_DATE_EPOCH stamped into every archive entry; leaving it stale makes successive releases claim the same build time.

  4. Changelog — Stamp the ## [Unreleased] heading in CHANGELOG.md as ## [X.Y.Z] - YYYY-MM-DD, add the compare/tag links at the bottom, and open a fresh ## [Unreleased]. Diff the public surface against it while you are there: every documentation defect found in the 2026-08-28 audit had a matching CHANGELOG omission.

  5. Tests — Both projects, from the repo root:

    mvn -B verify
    mvn -B -f gpu4j-sidecar/pom.xml verify
    
  6. Dry-run locally — Build release artifacts without uploading:

    mvn -B -Prelease clean verify
    

    Inspect target/*.jar, *-sources.jar, *-javadoc.jar, and *.asc. To check everything except signing on a machine with no key, add -Dgpg.skip=true.

  7. Merge dev to maindev is the integration branch; releases are tagged from main. Tag only the commit you intend to release.


Publish a release

  1. Commit version and scm tag updates on main (merged from dev).

  2. Create and push an annotated tag:

    git tag -a v0.4.0 -m "Release 0.4.0"
    git push origin v0.4.0
    
  3. Watch the Release to Maven Central workflow in GitHub Actions.

  4. When the job succeeds, open central.sonatype.com/publishing/deployments.

  5. Find the new deployment (validation usually finishes in the build log). Because autoPublish is false, click Publish manually to push the version to Maven Central.

After publishing, artifacts appear on search.maven.org within minutes (sync can take up to ~30 minutes).

Consumers then depend on:

<dependency>
  <groupId>io.github.craton-co</groupId>
  <artifactId>gpu4j-core</artifactId>
  <version>0.4.0</version>
</dependency>

Manual deploy from a workstation

Use the same credentials as CI:

export MAVEN_USERNAME="..."   # token username
export MAVEN_PASSWORD="..."   # token password
export MAVEN_GPG_PASSPHRASE="..."

mvn -B -ntp -Prelease clean deploy

Then complete Publish in the Portal as above.

Optional: fully automatic Portal publish

To skip the manual Portal click (typical for trusted CI only), set in the release profile:

<autoPublish>true</autoPublish>

You can also set <waitUntil>published</waitUntil> so the build fails if Central does not finish syncing. See plugin configuration.


Post-release

  1. Confirm the version on search.maven.org.
  2. Update README.md install examples if the version changed.
  3. Create a GitHub Release for the tag (optional; not required for Central).
  4. Bump pom.xml to the next development version if you use a separate snapshot workflow.

Troubleshooting

SymptomLikely cause
401 / authentication failedWrong or expired Portal token; server-id in workflow must be central
Namespace not verifiedio.github.craton-co not verified; sign in with the owning GitHub org or complete hosting-service verification
Missing signaturesGPG key not loaded; MAVEN_GPG_* secrets missing or wrong passphrase
Missing sources/JavadocForgot -Prelease profile
Deployment validated but not on CentralautoPublish is false — click Publish in the Portal
groupId already exists under OSSRHNamespace tied to legacy OSSRH; contact central-support@sonatype.com to migrate
Version already existsMaven Central versions are immutable; ship 0.3.1 (or next) instead

Useful commands

# Verify local GPG signing works
gpg --list-secret-keys

# Re-run only packaging/signing (no deploy)
mvn -B -Prelease clean verify

Security notes

  • Rotate Portal tokens periodically; update GitHub secrets when you do.
  • Limit who can push tags and edit Actions secrets (tags trigger production publishes).
  • Never commit settings.xml with tokens, or private GPG material, to the repository.