This guide describes how to create a release of Apache Paimon Rust, including the Rust crates, Python binding, and Go binding. It follows the ASF Release Policy and Release Distribution Policy.
The release process consists of:
When a version tag is pushed, GitHub Actions automatically publishes the language-specific artifacts:
| Component | Tag Pattern | Published To | Pre-release (-rc) Behavior |
|---|---|---|---|
| Rust crates | v0.1.0 | crates.io | Dry-run only |
| Python binding | v0.1.0 | PyPI | Publishes to TestPyPI |
| Go binding | v0.1.0 | Go module proxy | Publishes as bindings/go/vX.Y.Z-rcN |
The Release Manager's primary responsibility is managing the source release (tarball + signature) and coordinating the community vote. Language artifact publishing is handled by CI once the final tag is pushed.
Deciding to release and selecting a Release Manager is the first step. This is a consensus-based decision of the community.
Anybody can propose a release on the dev mailing list, giving a short rationale and nominating a committer as Release Manager (including themselves).
Checklist
Before your first release, complete the following setup.
Install GnuPG if not already available:
# macOS brew install gnupg # Ubuntu / Debian sudo apt install gnupg2
Generate a key pair:
gpg --full-gen-key
When prompted, select:
@apache.org emailList your keys to find your key ID (the 8-digit hex string in the pub line):
gpg --list-keys --keyid-format short
Example output:
pub rsa4096/845E6689 2024-01-01 [SC] ABCDEF1234567890ABCDEF1234567890845E6689 uid [ultimate] Your Name <yourname@apache.org> sub rsa4096/12345678 2024-01-01 [E]
In this example, the key ID is 845E6689. Replace <YOUR_KEY_ID> with your actual key ID in the following steps.
Upload your public key to the Ubuntu key server:
gpg --keyserver hkps://keyserver.ubuntu.com --send-keys <YOUR_KEY_ID>
Append your key to the project KEYS file (requires PMC write access):
svn co https://dist.apache.org/repos/dist/release/paimon/ paimon-dist-release --depth=files cd paimon-dist-release (gpg --list-sigs <YOUR_KEY_ID> && gpg --armor --export <YOUR_KEY_ID>) >> KEYS svn ci -m "Add <YOUR_NAME>'s public key"
!!! note Never remove existing keys from the KEYS file — users may need them to verify older releases.
Configure Git to sign tags with your key:
git config --global user.signingkey <YOUR_KEY_ID>
Omit --global to only configure signing for the current repository.
(Optional) Upload the GPG public key to your GitHub account:
Go to https://github.com/settings/keys and add your GPG key. Make sure the email associated with the key is also added at https://github.com/settings/emails, otherwise signed commits and tags may show as “Unverified”.
Ensure the following repository secrets are configured:
CARGO_REGISTRY_TOKEN — for crates.io publishingPYPI_API_TOKEN — for PyPI publishingTEST_PYPI_API_TOKEN — for TestPyPI publishingUse a clean clone to avoid local changes affecting the release.
git clone https://github.com/apache/paimon-rust.git cd paimon-rust
RELEASE_VERSION="0.1.0" SHORT_RELEASE_VERSION="0.1" NEXT_VERSION="0.2.0" RELEASE_TAG="v${RELEASE_VERSION}" RC_NUM="1" RC_TAG="v${RELEASE_VERSION}-rc${RC_NUM}"
ASF release policy requires that every release comply with ASF licensing policy. Generate and commit a dependency list on main before creating the release branch, so both main and the release branch have the same list.
Install cargo-deny:
cargo install cargo-deny
Generate the dependency list (requires Python 3.11+):
git checkout main git pull python3 scripts/dependencies.py generate
This creates a DEPENDENCIES.rust.tsv file for the workspace root and each member crate.
Commit the result:
git add **/DEPENDENCIES*.tsv git commit -m "chore: update dependency list for release ${RELEASE_VERSION}" git push origin main
To only check licenses without generating files: python3 scripts/dependencies.py check.
From main, create a release branch:
git checkout -b release-${SHORT_RELEASE_VERSION} git push origin release-${SHORT_RELEASE_VERSION}
After cutting the release branch, bump main to the next version so that ongoing development does not use the released version number:
git checkout main ./scripts/bump-version.sh ${RELEASE_VERSION} ${NEXT_VERSION} git add Cargo.toml git commit -m "chore: bump version to ${NEXT_VERSION}" git push origin main
The script updates version in root Cargo.toml ([workspace.package] and the paimon entry in [workspace.dependencies]). All member crates inherit the workspace version.
If the project website has a release blog or download page, create pull requests to add the new version. Do not merge these PRs until the release is finalized.
Check out the release branch, create a signed RC tag, and push it. Pushing the tag triggers CI workflows for all three components.
git checkout release-${SHORT_RELEASE_VERSION} git pull git tag -s ${RC_TAG} -m "${RC_TAG}" git push origin ${RC_TAG}
After pushing, verify in GitHub Actions that all release workflows succeed:
bindings/go/${RC_TAG} tagFrom the repository root (on the release branch, at the commit you tagged):
./scripts/release.sh ${RELEASE_VERSION}
This creates the following under dist/:
paimon-rust-${RELEASE_VERSION}.tar.gz — source archivepaimon-rust-${RELEASE_VERSION}.tar.gz.asc — GPG signaturepaimon-rust-${RELEASE_VERSION}.tar.gz.sha512 — SHA-512 checksumThe script automatically generates the archive from HEAD via git archive, signs it with your GPG key, and verifies the signature.
Upload the source release to the ASF dev area:
svn checkout https://dist.apache.org/repos/dist/dev/paimon/ paimon-dist-dev --depth=immediates cd paimon-dist-dev mkdir paimon-rust-${RELEASE_VERSION}-rc${RC_NUM} cp ../paimon-rust-${RELEASE_VERSION}.tar.gz* paimon-rust-${RELEASE_VERSION}-rc${RC_NUM}/ svn add paimon-rust-${RELEASE_VERSION}-rc${RC_NUM} svn commit -m "Add paimon-rust ${RELEASE_VERSION} RC${RC_NUM}"
Checklist
Start a vote on the dev mailing list.
Subject: [VOTE] Release Apache Paimon Rust ${RELEASE_VERSION} (RC${RC_NUM})
Body:
Hi everyone, Please review and vote on release candidate #${RC_NUM} for Apache Paimon Rust ${RELEASE_VERSION}. [ ] +1 Approve the release [ ] +0 No opinion [ ] -1 Do not approve (please provide specific comments) The release candidate is available at: https://dist.apache.org/repos/dist/dev/paimon/paimon-rust-${RELEASE_VERSION}-rc${RC_NUM}/ Git tag: https://github.com/apache/paimon-rust/releases/tag/${RC_TAG} KEYS for signature verification: https://downloads.apache.org/paimon/KEYS The vote will be open for at least 72 hours. Thanks, Release Manager
After the vote passes, send a result email:
Subject: [RESULT][VOTE] Release Apache Paimon Rust ${RELEASE_VERSION} (RC${RC_NUM})
If the vote reveals issues:
cd paimon-dist-dev svn remove paimon-rust-${RELEASE_VERSION}-rc${RC_NUM} svn commit -m "Remove paimon-rust ${RELEASE_VERSION} RC${RC_NUM} (superseded)"
RC_NUM, then go back to Build a release candidate.Once the vote passes, create and push the final release tag. This triggers CI to publish to crates.io, PyPI, and Go module proxy automatically.
git checkout ${RC_TAG} git tag -s ${RELEASE_TAG} -m "Release Apache Paimon Rust ${RELEASE_VERSION}" git push origin ${RELEASE_TAG}
svn mv -m "Release paimon-rust ${RELEASE_VERSION}" \ https://dist.apache.org/repos/dist/dev/paimon/paimon-rust-${RELEASE_VERSION}-rc${RC_NUM} \ https://dist.apache.org/repos/dist/release/paimon/paimon-rust-${RELEASE_VERSION}
${RELEASE_VERSION}${RELEASE_VERSION}go list -m github.com/apache/paimon-rust/bindings/go@v${RELEASE_VERSION} resolves${RELEASE_TAG}.Checklist
Update the Releases page: move the released version from “Upcoming” to “Past Releases” with a summary of key features and a link to the GitHub release notes.
Wait at least 24 hours after finalizing. Send the announcement to dev@paimon.apache.org and announce@apache.org using your @apache.org email in plain text.
Subject: [ANNOUNCE] Release Apache Paimon Rust ${RELEASE_VERSION}
Body:
The Apache Paimon community is pleased to announce the release of Apache Paimon Rust ${RELEASE_VERSION}. Rust: cargo add paimon Python: pip install pypaimon-rust Go: go get github.com/apache/paimon-rust/bindings/go@v${RELEASE_VERSION} Release notes: https://github.com/apache/paimon-rust/releases/tag/v${RELEASE_VERSION} Thanks to all contributors!