diff --git a/docs/howto/alpha.md b/docs/howto/alpha.md new file mode 100644 index 0000000000..db33d0a95e --- /dev/null +++ b/docs/howto/alpha.md @@ -0,0 +1,48 @@ +# Joining the alpha channel + +If you're actively developing the app, you should join the [alpha +channel](../release.md#terminology) so that when we make an alpha +release you get it on your normal devices you use daily. This means +you'll see any regressions we have, so you can help find and fix them +before they go out wider. + +* **Android**: A maintainer will add you to the list, and then give + you a link you'll use to confirm. + + (Maintainer: see [Release > Testing > Internal testing > + Testers][play-internal-testers] in the Play Console.) + +* **iOS**: A maintainer will send you an invite to join App Store Connect. + Then after you join, there's a second step to join the list of users that + get alpha updates. + + (Maintainer: that list is confusingly labeled in the UI as simply + ["App Store Connect Users"][] — don't be fooled. Confirm the + person is on it; if not, see the plus-sign icon next to the + "Testers" heading, which lets you send an invite for that step.) + +[join-beta]: https://github.com/zulip/zulip-mobile#using-the-beta +[play-internal-testers]: https://play.google.com/console/developers/8060868091387311598/app/4976350040864490411/tracks/internal-testing?tab=testers +["App Store Connect Users"]: https://appstoreconnect.apple.com/apps/1203036395/testflight/groups/d246e92d-76a2-4b3e-8293-347a1a6e27ab + + +## Joining the beta channel + +Historically we also used a [beta channel](../release.md#terminology). +Our current practice is that the beta channel is nearly equivalent to +the prod channel, though, so there's little effect to be had from +joining the beta. + +Here are the instructions for joining the beta channel, mostly for the +purpose of internal notes in case we decide to revive the use of it: + +* Android: install the app, then just + [join the testing program](https://play.google.com/apps/testing/com.zulipmobile/) + on Google Play. + * Or if you don't use Google Play, you can [download an + APK](https://github.com/zulip/zulip-flutter/releases/); the latest + release on GitHub (including "pre-releases") is the current beta. + +* iOS: install [TestFlight](https://developer.apple.com/testflight/testers/), + then open [this public invitation link](https://testflight.apple.com/join/ZuzqwXGf) + on your device. diff --git a/docs/release.md b/docs/release.md index 6fd5dab8d6..24734fd427 100644 --- a/docs/release.md +++ b/docs/release.md @@ -1,17 +1,10 @@ # Making releases -## NOTE: This document is out of date. +This doc explains how to make a release of the Zulip mobile app to the +iOS App Store, to the Google Play Store, and as APKs on the web. -Now that this is the main Zulip mobile app, -the actual release process is roughly a hybrid of the steps below -and those from the legacy app's release instructions. - -The steps below have been updated up through "Promote to beta". -After that, announce the release following a hybrid of the two docs; -and release to production following the other doc. - -Revising this further into a single coherent set of instructions -is an open TODO. +If you're reading this page for the first time, see the sections on +[terminology](#terminology) and [setup](#setup) below. ## Prepare source tree @@ -129,7 +122,7 @@ is an open TODO. * Upload both the AAB and the APK. - * Check the box "This is a pre-release". + * Check the box "Set as a pre-release". * iOS via TestFlight: @@ -148,7 +141,7 @@ is an open TODO. * Also submit for App Store review, to save latency in the prod rollout: - * In App Store Connect for the app, [go to the "App Store" + * In App Store Connect for the app, [go to the "Distribution" tab][asc-main], and hit the "+" button next to "iOS App" at the top of the left sidebar. Enter the version number. This creates a new draft listing. @@ -166,10 +159,7 @@ is an open TODO. this version"). * Back at the top, hit "Save" and then "Add for Review", and hit - "Continue" in the resulting dialog box. - - * In the resulting "Confirm Submission" page, hit - "Submit to App Review". + "Submit for Review" in the resulting modal sidebar. * The draft listing should enter state "Waiting for Review". From here, it typically takes a day or so to get a result from the @@ -177,19 +167,67 @@ is an open TODO. button to roll it out. [asc-external]: https://appstoreconnect.apple.com/apps/1203036395/testflight/groups/1bf18c25-da12-4bad-8384-9dd872ce447f -[asc-main]: https://appstoreconnect.apple.com/apps/1203036395/appstore/info +[asc-main]: https://appstoreconnect.apple.com/apps/1203036395/distribution/info + + +## Release to production + +Historically we would wait a couple of days after sending to beta +before sending to production. More recently (since 2025) we've +been sending a typical release to production promptly after beta. +Discussion thread: [#mobile-team > mobile releases @ 💬](https://chat.zulip.org/#narrow/channel/243-mobile-team/topic/mobile.20releases/near/2218205) + + +* Android via Play Store: + + * In the Play Console, go to [Release > Testing > + Open testing][play-open-testing]. + + * Under the release you want to promote, choose "Promote release > + Production". + + * Under "Staged roll-out", set 100% as the roll-out percentage. + + * Occasionally we start with a smaller percentage. In that case, + remember to come back later to make a 100% rollout. + + * Confirm and send to Google for review. + +[play-open-testing]: https://play.google.com/console/developers/8060868091387311598/app/4976350040864490411/tracks/open-testing + + +* Android via GitHub: + + * Edit the release [on GitHub][gh-releases]. Uncheck + "Set as a pre-release", and check "Set as the latest release". + +[gh-releases]: https://github.com/zulip/zulip-flutter/releases + + +* iOS via App Store: + + * (This assumes the new version was submitted for App Store review + at the time of the beta rollout, and accepted. See beta steps + above for how to submit it.) + + * In App Store Connect for the app, go to [Distribution > iOS App > + (the draft release)][asc-inflight]. + + * Hit the big blue button at top right to release to the App Store. + +[asc-inflight]: https://appstoreconnect.apple.com/apps/1203036395/appstore/ios/version/inflight ## Announce * Announce the updated beta in - [#announce > mobile beta][releases-thread]. + [#announce > mobile releases][releases-thread]. For release notes, use `tools/format-changelog czo`. -[releases-thread]: https://chat.zulip.org/#narrow/stream/1-announce/topic/mobile.20beta +[releases-thread]: https://chat.zulip.org/#narrow/stream/1-announce/topic/mobile.20releases -* For any fixed issues that were tagged "beta feedback", or otherwise +* For any fixed issues that were tagged "user feedback", or otherwise had people outside the mobile team specifically interested in them, follow up with the requesters: post on the relevant thread (in GitHub or Zulip) and @-mention the individuals who asked for the @@ -231,10 +269,118 @@ Steps specific to this type of release are: (with the correct version number), and push. +## Security releases + +Very occasionally, we find a security vulnerability in the app. +When a release fixes a vulnerability which isn't already public, +we follow a variation of the process above. + +The goal is to get the update onto most users' phones almost before +the issue is disclosed, minimizing the window where the issue is +public and users are still vulnerable. + +### Preparing commit + +* Write the fixes on a private branch, but don't push to the main repo (or + other public repos.) + +* Prepare and QA the commit as usual. We'll be skipping the beta phase, so + be especially diligent with the QA, and choosy in what commits to include. + Definitely make it a stable release, with only hand-picked changes on top + of the last release. + +* Tag the commit, but don't push it yet. + +### Android prep + +* Build and upload to Google Play, but release only to alpha for now. + Repeat manual QA with the alpha. + +* Also send for Google's review to promote to both beta and + production, but adjust settings so that it will wait to roll out + until we later hit a button saying so. + + (The last time we needed this procedure was years ago, before the + Play Store had blocking reviews on updates, so we've not yet + actually done this step in practice.) + +* Don't upload to GitHub yet. + +### iOS prep + +* Build and upload to App Store Connect, but release only to alpha for now. + Repeat manual QA with the alpha. + +* Follow the steps to release to production, with one change: in the draft + listing, find the option for "Manually release this version", and select it. + +### Release + +* Wait for Apple's review; on success, the app will enter state "Pending + Developer Release". (On failure, try to fix the issue, then resubmit.) + Similarly wait for Google's review. + +* Now release the app to both the App Store and the Play Store. + +* Also now submit to TestFlight, for beta users on iOS. + Wait for that to go out before discussing further in public. + +### Followup + +* Wait for the release to be approved for TestFlight. + (On failure, try to fix, then resubmit.) + +* Push the tagged commit, and also push the corresponding changes to main. + +* Upload the APKs to GitHub as usual. + +* Discuss freely. + + +
+ ## One-time or annual setup -* You'll need the Google Play upload key. The setup is similar to - what we use for the React Native app, but the key is a fresh one. +### Prepare Android + +You'll need the Google Play upload key. +This key also serves as the [app signing key][] for +the APK and AAB files we publish directly via GitHub releases. +As the linked upstream doc explains, this is a highly sensitive secret +which it's very important to handle securely. + +[app signing key]: https://developer.android.com/studio/publish/app-signing#secure_key + +(This setup is similar to what we used for the legacy mobile app, +but the key is a fresh one.) + +* Get the keystore file, and the keystore properties file. + An existing/previous release manager can send these to you, + encrypted to your PGP key. + + * Never make an unencrypted version visible to the network or to a + cloud service (including Zulip). + +* Put the release-signing keystore, PGP-encrypted to yourself, + at `android/release.keystore.pgp`. + + * Don't leave an unencrypted version on disk, except temporarily. + The script `tools/checkout-keystore` will help manage this; see + `tools/checkout-keystore --help` and release instructions above. + +* Put the keystore properties file at + `android/release-keystore.properties`. + It looks like this (passwords redacted): + +``` +storeFile=release.keystore +keyAlias=zulip-mobile +storePassword=***** +keyPassword=***** +``` + + +### Prepare iOS * You'll need an "Apple Distribution" certificate and its key, and also an iOS "provisioning profile" that refers to that @@ -253,3 +399,66 @@ Steps specific to this type of release are: