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).
| Item | Value |
|---|---|
| Coordinates | io.github.craton-co:gpu4j-core |
| Release profile | -Prelease (sources, Javadoc, GPG, Central upload) |
| CI workflow | .github/workflows/release.yml |
| Portal publish mode | Manual (autoPublish is false in pom.xml) |
Official references:
- Central Portal publishing guide
- Maven plugin (how
mvn deployworks) - Requirements (POM, GPG, sources, Javadoc)
Readiness status (checked 2026-08-28)
What is done, and what actually blocks a first publish.
| Check | Status |
|---|---|
Required POM metadata (name, description, url, licenses, developers, scm) | Present |
-sources.jar builds | Yes (34 entries) |
-javadoc.jar builds | Yes (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 push | Yes: v0.4.0 |
| Reproducible-build timestamp | Set; bump it every release (see checklist) |
Anything published under io.github.craton-co | No. https://repo1.maven.org/maven2/io/github/craton-co/ returns 404 — the namespace has never carried an artifact |
| Namespace verified in the Portal | Unknown (blocking). Requires signing in to the Portal as the owning org; cannot be checked from a build |
| GPG signing key present | No (blocking). No secret key on the release machine; gpg --list-secret-keys is empty |
| Portal token / GitHub secrets configured | Unknown (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.mdrecords a0.2.0release dated 2026-05-19 with a release-tag link, but no0.2.0artifact 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.jarmaven-javadoc-plugin—-javadoc.jarmaven-gpg-plugin—.ascsignaturescentral-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
- Sign up at central.sonatype.com.
- 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.
- Sign in to the Portal with the craton-co GitHub account (or org) that owns github.com/craton-co.
- Profile menu → View Namespaces. If
io.github.craton-cois not listed, click Add Namespace and enterio.github.craton-co. - 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).
- GitHub sign-in: Sonatype often auto-provisions
- 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.
- Open central.sonatype.com/usertoken.
- 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:
| Secret | Purpose |
|---|---|
CENTRAL_USERNAME | Portal user token username |
CENTRAL_PASSWORD | Portal user token password |
MAVEN_GPG_PRIVATE_KEY | Armored private GPG key |
MAVEN_GPG_PASSPHRASE | GPG 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:
-
Version — Set
<version>inpom.xmlto the release version (no-SNAPSHOTfor releases). Central versions are immutable, so a version can only be published once. -
scmtag — Point<scm><tag>at the Git tag you will push (e.g.v0.4.0), notHEAD:<scm> ... <tag>v0.4.0</tag> </scm> -
Reproducible-build timestamp — Bump
project.build.outputTimestampinpom.xmlto the release date. It is theSOURCE_DATE_EPOCHstamped into every archive entry; leaving it stale makes successive releases claim the same build time. -
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. -
Tests — Both projects, from the repo root:
mvn -B verify mvn -B -f gpu4j-sidecar/pom.xml verify -
Dry-run locally — Build release artifacts without uploading:
mvn -B -Prelease clean verifyInspect
target/*.jar,*-sources.jar,*-javadoc.jar, and*.asc. To check everything except signing on a machine with no key, add-Dgpg.skip=true. -
Merge
devtomain—devis the integration branch; releases are tagged frommain. Tag only the commit you intend to release.
Publish a release
Automated (recommended)
-
Commit version and
scmtag updates onmain(merged fromdev). -
Create and push an annotated tag:
git tag -a v0.4.0 -m "Release 0.4.0" git push origin v0.4.0 -
Watch the Release to Maven Central workflow in GitHub Actions.
-
When the job succeeds, open central.sonatype.com/publishing/deployments.
-
Find the new deployment (validation usually finishes in the build log). Because
autoPublishisfalse, 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
- Confirm the version on search.maven.org.
- Update README.md install examples if the version changed.
- Create a GitHub Release for the tag (optional; not required for Central).
- Bump
pom.xmlto the next development version if you use a separate snapshot workflow.
Troubleshooting
| Symptom | Likely cause |
|---|---|
401 / authentication failed | Wrong or expired Portal token; server-id in workflow must be central |
| Namespace not verified | io.github.craton-co not verified; sign in with the owning GitHub org or complete hosting-service verification |
| Missing signatures | GPG key not loaded; MAVEN_GPG_* secrets missing or wrong passphrase |
| Missing sources/Javadoc | Forgot -Prelease profile |
| Deployment validated but not on Central | autoPublish is false — click Publish in the Portal |
groupId already exists under OSSRH | Namespace tied to legacy OSSRH; contact central-support@sonatype.com to migrate |
| Version already exists | Maven 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.xmlwith tokens, or private GPG material, to the repository.