Skip to content

ci: add Maven Central publish workflow + maintainer runbook (D4)#98

Merged
DemchaAV merged 1 commit into
developfrom
ci/publish-workflow
May 31, 2026
Merged

ci: add Maven Central publish workflow + maintainer runbook (D4)#98
DemchaAV merged 1 commit into
developfrom
ci/publish-workflow

Conversation

@DemchaAV
Copy link
Copy Markdown
Owner

Summary

Wires up Track D4 — the fourth and final step of the Maven Central pipeline. Fires on the same v* tag push that triggers release.yml.

Stacked on D3 (#97). After D3 merges, this PR fast-forwards onto develop.

The workflow

.github/workflows/publish.yml:

  1. Re-runs mvnw verify at the tagged commit. Defence-in-depth against a tag pushed from a broken branch.
  2. actions/setup-java@v5 configures GPG + Central credentials. Imports MAVEN_GPG_PRIVATE_KEY into the runner keyring; writes a <server id="central"> credentials block from CENTRAL_USERNAME + CENTRAL_TOKEN into ~/.m2/settings.xml.
  3. Runs ./mvnw -P release -Dgpg.skip=false deploy. Release profile (D1) attaches sources + javadoc jars; maven-gpg-plugin (D2) signs them; central-publishing-maven-plugin (D3) uploads to Central and blocks until validation completes.
Surface Behaviour
Hyphenated tag (v1.7.0-rc.1, -alpha, -beta, -snapshot) Job's if: guard skips it. Those ship to JitPack + GitHub Release pre-release only; Central rejects them.
workflow_dispatch with tag input Maintainer can re-publish an existing tag without re-cutting it if Central had a transient validator hiccup.
Tag push on plain semver (v1.6.6) Workflow runs end-to-end. autoPublish=false in D3's plugin config means the artefact lands in Central's validation queue; maintainer releases it on central.sonatype.com.

Documentation — docs/contributing/release-process.md

Two updates:

  • New § 2.C "One-time Maven Central setup (maintainer)" — six-step runbook for GPG key generation, keyserver upload, Sonatype account + namespace verification, Central user-token generation, the four GitHub secrets, and the release-candidate dry-run strategy.
  • § 2.B post-release checklist gains a new step 9 for the Central publish alongside the existing JitPack step.

Workflow is dormant until secrets land

Four GitHub repo secrets the maintainer must wire (one-time):

Secret What it carries
MAVEN_GPG_PRIVATE_KEY Full ASCII-armored private key
MAVEN_GPG_PASSPHRASE Passphrase for the key above
CENTRAL_USERNAME Central user-token username half
CENTRAL_TOKEN Central user-token password half

The full procedure (key generation, namespace verification, secret wiring) is in the new § 2.C of the release-process doc. Until those secrets are in place, the workflow will fail at the Set up Temurin JDK 17 with Central credentials step with a clear "no key provided" error — no half-published state, no Central pollution.

D-track final state

Step State
D1 — sources / javadoc jars + SCM ✅ shipped
D2 — GPG signing ✅ shipped
D3 — central-publishing plugin 🟡 #97 (this PR's parent)
D4 — publish workflow 🟢 this PR

After this merges, the v1.6.6 cut is one human step away from publishing to Maven Central: wire the four secrets, cut the tag, watch publish.yml validate the upload, click the release-button on central.sonatype.com. autoPublish=false keeps the human in the loop for the first publish; flips to true is a one-line follow-up once we're confident.

Test plan

  • publish.yml validates as YAML
  • release-process.md guards green locally
  • Workflow is not visible / not run until secrets exist
  • CI on PR (Guards / JDK 17/21/25 / Examples Smoke / no-poi / japicmp)
  • After D3 merge — rebase onto develop and re-run CI
  • Reviewer skim — publish.yml (~85 LOC) is the load-bearing piece; the docs are descriptive
  • (Out of band) maintainer wires the four secrets; first cut after that publishes to Central

Wires up Track D4 - the fourth and final step of the Maven Central pipeline. Fires on the same v* tag push that triggers the existing release.yml workflow.

What the workflow does:

1. Re-runs mvnw verify against the tagged commit (defence-in-depth against a tag pushed from a broken branch).

2. actions/setup-java@v5 imports MAVEN_GPG_PRIVATE_KEY into the runner keyring and writes <server id='central'> credentials block from CENTRAL_USERNAME + CENTRAL_TOKEN secrets into ~/.m2/settings.xml.

3. Runs ./mvnw -P release -Dgpg.skip=false deploy. Release profile (D1) attaches sources + javadoc jars; maven-gpg-plugin (D2) signs them; central-publishing-maven-plugin (D3) uploads to Central and blocks until validation completes.

Hyphenated tags (-rc, -alpha, -beta, -snapshot) are explicitly skipped via the job's if: guard. Those ship only to JitPack + the GitHub Release pre-release surface; Central rejects them anyway.

workflow_dispatch input lets the maintainer re-publish an existing tag without re-cutting it if Central had a transient validator hiccup.

Workflow is dormant until four GitHub repo secrets are wired by the maintainer: MAVEN_GPG_PRIVATE_KEY, MAVEN_GPG_PASSPHRASE, CENTRAL_USERNAME, CENTRAL_TOKEN. docs/contributing/release-process.md section 2.C walks through the one-time setup end-to-end.

Stacked on D3 (#97). After D3 merges, this rebases fast-forward.
@DemchaAV DemchaAV force-pushed the ci/publish-workflow branch from a6f3425 to 2c95119 Compare May 31, 2026 16:43
@DemchaAV DemchaAV merged commit 3c42192 into develop May 31, 2026
11 checks passed
@DemchaAV DemchaAV deleted the ci/publish-workflow branch May 31, 2026 16:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant