xref: /aosp_15_r20/external/leakcanary2/docs/releasing.md (revision d9e8da70d8c9df9a41d7848ae506fb3115cae6e6)
1*d9e8da70SAndroid Build Coastguard Worker# Releasing LeakCanary
2*d9e8da70SAndroid Build Coastguard Worker
3*d9e8da70SAndroid Build Coastguard Worker## Preparing the release environment
4*d9e8da70SAndroid Build Coastguard Worker
5*d9e8da70SAndroid Build Coastguard Worker### Set up your Sonatype OSSRH account
6*d9e8da70SAndroid Build Coastguard Worker
7*d9e8da70SAndroid Build Coastguard Worker* Create a [Sonatype OSSRH JIRA account](https://issues.sonatype.org/secure/Signup!default.jspa).
8*d9e8da70SAndroid Build Coastguard Worker* Create a ticket to request access to the `com.squareup.leakcanary` project. Here's an example: [OSSRH-54959](https://issues.sonatype.org/browse/OSSRH-54959).
9*d9e8da70SAndroid Build Coastguard Worker* Then ask someone with deployer role from the LeakCanary team to confirm access.
10*d9e8da70SAndroid Build Coastguard Worker
11*d9e8da70SAndroid Build Coastguard Worker### Set up your signing key
12*d9e8da70SAndroid Build Coastguard Worker
13*d9e8da70SAndroid Build Coastguard Worker```bash
14*d9e8da70SAndroid Build Coastguard Worker# Create a new key
15*d9e8da70SAndroid Build Coastguard Workergpg --gen-key
16*d9e8da70SAndroid Build Coastguard Worker# List local keys. Key id is last 8 characters
17*d9e8da70SAndroid Build Coastguard Workergpg -K
18*d9e8da70SAndroid Build Coastguard Workercd ~/.gnupg
19*d9e8da70SAndroid Build Coastguard Worker# Export key locally
20*d9e8da70SAndroid Build Coastguard Workergpg --export-secret-keys -o secring.gpg
21*d9e8da70SAndroid Build Coastguard Worker# Upload key to Ubuntu servers
22*d9e8da70SAndroid Build Coastguard Workergpg --send-keys --keyserver keyserver.ubuntu.com <KEY ID>
23*d9e8da70SAndroid Build Coastguard Worker# Confirm the key can now be found
24*d9e8da70SAndroid Build Coastguard Workergpg --recv-keys --keyserver keyserver.ubuntu.com <KEY ID>
25*d9e8da70SAndroid Build Coastguard Worker```
26*d9e8da70SAndroid Build Coastguard Worker
27*d9e8da70SAndroid Build Coastguard Worker### Set up your home gradle.properties
28*d9e8da70SAndroid Build Coastguard Worker
29*d9e8da70SAndroid Build Coastguard WorkerAdd this to your `~/.gradle/gradle.properties`:
30*d9e8da70SAndroid Build Coastguard Worker
31*d9e8da70SAndroid Build Coastguard Worker```
32*d9e8da70SAndroid Build Coastguard Workersigning.keyId=<KEY ID>
33*d9e8da70SAndroid Build Coastguard Workersigning.password=<KEY PASSWORD>
34*d9e8da70SAndroid Build Coastguard Workersigning.secretKeyRingFile=/Users/YOUR_USERNAME_/.gnupg/secring.gpg
35*d9e8da70SAndroid Build Coastguard WorkerSONATYPE_NEXUS_USERNAME=<SONATYPE_USERNAME>
36*d9e8da70SAndroid Build Coastguard WorkerSONATYPE_NEXUS_PASSWORD=<SONATYPE_PASSWORD>
37*d9e8da70SAndroid Build Coastguard Worker```
38*d9e8da70SAndroid Build Coastguard Worker
39*d9e8da70SAndroid Build Coastguard Worker### Set up the Google Analytics docs key
40*d9e8da70SAndroid Build Coastguard Worker
41*d9e8da70SAndroid Build Coastguard WorkerAdd this to your `~/.bashrc`:
42*d9e8da70SAndroid Build Coastguard Worker
43*d9e8da70SAndroid Build Coastguard Worker```bash
44*d9e8da70SAndroid Build Coastguard Workerexport LEAKCANARY_GOOGLE_ANALYTICS_KEY="UA-142834539-1"
45*d9e8da70SAndroid Build Coastguard Worker```
46*d9e8da70SAndroid Build Coastguard Worker
47*d9e8da70SAndroid Build Coastguard Worker### Set up GitHub CLI
48*d9e8da70SAndroid Build Coastguard Worker
49*d9e8da70SAndroid Build Coastguard WorkerInstall GitHub CLI
50*d9e8da70SAndroid Build Coastguard Worker
51*d9e8da70SAndroid Build Coastguard Worker```bash
52*d9e8da70SAndroid Build Coastguard Workerbrew install gh
53*d9e8da70SAndroid Build Coastguard Worker```
54*d9e8da70SAndroid Build Coastguard Worker
55*d9e8da70SAndroid Build Coastguard WorkerInstall jq, a CLI Json processor
56*d9e8da70SAndroid Build Coastguard Worker
57*d9e8da70SAndroid Build Coastguard Worker```bash
58*d9e8da70SAndroid Build Coastguard Workerbrew install jq
59*d9e8da70SAndroid Build Coastguard Worker```
60*d9e8da70SAndroid Build Coastguard Worker
61*d9e8da70SAndroid Build Coastguard WorkerSet up aliases for milestone management:
62*d9e8da70SAndroid Build Coastguard Worker
63*d9e8da70SAndroid Build Coastguard Worker```bash
64*d9e8da70SAndroid Build Coastguard Workergh alias set listOpenMilestones "api graphql -F owner=':owner' -F name=':repo' -f query='
65*d9e8da70SAndroid Build Coastguard Worker    query ListOpenMilestones(\$name: String\!, \$owner: String\!) {
66*d9e8da70SAndroid Build Coastguard Worker        repository(owner: \$owner, name: \$name) {
67*d9e8da70SAndroid Build Coastguard Worker            milestones(first: 100, states: OPEN) {
68*d9e8da70SAndroid Build Coastguard Worker                nodes {
69*d9e8da70SAndroid Build Coastguard Worker                    title
70*d9e8da70SAndroid Build Coastguard Worker                    number
71*d9e8da70SAndroid Build Coastguard Worker                    description
72*d9e8da70SAndroid Build Coastguard Worker                    dueOn
73*d9e8da70SAndroid Build Coastguard Worker                    url
74*d9e8da70SAndroid Build Coastguard Worker                    state
75*d9e8da70SAndroid Build Coastguard Worker                    closed
76*d9e8da70SAndroid Build Coastguard Worker                    closedAt
77*d9e8da70SAndroid Build Coastguard Worker                    updatedAt
78*d9e8da70SAndroid Build Coastguard Worker                }
79*d9e8da70SAndroid Build Coastguard Worker            }
80*d9e8da70SAndroid Build Coastguard Worker        }
81*d9e8da70SAndroid Build Coastguard Worker    }
82*d9e8da70SAndroid Build Coastguard Worker'"
83*d9e8da70SAndroid Build Coastguard Worker
84*d9e8da70SAndroid Build Coastguard Workergh alias set --shell createMilestone "gh api --method POST repos/:owner/:repo/milestones --input - | jq '{ html_url: .html_url, state: .state, created_at: .created_at }'"
85*d9e8da70SAndroid Build Coastguard Worker
86*d9e8da70SAndroid Build Coastguard Workergh 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 }'"
87*d9e8da70SAndroid Build Coastguard Worker```
88*d9e8da70SAndroid Build Coastguard Worker
89*d9e8da70SAndroid Build Coastguard Worker### Install or update the doc generation dependencies
90*d9e8da70SAndroid Build Coastguard Worker
91*d9e8da70SAndroid Build Coastguard Worker```bash
92*d9e8da70SAndroid Build Coastguard Workerpip3 install --requirement docs/requirements.txt
93*d9e8da70SAndroid Build Coastguard Worker```
94*d9e8da70SAndroid Build Coastguard Worker
95*d9e8da70SAndroid Build Coastguard Worker## Releasing
96*d9e8da70SAndroid Build Coastguard Worker
97*d9e8da70SAndroid Build Coastguard Worker* Create a local release branch from `main`
98*d9e8da70SAndroid Build Coastguard Worker```bash
99*d9e8da70SAndroid Build Coastguard Workergit checkout main && \
100*d9e8da70SAndroid Build Coastguard Workergit pull && \
101*d9e8da70SAndroid Build Coastguard Workergit checkout -b release_{{ leak_canary.next_release }}
102*d9e8da70SAndroid Build Coastguard Worker```
103*d9e8da70SAndroid Build Coastguard Worker
104*d9e8da70SAndroid Build Coastguard Worker* Update `VERSION_NAME` in `gradle.properties` (remove `-SNAPSHOT`)
105*d9e8da70SAndroid Build Coastguard Worker```gradle
106*d9e8da70SAndroid Build Coastguard Workersed -i '' 's/VERSION_NAME={{ leak_canary.next_release }}-SNAPSHOT/VERSION_NAME={{ leak_canary.next_release }}/' gradle.properties
107*d9e8da70SAndroid Build Coastguard Worker```
108*d9e8da70SAndroid Build Coastguard Worker
109*d9e8da70SAndroid Build Coastguard Worker* Update the current version and next version in `mkdocs.yml`
110*d9e8da70SAndroid Build Coastguard Worker```bash
111*d9e8da70SAndroid Build Coastguard Workersed -i '' 's/{{ leak_canary.next_release }}/NEXT/' mkdocs.yml
112*d9e8da70SAndroid Build Coastguard Workersed -i '' 's/{{ leak_canary.release }}/{{ leak_canary.next_release }}/' mkdocs.yml
113*d9e8da70SAndroid Build Coastguard Worker```
114*d9e8da70SAndroid Build Coastguard Worker
115*d9e8da70SAndroid Build Coastguard Worker* Create the release
116*d9e8da70SAndroid Build Coastguard Worker```bash
117*d9e8da70SAndroid Build Coastguard Workergit commit -am "Prepare {{ leak_canary.next_release }} release" && \
118*d9e8da70SAndroid Build Coastguard Worker./gradlew clean && \
119*d9e8da70SAndroid Build Coastguard Worker./gradlew build && \
120*d9e8da70SAndroid Build Coastguard Workergit tag v{{ leak_canary.next_release }} && \
121*d9e8da70SAndroid Build Coastguard Workergit push origin v{{ leak_canary.next_release }} && \
122*d9e8da70SAndroid Build Coastguard Worker./gradlew publish --no-daemon --no-parallel && \
123*d9e8da70SAndroid Build Coastguard Worker./gradlew closeAndReleaseRepository && \
124*d9e8da70SAndroid Build Coastguard Worker./gradlew shark-cli:distZip
125*d9e8da70SAndroid Build Coastguard Worker```
126*d9e8da70SAndroid Build Coastguard Worker
127*d9e8da70SAndroid Build Coastguard WorkerNote: if anything goes wrong, you can manually drop the release at https://s01.oss.sonatype.org/
128*d9e8da70SAndroid Build Coastguard Worker
129*d9e8da70SAndroid Build Coastguard Worker* Merge back to main
130*d9e8da70SAndroid Build Coastguard Worker```bash
131*d9e8da70SAndroid Build Coastguard Workergit checkout main && \
132*d9e8da70SAndroid Build Coastguard Workergit pull && \
133*d9e8da70SAndroid Build Coastguard Workergit merge --no-ff release_{{ leak_canary.next_release }}
134*d9e8da70SAndroid Build Coastguard Worker```
135*d9e8da70SAndroid Build Coastguard Worker* Update `VERSION_NAME` in `gradle.properties` (increase version and add `-SNAPSHOT`)
136*d9e8da70SAndroid Build Coastguard Worker```gradle
137*d9e8da70SAndroid Build Coastguard Workersed -i '' 's/VERSION_NAME={{ leak_canary.next_release }}/VERSION_NAME=NEXT-SNAPSHOT/' gradle.properties
138*d9e8da70SAndroid Build Coastguard Worker```
139*d9e8da70SAndroid Build Coastguard Worker
140*d9e8da70SAndroid Build Coastguard Worker* Generate the Dokka docs
141*d9e8da70SAndroid Build Coastguard Worker```bash
142*d9e8da70SAndroid Build Coastguard Workerrm -rf docs/api && ./gradlew siteDokka
143*d9e8da70SAndroid Build Coastguard Worker```
144*d9e8da70SAndroid Build Coastguard Worker
145*d9e8da70SAndroid Build Coastguard Worker* Update the changelog ([commit list](https://github.com/square/leakcanary/compare/v{{ leak_canary.release }}...main))
146*d9e8da70SAndroid Build Coastguard Worker```
147*d9e8da70SAndroid Build Coastguard Workermate docs/changelog.md
148*d9e8da70SAndroid Build Coastguard Worker```
149*d9e8da70SAndroid Build Coastguard Worker
150*d9e8da70SAndroid Build Coastguard Worker* Deploy the docs locally then [open the changelog](http://127.0.0.1:8000/leakcanary/changelog/) and check everything looks good
151*d9e8da70SAndroid Build Coastguard Worker```bash
152*d9e8da70SAndroid Build Coastguard Workermkdocs serve
153*d9e8da70SAndroid Build Coastguard Worker```
154*d9e8da70SAndroid Build Coastguard Worker
155*d9e8da70SAndroid Build Coastguard Worker* Finish up the release
156*d9e8da70SAndroid Build Coastguard Worker
157*d9e8da70SAndroid Build Coastguard Worker```bash
158*d9e8da70SAndroid Build Coastguard Workergit commit -am "Prepare for next development iteration" && \
159*d9e8da70SAndroid Build Coastguard Workergit push && \
160*d9e8da70SAndroid Build Coastguard Workergh listOpenMilestones | jq '.data.repository.milestones.nodes[0].number' | xargs gh closeMilestone && \
161*d9e8da70SAndroid Build Coastguard Workerecho '{
162*d9e8da70SAndroid Build Coastguard Worker  "title": "REPLACE_WITH_NEXT_VERSION_NUMBER",
163*d9e8da70SAndroid Build Coastguard Worker  "state": "open",
164*d9e8da70SAndroid Build Coastguard Worker  "description": ""
165*d9e8da70SAndroid Build Coastguard Worker}' | gh createMilestone && \
166*d9e8da70SAndroid Build Coastguard Workermkdocs gh-deploy
167*d9e8da70SAndroid Build Coastguard Workergh release create v{{ leak_canary.next_release }} ./shark-cli/build/distributions/shark-cli-{{ leak_canary.next_release }}.zip --title v{{ leak_canary.next_release }} --notes 'See [Change Log](https://square.github.io/leakcanary/changelog)'
168*d9e8da70SAndroid Build Coastguard Worker```
169*d9e8da70SAndroid Build Coastguard Worker
170*d9e8da70SAndroid Build Coastguard Worker* Open the [v{{ leak_canary.next_release }} release](https://github.com/square/leakcanary/releases/tag/v{{ leak_canary.next_release }}) to confirm everything looks good.
171*d9e8da70SAndroid Build Coastguard Worker
172*d9e8da70SAndroid Build Coastguard Worker* Upload shark-cli to [brew](https://brew.sh/):
173*d9e8da70SAndroid Build Coastguard Worker```bash
174*d9e8da70SAndroid Build Coastguard Workerbrew bump-formula-pr --url https://github.com/square/leakcanary/releases/download/v{{ leak_canary.next_release }}/shark-cli-{{ leak_canary.next_release }}.zip leakcanary-shark
175*d9e8da70SAndroid Build Coastguard Worker```
176*d9e8da70SAndroid Build Coastguard Worker
177*d9e8da70SAndroid Build Coastguard Worker* Wait for the release to be available [on Maven Central](https://repo1.maven.org/maven2/com/squareup/leakcanary/leakcanary-android/).
178*d9e8da70SAndroid Build Coastguard Worker* Tell your friends, update all of your apps, and tweet the new release. As a nice extra touch, mention external contributions.
179