Prepare one coordinated version

  1. Run dev/scripts/set-version.sh <version>. It updates the only four files that carry a literal version — pom.xml, README.md, CITATION.cff, and CHANGELOG.md — and verifies the result.
  2. Fill in the new changelog section. Documentation pages need no edits — they carry the __ARIADNE_VERSION__ token, which is substituted when the site is built — and the API reference is generated from source on every deploy.
  3. Merge the release pull request after both profile checks and CodeQL pass.

Publish the GitHub Release

Create a tag exactly equal to the Maven project version, without a v prefix, then publish the GitHub Release. The protected workflow signs and uploads each profile as a user-managed Central deployment. It publishes nothing until both deployments reach the validated state.

Before staging, the workflow checks that the tagged commit already has successful Build & Test (Spark 3.5) and Build & Test (Spark 4.1) runs. Because CI runs on every push to main, the merge commit a release tag points at has its own green run. Staging then builds with -DskipTests, since re-running the same suite on the same tree adds roughly 45 minutes and cannot discover anything new. If the tag points at a commit CI never tested, the release stops before anything is uploaded.

A green job is not by itself proof the artifacts were built. CI classifies each change and guards its build steps with if: needs.changes.outputs.source == 'true', so a documentation-only commit reports Build & Test as successful within a few seconds having compiled nothing. The gate therefore also reads the conclusion of the build step inside each job and requires it to have run, so tagging such a commit is refused rather than publishing artifacts no test ever covered.

Re-running a job adds another check run under the same name rather than replacing the old one, so the gate refuses the release if any attempt for a required check has not finished, and otherwise reads the conclusion of the attempt with the newest started_at. Failing closed on an unfinished attempt means the result does not depend on how a pending run populates its timestamps, so a release triggered while CI is re-running is refused rather than being matched against an earlier green attempt.

Skipping tests would otherwise skip the release guards. The governance scripts in dev/scripts are bound to the test phase through exec-maven-plugin, which is configured with <skip>${skipTests}</skip>, so -DskipTests suppresses them along with the Scala suites. The workflow therefore runs dev/scripts/run-governance-checks.sh as an explicit step before staging; that script derives its list from pom.xml, so a newly registered check is picked up automatically. Two executions opt out of the skip with <skip>false</skip> and still run during staging: clean-api-docs-output and test-package-contents, the latter validating the shaded jar's contents. Scalafix and scalastyle are separate plugins and are unaffected by -DskipTests.

Coordinated publication

After both profiles validate, the workflow requests publication for both deployments, waits for both to reach PUBLISHED, confirms both Maven Central coordinates resolve, and downloads each artifact through a clean Maven repository.

Safe defaults and failure handling