Skip to main content

Release Overview

Paimon and PyPaimon share a release version and a community vote. This page explains what is released and who does each part of the work. Use the linked guides for commands and verification steps.

Your taskGuideResult
Manage a release candidate (RC)Creating a releaseSigned source archives, a closed Java staging repository, and a vote thread
Review a candidateVerifying a release candidateAn independent vote with the checks and environment recorded
Publish an approved candidatePublishing a releasePublic artifacts, documentation, release notes, and announcement

Release lifecycle

Release lifecycle: prepare and tag a candidate, stage its artifacts, verify and vote, then publish the approved candidate. A failed candidate returns to preparation with a new RC number.

Open the lifecycle diagram at full size.

  1. The Release Manager (RM) agrees the scope with the community and creates a signed RC tag.
  2. GitHub Actions packages convenience artifacts. The RM signs and stages the Java artifacts and both source archives from the same tag.
  3. Community members independently verify the candidate and vote. The RM records the result.
  4. After approval, the RM publishes the approved artifacts and updates the documentation and website before announcing the release. A failed candidate needs a new RC number and a new vote.

The process follows the ASF Release Policy and ASF Release Distribution Policy.

Preserve the approved candidate

The signed source archives are the Apache releases. Maven and PyPI packages are convenience artifacts. Promote the source archives and closed Java repository approved by the vote; do not rebuild or replace them. The final PyPI package is built from the approved commit with the final version.

Release model

The combined Paimon and PyPaimon release uses one shared version number. The Maven project version and paimon-python/setup.py version must be equal.

DeliverableCandidatePublished location
Paimon sourceapache-paimon-PAIMON_VERSION-src.tgz, .asc, .sha512ASF distribution
Java convenience artifactsMaven artifacts built in the JDK 8, 11, and 17 lanesApache Nexus staging, then Maven Central
PyPaimon sourcepypaimon-PAIMON_VERSION.tar.gz, .asc, .sha512ASF distribution
Python convenience packagepypaimon==PAIMON_VERSIONrcRC_NUMBER for an RCTestPyPI, then pypaimon==PAIMON_VERSION on PyPI

A combined release vote covers both signed source candidates. This guide does not define an independent PyPaimon release. Before releasing PyPaimon separately, the PMC must define a Python-only tag and workflow which do not depend on the Maven version or Java jobs, and must provide a signed source package which is independently sufficient to build and test the release.

Java build matrix

The three Java lanes are different release targets, not interchangeable build JDKs:

JDKMaven profiles and scopeMain artifacts
8spark3,flink1 and the default reactorPaimon core, Flink 1.x, Spark 3.x, Hive, filesystems, bundles, and other Java 8 artifacts
11flink2 plus paimon-icebergFlink 2.x, paimon-flink2-common, and Iceberg integration
17spark4Spark 4.x and its Scala 2.13 common artifacts

Each lane must use the matching JDK. Building everything on JDK 17 with a lower compiler target is not a substitute for running the JDK 8 and JDK 11 lanes.

GitHub Actions release workflow

The release process uses the Release workflow to package the JDK 8, JDK 11, and JDK 17 Java lanes and PyPaimon from every signed RC tag. The Java lanes are merged into one unsigned Maven repository image. The RM downloads that image, signs it, and stages it in Nexus. The RM also creates and signs the two ASF source archives locally from the same tag. The RM's GPG private key is never stored in GitHub Actions.

The workflow has the following contract:

JobRequired behavior
ValidationRequire an RC tag named release-PAIMON_VERSION-rcN or a final tag named release-PAIMON_VERSION, where PAIMON_VERSION exactly equals the root Maven project.version
Java 8Use Temurin 8 to deploy the default reactor with Spark 3 and Flink 1 into a local Maven repository image
Java 11Use Temurin 11 to deploy Flink 2 and Iceberg into a local Maven repository image
Java 17Use Temurin 17 to deploy Spark 4 into a local Maven repository image
Java repositoryRequire every deploy-enabled effective-POM project and its POM, main JAR, and source JAR; retain Javadoc JARs where Maven produces them; merge all three lanes; reject conflicting coordinates; then upload the complete unsigned Maven repository image, checksums, manifests, and logs
Python packageBuild and validate the PyPaimon source distribution and universal wheel, then upload them as workflow artifacts
Python publishPublish an RC to TestPyPI or a final tag to PyPI after Python packaging passes, without waiting for Java packaging

Before packaging, every Java lane runs Maven Enforcer's requireReleaseVersion and requireReleaseDeps rules over its complete reactor scope. The latter includes transitive dependencies. Any remaining -SNAPSHOT project, parent, direct dependency, or transitive dependency is a release blocker.

The Java jobs run independently of the common validation and Python jobs. They use -Dgpg.skip=true, deploy only to runner-local file repositories, and never receive Nexus credentials or a GPG private key. The combined repository image contains POMs, main artifacts, source JARs, Javadoc JARs produced by Maven, and Maven-generated checksums. Scala-only and wrapper modules may not produce a Javadoc JAR. The image is the input to the RM's local signing and Nexus staging steps, not itself an ASF release. The Python RC job uses the TEST_PYPI_API_TOKEN repository Actions secret to publish PAIMON_VERSIONrcRC_NUMBER to TestPyPI. The final job uses the PYPI_API_TOKEN repository Actions secret to publish to PyPI. The release workflow passes only these two secrets to the reusable publishing workflow.

Artifact flow

A signed RC tag feeds three artifact paths: locally signed sources staged in ASF dist dev, a Java repository signed locally and closed in Nexus, and Python packages published to TestPyPI. After approval, sources and Java artifacts are promoted, while the final signed tag builds the final PyPI version.

Open the artifact diagram at full size.

Source and Java publication preserve the approved bytes. Python publication builds the final PyPI version from the final tag at the approved RC commit. All three paths must be checked before the release announcement.

Responsibilities and handoffs

OwnerResponsibilityEvidence to hand off
RMReview relevant CI results and prepare an immutable candidateSigned tag, commit SHA, and release versions
GitHub ActionsPackage Java lanes and Python artifactsRun URL, manifests, checksums, logs, and TestPyPI version
RMSign locally and stage the candidateBoth source URLs, signing-key fingerprint, and closed Nexus repository URL
VotersIndependently inspect, build, and test the source candidateVote with actual checks, platforms, tool versions, and any failures
RMTally the vote and publish after approvalVote result, final tag, public downloads, and updated documentation

The Java packaging lanes do not run the full test matrix. The RM reviews relevant CI results before calling the vote, and voters report their own source build and test scope. Packaging success alone is not release approval.