Publishing Reference ​
Public reactor verification ​
Publish the framework reactor with ./mvnw -f framework/pom.xml. Before a Central release, deploy with -Ppublication-verification to a temporary file repository and run scripts/verify-framework-publication.mjs. The verifier is packaging-aware: public pom artifacts require their POM and signature, while public jar artifacts also require main, sources, Javadoc, and signature files.
Reference Appendix
This is the long-form Maven Central and release reference. Start with Publishing, Framework Release Process, or Docs Snapshot Process for the canonical path.
This document explains how to publish immutable The Pipeline Framework releases to Maven Central, refresh the current development snapshot, and manage the project's versioning and release process properly.
TL;DR: Guarded Release Process ​
The release process uses the Maven Release Plugin for the root reactor, then GitHub Actions publishes framework artifacts from the release tag. Keep Maven's push step disabled so the generated release and next-development commits can be inspected before they reach main.
Prepare locally without pushing:
bash./mvnw release:prepare \ -DpushChanges=false \ -DreleaseVersion=26.5.2 \ -DdevelopmentVersion=26.6.1-SNAPSHOT \ -Dtag=v26.5.2 \ -Darguments="-DskipTests"Synchronize release-coupled standalone POMs: confirm alternate topology and standalone reference POMs moved to the next snapshot, including
examples/csv-payments/pom.pipeline-runtime.xml,examples/csv-payments/pom.monolith.xml,examples/checkout/pom.xml, andai-sdk/pom.xml.Run the release validation gate: at minimum run version-drift checks, framework verification, CSV topology checks, and docs build before pushing.
Push only after validation: push the prepared commits to
main, then push the immutablevX.Y.Ztag to trigger publishing.Verify on Maven Central: check artifacts at https://central.sonatype.com/.
The GitHub Actions workflow automatically:
- Runs the workflows selected by the pushed paths on
main - Signs all artifacts with GPG
- Deploys to Sonatype Central
- Creates a GitHub release with notes
Sonatype Central can take a long time to move an automatic deployment from validated to published. The central-publishing profile therefore sets the Central Publishing plugin's waitMaxTime to 7200 seconds, and the publish workflow allows 150 minutes for the job. If the workflow still times out but Central later publishes the deployment, verify Maven Central metadata and create the skipped GitHub release from the existing immutable tag.
Table of Contents ​
- Overview
- Version Management
- Maven Central Publishing Setup
- settings.xml Configuration
- GitHub Actions Workflow
- Nightly Snapshot Publishing
- Safe Release Process
- Troubleshooting
Overview ​
The Pipeline Framework is published to Maven Central to make it available to developers who want to use it in their projects. This document outlines the process, configuration, and best practices for publishing releases.
Version Management ​
The framework release version is defined in the root POM (pom.xml) as the root reactor's <version>. Most root-reactor modules inherit that version through parent links, but several compatibility and reference surfaces are intentionally outside that reactor or use alternate top-level POMs.
Keep these categories aligned during every release:
- Root reactor: root, framework, main examples, and plugins listed in the root
pom.xml. - Alternate topology POMs: build-entry POMs such as
examples/csv-payments/pom.pipeline-runtime.xmlandexamples/csv-payments/pom.monolith.xml. - Standalone compatibility surfaces: POMs such as
ai-sdk/pom.xmland reference examples outside the root reactor.
Version Property Definition ​
In the root POM (pom.xml):
<version>26.4.5-SNAPSHOT</version>Root-reactor children should inherit this version through the parent relationship and omit their own project <version> where possible. Alternate top-level POMs and standalone builds may need an explicit parent version or dependency property, so they must be checked separately.
For the v26.5.2 release, use release version 26.5.2, tag v26.5.2, and next development version 26.6.1-SNAPSHOT.
Using Maven Versions Plugin ​
To update root-reactor versions consistently, use the Maven Versions Plugin:
# Update the version across all modules
./mvnw versions:set -DnewVersion=1.0.0
# Verify the changes before committing
./mvnw versions:commit
# Or rollback if needed
./mvnw versions:revertThis ensures that modules in the selected Maven reactor are updated consistently. It does not automatically update alternate POM entrypoints or standalone surfaces that are not part of that reactor.
Documentation Snapshot (Hybrid Versioning) ​
For released docs versions, snapshot the docs into docs/versions/:
cd docs
npm run snapshot -- --version v0.9.3Then update docs/versions.md to mark the latest version and confirm the version selector list.
Maven Central Publishing Setup ​
The Maven Central publishing configuration is located in the framework's parent POM (framework/pom.xml). It is handled by the GitHub Actions workflow, but this is a description of how such setup could be done on your local workstation.
Required Plugins ​
The following plugins are configured in the framework POM for Maven Central compliance:
- Source Plugin: Generates sources JAR
- Javadoc Plugin: Generates documentation JAR
- GPG Plugin: Signs artifacts
- Central Publishing Plugin: Deploys to Sonatype Central
For the complete configuration, see the central-publishing profile in framework/pom.xml.
Local settings.xml Configuration ​
To authenticate with Sonatype Central and provide GPG credentials, you could configure your ~/.m2/settings.xml file:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>central</id>
<username>your-sonatype-username</username>
<password>your-encrypted-sonatype-password</password>
</server>
</servers>
</settings>GPG Configuration ​
The publishing workflow handles GPG signing on GitHub Actions, but for reference, this is how you could configure it on your local machine:
<profiles>
<profile>
<id>central-publishing</id>
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.passphrase>your-gpg-passphrase</gpg.passphrase>
<gpg.keyname>your-gpg-key-id</gpg.keyname>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>central-publishing</activeProfile>
</activeProfiles>Encrypting Passwords ​
To encrypt your Sonatype password on your local settings.xml:
Create the master password:
bash./mvnw --encrypt-master-passwordThis creates
~/.m2/settings-security.xmlEncrypt your Sonatype password:
bash./mvnw --encrypt-passwordUpdate settings.xml with the encrypted password (prefixed with
{and suffixed with}).
GitHub Actions Workflow ​
The publishing process is automated using GitHub Actions.
Required GitHub Secrets ​
These secrets must exist in the GitHub repository:
CENTRAL_USERNAME- Your Sonatype usernameCENTRAL_PASSWORD- Your Sonatype passwordGPG_PRIVATE_KEY- Your GPG private key exported withgpg --export-secret-keys --armor <your-key-id>GPG_PASSPHRASE- The passphrase for your GPG key
Nightly Snapshot Publishing ​
The current main development version is scheduled for publication daily at 02:00 UTC by .github/workflows/publish-snapshots.yml. Publication depends on a successful workflow run and may be delayed. The workflow can also be dispatched manually, but its publish job runs only from main. It verifies the same framework reactor that the release workflow deploys, then publishes the existing -SNAPSHOT version with the central-publishing profile. It does not create a tag or GitHub release.
Sonatype Central snapshots are mutable development artifacts and are currently cleaned up after 90 days. Before the first snapshot deployment, enable SNAPSHOT publishing for the project namespace in the Central Portal. Consumers must explicitly enable the Central snapshots repository and should depend on the active framework -SNAPSHOT version:
<repositories>
<repository>
<id>central-portal-snapshots</id>
<name>Central Portal Snapshots</name>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>Snapshots do not have the immutability guarantees of tagged Maven Central releases. Use a released version for production dependencies that require a stable, permanent artifact.
Safe Release Process ​
Standard Release Workflow ​
Use the Maven Release Plugin as the versioning tool for the root reactor, but keep publication gated by explicit inspection and CI validation.
Start from a clean release branch:
bashgit status --short git fetch origin --tagsConfirm the branch contains the intended docs snapshot and no unrelated local changes.
Prepare the release locally without pushing:
bash./mvnw release:prepare \ -DpushChanges=false \ -DreleaseVersion=X.Y.Z \ -DdevelopmentVersion=NEXT_VERSION-SNAPSHOT \ -Dtag=vX.Y.Z \ -Darguments="-DskipTests"The root POM also configures
<pushChanges>false</pushChanges>for the release plugin. Keep the command-line flag anyway so the behavior is explicit in shell history and release notes.The plugin creates two local commits and a local tag:
[maven-release-plugin] prepare release vX.Y.Z[maven-release-plugin] prepare for next development iterationvX.Y.Z
Inspect the release plugin output before any push:
bashgit log --oneline --decorate -n 5 git diff HEAD~2..HEAD -- pom.xml framework/pom.xml examples ai-sdk pluginsThe release commit should contain the release version. The next-development commit should contain the next
-SNAPSHOTversion.Synchronize release-coupled POMs outside the root reactor: The release plugin only updates POMs in the Maven reactor it runs. After
release:prepare, check and fix alternate topology and standalone POMs so they match the next development version onmain.Required checks:
bashrg -n "X\\.Y\\.Z-SNAPSHOT" --glob "pom*.xml" --glob "!docs/versions/**" rg -n "X\\.Y\\.Z" examples ai-sdk --glob "pom*.xml"Replace
X.Y.Zwith the just-released version. There should be no remaining references to the old snapshot in active POMs after the next-development commit.At minimum, check:
examples/csv-payments/pom.pipeline-runtime.xmlexamples/csv-payments/pom.monolith.xmlexamples/csv-payments/pipeline-runtime-svc/pom.xmlexamples/csv-payments/monolith-svc/pom.xmlexamples/checkout/pom.xmland its child modulesai-sdk/pom.xml
Run the release validation gate before pushing:
bash./mvnw -f framework/pom.xml verify ./examples/csv-payments/build-pipeline-runtime.sh -pl orchestrator-svc -Dcsv.runtime.layout=pipeline-runtime -Dtest=PipelineRuntimeTopologyTest -Dit.test=CsvPaymentsPipelineRuntimeEndToEndIT verify ./examples/csv-payments/build-monolith.sh -DskipTests ./mvnw -f ai-sdk/pom.xml test npm --prefix docs run buildIf time forces a smaller gate, record exactly which commands were skipped and do not claim full release validation.
Push the validated commits:
bashgit push origin mainWatch the
mainworkflows. If a workflow fails because of version drift, fixmainbefore pushing the tag.Publish the release:
bashgit push origin vX.Y.ZThis triggers the GitHub Actions workflow that runs
mvn deployto publish framework artifacts to Maven Central.
Note: The mvn release:perform step is not used in this setup since deployment is handled by GitHub Actions when a tag is pushed.
Important Publishing Details (Central Validation) ​
Publishing scope ​
The publish workflow deploys only the framework artifacts (parent, runtime, deployment) and skips examples:
- Maven runs from the repo root with
-pl framework,framework/runtime,framework/deployment -am. - The root POM is included in the reactor but is not deployed (
maven.deploy.skip=truein the root, overridden to false inframework/pom.xml).
Note: Publishing the framework-parent artifact is expected. It is the BOM/parent POM that consumers import for dependency management, so it will appear in Maven Central autocomplete results.
Publishing only framework artifacts does not mean example and SDK versions can drift. The E2E CI lanes build compatibility surfaces from the same checkout and expect their parent versions and tpf.version properties to match the root development version. A stale alternate POM can fail before tests start with Non-resolvable parent POM because its relativePath points to the checked-out root POM at a different version.
Main-branch E2E impact ​
The CSV E2E workflows run from alternate topology POMs. During the v26.4.4 release, release:prepare updated the root reactor to 26.4.5-SNAPSHOT, but left examples/csv-payments/pom.pipeline-runtime.xml, examples/csv-payments/pom.monolith.xml, and ai-sdk/pom.xml at 26.4.4-SNAPSHOT. Because the release plugin pushed by default, main received the drift before it was reviewed. The next main E2E runs then failed at Maven model resolution rather than test execution.
Treat this as a release-blocking condition:
rg -n "OLD_VERSION-SNAPSHOT" --glob "pom*.xml" --glob "!docs/versions/**"The command should return no active POMs after the next-development commit is prepared.
Flattening at publish time (property-gated) ​
Central validation requires resolved dependency versions. We avoid profiles for core behavior and enable flattening only during publish using a property:
- Default:
-Dtpf.flatten.skip=true(skip flatten during normal builds) - Publish:
-Dtpf.flatten.skip=false(flatten only for release)
This keeps local builds clean while producing Central-compliant POMs.
Tag immutability ​
Release tags are treated as immutable. If a publish fails after a tag is created, you generally cannot reuse the same tag:
- Create a new patch tag (e.g.,
v26.2.1,v26.2.2) for retries. - If repo rules allow, tags can be created from the GitHub UI as part of a release draft.
When to Use the Versions Plugin Approach ​
Use this manual approach only when you need fine-grained control or the Release Plugin is not available:
- Manual Version Update:
Update the version using the Maven Versions Plugin:
bash./mvnw versions:set -DnewVersion=1.0.0 ./mvnw versions:commitTest the build with
./mvnw clean install -P central-publishingCreate a Git tag (e.g.,
v1.0.0)Push the tag to trigger the GitHub Actions release workflow
Comparison:
- Release Plugin: Handles version updates across the selected Maven reactor, creates local release commits, and creates the local tag. It must run with push disabled so version drift can be fixed before
mainmoves. - Versions Plugin: Offers more manual control but requires multiple manual steps and careful coordination
Alternative: Manual Release Workflow ​
For more control, you can create a workflow dispatch that requires manual triggering:
name: Manual Publish to Maven Central
on:
workflow_dispatch:
inputs:
release_version:
description: 'Release version (e.g., 1.0.0)'
required: true
type: string
dry_run:
description: 'Dry run? (true/false)'
required: false
default: true
type: booleanThis approach allows manual control over when releases happen.
Troubleshooting ​
GPG Signing Errors:
- Verify your GPG key is properly configured
- Check that the GPG key ID matches what's in your keystore
- Ensure the GPG agent is running or passphrase is provided
Sonatype Authentication Errors:
- Verify your credentials in settings.xml
- Ensure you're using encrypted passwords in public repositories
- Check that your Central account has permissions for the group ID
Sonatype Central Publishing Errors:
- Review Sonatype Central logs in the GitHub Actions workflow
- Ensure all required artifacts (JARs, sources, javadoc, signatures) are present
- Check that artifacts meet Maven Central requirements
Main E2E Fails Before Tests Start:
- Check for stale parent versions in alternate POMs:
rg -n "OLD_VERSION-SNAPSHOT" --glob "pom*.xml" --glob "!docs/versions/**" - Check standalone TPF dependency properties such as
ai-sdk/pom.xml'stpf.version - Confirm the local root POM version matches the parent version in
examples/csv-payments/pom.pipeline-runtime.xmlandexamples/csv-payments/pom.monolith.xml
Testing the Setup ​
Before pushing a tag that triggers the release workflow:
mvn clean verify- test the build locally (runs unit tests)mvn clean verify -DskipITs- test build without integration testsmvn clean verify -P central-publishing- test with the central publishing profile but without deployment- Use a test Sonatype repository for verification
Important Notes ​
- Only the framework artifacts are published to Maven Central.
- Examples and SDK surfaces are not Central artifacts, but they are release-coupled because CI and users build them against the checked-out framework version.
- The root POM orchestrates the main build while the framework POM handles publishing.
- Prefer parent inheritance inside the root reactor. Check alternate top-level POMs and standalone POM properties separately during release preparation.
- Always verify release artifacts on Maven Central after a successful deployment.