Releasing LeakCanary¶
Prerequisites¶
Publishing to Maven Central is fully automated: the
publish-release.yml
GitHub Actions workflow builds, signs, and publishes to the
Maven Central Portal. The credentials live as
GitHub organization secrets, so no local Sonatype account or signing key is
required to cut a release:
SONATYPE_CENTRAL_USERNAME/SONATYPE_CENTRAL_PASSWORD— a Central Portal user tokenGPG_SECRET_KEY/GPG_SECRET_PASSPHRASE— the artifact signing key
To run a release you only need:
- GitHub CLI and
jq:brew install gh jq - The documentation toolchain (used to generate and deploy the docs site):
python3 -m venv venv source venv/bin/activate pip3 install --requirement docs/requirements.txt - The Google Analytics key, required by
mkdocswhen deploying the docs. Add to your~/.bashrc:export LEAKCANARY_GOOGLE_ANALYTICS_KEY="UA-142834539-1"
Milestone management aliases (optional helpers)¶
gh alias set listOpenMilestones "api graphql -F owner=':owner' -F name=':repo' -f query='
query ListOpenMilestones(\$name: String\!, \$owner: String\!) {
repository(owner: \$owner, name: \$name) {
milestones(first: 100, states: OPEN) {
nodes {
title
number
description
dueOn
url
state
closed
closedAt
updatedAt
}
}
}
}
'"
gh alias set --shell createMilestone "gh api --method POST repos/:owner/:repo/milestones --input - | jq '{ html_url: .html_url, state: .state, created_at: .created_at }'"
gh alias set --shell closeMilestone "echo '{\"state\": \"closed\"}' | gh api --method PATCH repos/:owner/:repo/milestones/\$1 --input - | jq '{ html_url: .html_url, state: .state, closed_at: .closed_at }'"
Publishing locally is normally unnecessary (and OSSRH-based local publishing no longer works). If you ever need it, set
mavenCentralUsername/mavenCentralPassword(a Central Portal token) andsigningInMemoryKey/signingInMemoryKeyPasswordas Gradle properties — the sameORG_GRADLE_PROJECT_*names the workflow uses — then run./gradlew publish.
Releasing¶
Set the version variables once; every step below uses them. This avoids the
hand-edited placeholders that previously caused mistakes (e.g. a dropped
-SNAPSHOT).
echo "Current: $(grep VERSION_NAME gradle.properties)"
printf "Version being released (e.g. 3.0-alpha-9): " && read NEW_VERSION
printf "Next version, WITHOUT -SNAPSHOT (e.g. 3.0-alpha-10): " && read NEXT_VERSION
# Previous release tag, used for the changelog diff link:
PREV_VERSION=$(git tag --sort=-v:refname | head -1)
echo "Releasing $NEW_VERSION (previous: $PREV_VERSION), next dev version: $NEXT_VERSION-SNAPSHOT"
-
Create the release branch and set the release version:
git checkout main && git pull && \ git checkout -b release_$NEW_VERSION && \ sed -i '' "s/VERSION_NAME=.*/VERSION_NAME=$NEW_VERSION/" gradle.properties -
Update
mkdocs.yml.next_releaseis the in-development version referenced by the snapshot docs — bump it to the next version.releaseis the latest stable version used throughout the getting-started docs; only change it when releasing a stable version, so leave it alone for alpha/beta releases.sed -i '' "s/next_release: .*/next_release: '$NEXT_VERSION'/" mkdocs.yml # Stable releases ONLY — also promote the stable version: # sed -i '' "s/release: .*/release: '$NEW_VERSION'/" mkdocs.yml -
Update the changelog: rename the
## Unreleasedsection to## Version $NEW_VERSION (<date>), make sure it lists everything merged since the last release, and add a full diff link at the end of the section:(Commit list for reference:See the [full diff](https://github.com/square/leakcanary/compare/v<PREV_VERSION>...v<NEW_VERSION>).https://github.com/square/leakcanary/compare/v$PREV_VERSION...main)"${EDITOR:-vi}" docs/changelog.md -
Commit, tag, push, and trigger the publish workflow. It builds, signs, and publishes to the Maven Central Portal (
automaticReleasereleases it once validation passes — no manual portal step).git commit -am "Prepare $NEW_VERSION release" && \ git tag v$NEW_VERSION && \ git push origin v$NEW_VERSION && \ gh workflow run publish-release.yml --ref v$NEW_VERSION && \ sleep 5 && \ gh run list --workflow=publish-release.yml --branch v$NEW_VERSION --json databaseId --jq ".[].databaseId" | xargs -I{} gh run watch {} --exit-status
Notes:
- The
publish-release.ymlworkflow must already exist onmainto be dispatchable (workflow_dispatchrequirement). -
Monitor or drop deployments at https://central.sonatype.com/publishing/deployments
-
Build the
shark-clidistribution and create the GitHub release. Do this whileVERSION_NAMEis still the release version (before the-SNAPSHOTbump below), otherwise the zip is named after the snapshot version../gradlew shark:shark-cli:distZip && \ gh release create v$NEW_VERSION ./shark/shark-cli/build/distributions/shark-cli-$NEW_VERSION.zip --title v$NEW_VERSION --notes 'See [Change Log](https://square.github.io/leakcanary/changelog)' -
Merge back to
mainand start the next development iteration. The-SNAPSHOTsuffix is required: without it,maincarries a release-style version for the whole dev cycle, which breaks snapshot deployment.git checkout main && git pull && \ git merge --no-ff --no-edit release_$NEW_VERSION && \ sed -i '' "s/VERSION_NAME=.*/VERSION_NAME=$NEXT_VERSION-SNAPSHOT/" gradle.properties && \ git commit -am "Prepare for next development iteration" && \ git push -
Generate the API docs and deploy the documentation site. Preview locally first if you want (
mkdocs serve, then open http://127.0.0.1:8000/leakcanary/changelog/).rm -rf docs/api && ./gradlew siteDokka && \ source venv/bin/activate && \ mkdocs gh-deploy -
Update milestones. There is one milestone per release:
- Make sure the milestone for the version you just released contains only the issues fixed in this release; move any unfinished issues to the next milestone.
- Close the released milestone and create the next one as the active milestone.
List open milestones with gh listOpenMilestones, then use
gh closeMilestone <number> and gh createMilestone (see the aliases above).
-
Open the v$NEW_VERSION release to confirm everything looks good.
-
Wait for the release to be available on Maven Central.
-
Stable releases only: publish
shark-clito Homebrew. homebrew-core only accepts stable versions, so skip this for alpha/beta releases.brew bump-formula-pr --url https://github.com/square/leakcanary/releases/download/v$NEW_VERSION/shark-cli-$NEW_VERSION.zip leakcanary-shark -
Tell your friends, update all of your apps, and announce the new release. As a nice extra touch, mention external contributions.