From 92546362a08f4982aa05837359f983bdfd4a2dd5 Mon Sep 17 00:00:00 2001 From: bl00dymarie Date: Sat, 18 Nov 2023 00:21:17 +0100 Subject: [PATCH] Chore: document release process for android --- RELEASE.md | 89 ++++++++++++++++++++++++++++++++--------- package.json | 5 ++- tools/update-version.js | 22 +++++----- 3 files changed, 86 insertions(+), 30 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 992b179..6c6954d 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,32 +1,81 @@ -# How to release a new version +# How to release a new app version for Android -Note: You need the release-key to bundle a release that can be uploaded to Google Play Store. +Note: You need the release-key for Android to bundle a signed release that can be uploaded and published via the Google Play Store. +A similar process for Apple requires a certificate to upload and publish the app to the App Store. More documentation on 'How to release a new app version for iOS' coming soon. -Run the release wizard that takes you through all the steps necessary to prepare a new release: +1. version updating +2. android building +3. release sharing + +## Version updating + +By running the following command, it will: + +- create a new versionName and a new higher versionCode (+1) +- create a commit including a tag named after the new release version name. ``` -npm run release -``` -This will trigger the following: -* update version number -* create a new tag for the release -* make a release commit - -To then bundle a release run the following command on your branch: - -``` -cd android && ./gradlew bundleRelease +yarn release ``` -This command creates an `app.aab` file in the folder `/android/app/build/outputs/bundle/release`. +## Android building -[More on Android App Bundle](https://blog.swmansion.com/make-your-react-native-app-3x-smaller-44c993eda2c9) +APK versus AAB -You need to manually push the created tag to Gitlab: +> Android App Bundles (AAB) include all your app’s compiled code and resources, but defer APK generation and signing to Google Play. Unlike an APK, you can't deploy an app bundle directly to a device. So, if you want to quickly test or share an APK with someone else, you should instead build an APK. + +(https://developer.android.com/build/building-cmdline) + +### APK + +To build a release apk file, run the following command: +(`cd android && ./gradlew clean && ./gradlew assembleRelease && cd ..`) ``` -git push origin +yarn build-android-apk-release ``` -Also don't forget to push your branch to Gitlab and review and merge it if ready! -Yay, done (have a scoop of ice cream, I suggest coconut 🍦)! \ No newline at end of file +It creates a new apk file named app-release.apk under ./android/app/release/ + +For signing an apk you can run this command: +(`zipalign -v -p 4 ./android/app/build/outputs/apk/release/app-release.apk ./android/app/build/outputs/apk/release/app-release_signed.apk`) + +``` +yarn sign-android-apk-release +``` + +It adds a file named "app-release_signed.apk" + +### AAB + +To build a release aab file, run: +(`cd android && ./gradlew clean && ./gradlew :app:bundleRelease && cd ..`) + +``` +yarn build-android-aab-release +``` + +It creates a new aab file named app-release.aab under ./android/app/build/outputs/bundle/release + +For signing an aab you first need to configure the base module’s build.gradle file with your app’s signing information. You can then run this command: +(`jarsigner -keystore ./android/app/drip-release-key.keystore ./android/app/build/outputs/bundle/release/app-release.aab drip-release-key`) + +``` +yarn sign-android-aab-release +``` + +## Share the release + +### Gitlab repository + +For a quick and easy way to share an apk to testers who are willing to sideload drip onto their Android phones, do this: Upload a signed apk to the Gitlab repository of the drip website under `/release` https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/tree/main/release and maybe adapt the name of the apk with a more specific name than "app-release.apk". + +### Google Play Console + +Upload a signed aab to the [Google Play Console for developers](https://play.google.com/console/) and add it to the App bundle explorer. This requires a higher versionCode and a different version name compared to previously uploaded aab or apk files. +You can decide if you want the new app version to get released for testing (internal, closed or open) or for production. Keep in mind that any track other than "internal testing" trigger an external review by Google and might take a few hours. + +### drip website + +After a new version has been published on Google Play (or F-Droid) the apk version that is downloadable directly from the [drip website](https://dripapp.org) needs to get updated as well. Therefore you upload a signed apk to the [repository](https://gitlab.com/bloodyhealth/bloodyhealth.gitlab.io/-/merge_requests/new) and adapt the name on /index.html. +Last time I checked it was [here](f3da9776b1943ffa32458e74ef86eeca98c1891c/index.html#L114). diff --git a/package.json b/package.json index c888675..2748eea 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,10 @@ "test-watch": "jest --watch test", "lint": "eslint components lib test styles db", "devtool": "adb shell input keyevent 82", - "build-android-release": "cd android && ./gradlew clean && ./gradlew assembleRelease && cd ..", + "build-android-apk-release": "cd android && ./gradlew clean && ./gradlew assembleRelease && cd ..", + "sign-android-apk-release": "zipalign -v -p 4 ./android/app/build/outputs/apk/release/app-release.apk ./android/app/build/outputs/apk/release/app-release_signed.apk", + "build-android-aab-release": "cd android && ./gradlew clean && ./gradlew :app:bundleRelease && cd ..", + "sign-android-aab-release": "jarsigner -keystore ./android/app/drip-release-key.keystore ./android/app/build/outputs/bundle/release/app-release.aab drip-release-key", "update-version": "node ./tools/bin/update-version.js", "commit-release": "node ./tools/bin/commit-release.js", "tag-release": "node ./tools/bin/tag-release.js", diff --git a/tools/update-version.js b/tools/update-version.js index d10d284..6f3b280 100755 --- a/tools/update-version.js +++ b/tools/update-version.js @@ -10,14 +10,16 @@ const fs = require('fs') module.exports = () => { return new Promise((resolve, reject) => { - const currentVersion = JSON.parse(fs.readFileSync('./package.json')).version + const currentVersionName = JSON.parse( + fs.readFileSync('./package.json') + ).version const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }) - function createTodaysVersion(attempt) { + function createTodaysVersionName(attempt) { const today = new Date() const yy = today.getFullYear() - 2000 // So it's two digits const monthString = (today.getMonth() + 1).toString() @@ -31,18 +33,20 @@ module.exports = () => { } } - let nextVersion + let nextVersionName for (let i = 0 /* letter a */; i <= 25 /* letter z */; i++) { - nextVersion = createTodaysVersion(i) - if (nextVersion !== currentVersion) break + nextVersionName = createTodaysVersionName(i) + if (nextVersionName !== currentVersionName) break } - if (nextVersion === currentVersion) { - console.error('I dont know what else to generate beyond ' + nextVersion) + if (nextVersionName === currentVersionName) { + console.error( + 'I dont know what else to generate beyond ' + nextVersionName + ) process.exit(1) } rl.question( - 'Next version will be `' + nextVersion + '`, okay? y/n ', + 'Next version name will be `' + nextVersionName + '`, okay? y/n ', async (yn) => { if (yn !== 'y' && yn !== 'Y') { reject('Release cancelled.\n') @@ -50,7 +54,7 @@ module.exports = () => { } const pkgJSON = JSON.parse(fs.readFileSync('./package.json')) - pkgJSON.version = nextVersion + pkgJSON.version = nextVersionName fs.writeFileSync('./package.json', JSON.stringify(pkgJSON, null, 2)) await ReactNativeVersion.version(