Step-by-step playbook for cutting a release of meshtastic-sdk. The
SemVer policy that governs what kind of release is appropriate lives in
docs/versioning.md; this document is the mechanics.
- You are listed in
CODEOWNERS. mainis green (latest CI run on the tip commit is ✅).- You have a clean working tree (
git statusis empty). - You have signing credentials for Maven Central in your environment if
cutting a stable release (
SIGNING_KEY,SIGNING_PASSWORD,MAVEN_CENTRAL_USERNAME,MAVEN_CENTRAL_PASSWORD). Snapshot releases do not need these.
Open the diff since the last tag:
git --no-pager log --oneline $(git describe --tags --abbrev=0)..HEADPick MAJOR / MINOR / PATCH per docs/versioning.md. If
unclear, ask a second maintainer in the PR thread before tagging.
Run from a clean tree:
./gradlew clean
./gradlew check # full gate: build, lint, detekt, BCV, tests
./gradlew :core:verifyModuleBoundary # ADR-008 — also part of `check`
./gradlew checkKotlinAbi # confirm api/*.api dumps are committed
./gradlew publishToMavenLocal # smoke test publishing layout
bash .github/tooling/check.sh # agent/tooling guardrailsIf checkKotlinAbi fails because public API intentionally changed, run
./gradlew updateKotlinAbi, commit the regenerated api/*.api, push, and start
this checklist over.
A passing ./gradlew check is necessary but not sufficient — every release
candidate must also pass the bench-radio acceptance sweep. Run from a connected
host with the bench radio reachable on the same network:
./gradlew :samples:cli:installDist
samples/cli/build/install/cli/bin/cli conformance \
--transport=tcp:meshtastic.local \
--peer-node='!aabbccdd' \
--candidate=vX.Y.Z-rc1 \
--output MANUAL-TEST-RESULTS.mdThe command exits 0 only if every scenario PASSes (SKIPs are allowed when
prerequisites like --peer-node aren't supplied). The transcript at
MANUAL-TEST-RESULTS.md is the audit trail for the release; commit it under
docs/release-history/ if you're keeping per-RC records, otherwise replace it
each cycle. See samples/cli/README.md
for the full set of flags.
Move everything under ## [Unreleased] to a new ## [vX.Y.Z] - YYYY-MM-DD
heading. Re-create an empty ## [Unreleased] section above it with the
standard ### Added / ### Changed / ### Removed / ### Fixed subsections.
If this is a pre-1.0 MINOR with breaking changes, add a ### Breaking
subsection at the top of the new release section, per
docs/versioning.md §Pre-1.0 policy.
Commit:
git add CHANGELOG.md
git commit -s -m "docs(changelog): prepare vX.Y.Z release notes"axion-release derives the version from the most recent annotated tag:
git tag -a vX.Y.Z -m "vX.Y.Z"
git push origin main --tagsConfirm: ./gradlew currentVersion should print X.Y.Z (no -SNAPSHOT
suffix) on the tagged commit.
Stable releases publish via the manual release workflow in
.github/workflows/ — trigger it via
gh workflow run release.yml -f version=X.Y.Z or the GitHub Actions UI.
Currently disabled. All workflows are suffixed
.yml.disabledfor the internal 0.1.0 team-share; until they're re-enabled, run the publish steps locally (./gradlew publish) per the workflow's intended sequence below.
The workflow:
- Re-runs
./gradlew check. - Runs
./gradlew publishAggregationToCentralPortal(perdocs/ci-cd.md). - Promotes the staged release on Sonatype Central Portal.
Snapshot releases publish automatically on every push to main — no
manual step needed.
- Create the GitHub release:
gh release create vX.Y.Z --notes-file <(awk '/^## \[vX.Y.Z\]/,/^## \[/' CHANGELOG.md | head -n -1)— verify the body before publishing. - Mark breaking changes with the
**BREAKING**prefix on the release notes title if applicable. - Verify the artifact:
./gradlew dependencyInsight --dependency org.meshtastic:sdk-core:X.Y.Zfrom a fresh consumer project pointing at Maven Central. It should resolve without-SNAPSHOT. - Announce in the channels listed in
SUPPORT.md.
Maven Central artifacts are immutable — there is no yank. If a release
ships a critical bug, cut a PATCH release immediately with the fix and
update SECURITY.md if the issue is security-relevant.
For pre-1.0 releases that are unsalvageable, document the 0.X.Y tag as
withdrawn in CHANGELOG.md and bump the MINOR.
Cherry-pick the fix onto a release/X.Y branch off the offending tag,
re-run the pre-release checklist, tag vX.Y.(Z+1), and push. Hotfixes
follow the same publish path as a normal stable release.
docs/versioning.md— SemVer policy.docs/ci-cd.md— workflow definitions and the publish task.- ADR-003 — axion-release + vanniktech + Central Portal rationale.
CHANGELOG.md