|
| 1 | +Building and Releasing Session |
| 2 | +============================== |
| 3 | + |
| 4 | +## Building |
| 5 | + |
| 6 | +### Dependencies |
| 7 | + |
| 8 | +Session uses standard Gradle/Android project structure. |
| 9 | + |
| 10 | +Ensure the following are set up on your machine: |
| 11 | + |
| 12 | +- **Android Studio** (recommended) or the Android SDK command-line tools |
| 13 | +- **JDK 17** or later |
| 14 | +- The following packages installed via the Android SDK Manager: |
| 15 | + - Android SDK Build Tools (see `buildToolsVersion` in `build.gradle`) |
| 16 | + - SDK Platform matching the `compileSdkVersion` in `build.gradle` |
| 17 | + - Android Support Repository |
| 18 | + |
| 19 | +### Setting up and building in Android Studio |
| 20 | + |
| 21 | +[Android Studio](https://developer.android.com/studio) is the recommended development environment. |
| 22 | + |
| 23 | +1. Open Android Studio. On a new installation the Quickstart panel will appear. If you have |
| 24 | + open projects, close them via **File > Close Project** to return to the Quickstart panel. |
| 25 | +2. Choose **Get from Version Control** and paste the repository URL: |
| 26 | + `https://github.com/session-foundation/session-android.git` |
| 27 | +3. The default Gradle sync and build configuration should work out of the box. |
| 28 | + |
| 29 | +### Build flavors |
| 30 | + |
| 31 | +The project has three product flavors: |
| 32 | + |
| 33 | +| Flavor | Description | |
| 34 | +|----------|----------------------------------------------| |
| 35 | +| `play` | Google Play Store build | |
| 36 | +| `fdroid` | F-Droid build (no proprietary dependencies) | |
| 37 | +| `huawei` | Huawei AppGallery build (HMS push) | |
| 38 | + |
| 39 | +To build a specific flavor manually, run the corresponding Gradle task, for example: |
| 40 | + |
| 41 | +```sh |
| 42 | +./gradlew assemblePlayDebug |
| 43 | +./gradlew assembleFdroidDebug |
| 44 | +./gradlew assembleHuaweiDebug -Phuawei |
| 45 | +``` |
| 46 | + |
| 47 | +The `-Phuawei` flag is required for Huawei builds to include the HMS dependencies. If building |
| 48 | +in Android Studio, add `-Phuawei` under |
| 49 | +**Preferences > Build, Execution, Deployment > Gradle-Android Compiler > Command-line Options**. |
| 50 | + |
| 51 | +### Building a signed release APK manually |
| 52 | + |
| 53 | +The build is standard Gradle — `build-and-release.py` is a convenience wrapper and is not |
| 54 | +required if you only need to produce a signed APK. Pass the signing credentials directly as |
| 55 | +Gradle properties: |
| 56 | + |
| 57 | +```sh |
| 58 | +./gradlew \ |
| 59 | + -PSESSION_STORE_FILE='/path/to/keystore.jks' \ |
| 60 | + -PSESSION_STORE_PASSWORD='<keystore-password>' \ |
| 61 | + -PSESSION_KEY_ALIAS='<key-alias>' \ |
| 62 | + -PSESSION_KEY_PASSWORD='<key-password>' \ |
| 63 | + assembleFdroidRelease |
| 64 | +``` |
| 65 | + |
| 66 | +The keystore file can be recreated from `release-creds.toml` — the `keystore` field in each |
| 67 | +section is the JKS file base64-encoded, so it can be decoded back to a `.jks` file using any |
| 68 | +standard base64 tool. |
| 69 | + |
| 70 | +--- |
| 71 | + |
| 72 | +## Release process |
| 73 | + |
| 74 | +> **Quick checklist** |
| 75 | +> |
| 76 | +> 1. [ ] Create a `release/MAJOR.MINOR.PATCH` branch from `master` |
| 77 | +> 2. [ ] Merge `dev` into the release branch (full release), or cherry-pick the relevant patch commits |
| 78 | +> 3. [ ] Bump the version code |
| 79 | +> 4. [ ] Create a GitHub release draft for the version (e.g. `1.23.4`) in this repository |
| 80 | +> 5. [ ] Obtain `release-creds.toml` from a project maintainer and place it in the project root |
| 81 | +> 6. [ ] Run `./scripts/build-and-release.py` from the release branch |
| 82 | +> 7. [ ] Upload the AAB bundle to the Play Store |
| 83 | +> 8. [ ] Review and merge the automated F-Droid PR in `session-foundation/session-fdroid` |
| 84 | +> 9. [ ] Review and publish the GitHub release draft |
| 85 | +
|
| 86 | +Steps 6–9 are explained in detail below. Steps 4 and 5 must be completed **before** running |
| 87 | +the script — if no release draft exists the artifact upload is silently skipped, and without |
| 88 | +the credentials file the script will exit immediately. |
| 89 | + |
| 90 | +### Branching strategy |
| 91 | + |
| 92 | +| Branch | Purpose | |
| 93 | +|--------|---------| |
| 94 | +| `master` | Represents production — always reflects what is live | |
| 95 | +| `dev` | Integration branch for ongoing development | |
| 96 | +| `release/MAJOR.MINOR.PATCH` | Short-lived branch used to prepare and build a release | |
| 97 | + |
| 98 | +To start a release: |
| 99 | + |
| 100 | +```sh |
| 101 | +git checkout master |
| 102 | +git checkout -b release/1.23.4 |
| 103 | +``` |
| 104 | + |
| 105 | +For a **full release**, merge `dev` into the release branch: |
| 106 | + |
| 107 | +```sh |
| 108 | +git merge dev |
| 109 | +``` |
| 110 | + |
| 111 | +For a **patch release**, cherry-pick only the relevant commits: |
| 112 | + |
| 113 | +```sh |
| 114 | +git cherry-pick <commit>... |
| 115 | +``` |
| 116 | + |
| 117 | +Once the branch is ready, bump the version code in `app/build.gradle` (the `versionCode` and |
| 118 | +`versionName` fields), commit the change, then proceed with the steps below. |
| 119 | + |
| 120 | +### Prerequisites |
| 121 | + |
| 122 | +- [**uv**](https://docs.astral.sh/uv/) — the script uses `uv run` to manage its Python |
| 123 | + dependencies (`fdroidserver`) automatically |
| 124 | +- [**gh**](https://cli.github.com/) — GitHub CLI, authenticated and with access to |
| 125 | + `session-foundation/session-android` and `session-foundation/session-fdroid` |
| 126 | +- **Android SDK** — either `ANDROID_HOME` set in the environment, or `sdk.dir` defined in |
| 127 | + `local.properties`. This would have been set up for you if you have opened the project in Android Studio. |
| 128 | + |
| 129 | +### Credentials file |
| 130 | + |
| 131 | +The script requires a `release-creds.toml` file in the project root. This file is not |
| 132 | +committed to the repository — ask a project maintainer for it. Its structure is: |
| 133 | + |
| 134 | +```toml |
| 135 | +[build.play] |
| 136 | +keystore = "<base64-encoded JKS keystore>" |
| 137 | +keystore_password = "<password>" |
| 138 | +key_alias = "<alias>" |
| 139 | +key_password = "<password>" |
| 140 | + |
| 141 | +[build.huawei] |
| 142 | +keystore = "<base64-encoded JKS keystore>" |
| 143 | +keystore_password = "<password>" |
| 144 | +key_alias = "<alias>" |
| 145 | +key_password = "<password>" |
| 146 | + |
| 147 | +[fdroid] |
| 148 | +keystore = "<base64-encoded PKCS12 keystore>" |
| 149 | +keystore_password = "<password>" |
| 150 | +key_alias = "<alias>" |
| 151 | +key_password = "<password>" |
| 152 | +``` |
| 153 | + |
| 154 | +### Running the script |
| 155 | + |
| 156 | +From the project root, run: |
| 157 | + |
| 158 | +```sh |
| 159 | +./scripts/build-and-release.py |
| 160 | +``` |
| 161 | + |
| 162 | +This performs a full build and release. The built artifacts are placed under where they suppose |
| 163 | +to be according to standard Android project layout. |
| 164 | + |
| 165 | +#### Options |
| 166 | + |
| 167 | +| Flag | Description | |
| 168 | +|-----------------|-----------------------------------------------------------------------------| |
| 169 | +| `--build-only` | Build all flavors but skip the F-Droid PR and GitHub release upload steps | |
| 170 | +| `--build-type` | Gradle build type to use (default: `release`) | |
| 171 | + |
| 172 | +For example, to perform builds without publishing anything: |
| 173 | + |
| 174 | +```sh |
| 175 | +./scripts/build-and-release.py --build-only |
| 176 | +``` |
| 177 | + |
| 178 | +### What the script does in detail |
| 179 | + |
| 180 | +1. **Play build** — assembles split APKs and an AAB bundle for the `play` flavor, signed with |
| 181 | + the Play keystore. |
| 182 | +2. **F-Droid build** — assembles split APKs for the `fdroid` flavor. |
| 183 | +3. **F-Droid repo update** (skipped with `--build-only`) — see [FDROID_RELEASE.md](FDROID_RELEASE.md) |
| 184 | + for a full explanation of the architecture and manual steps: |
| 185 | + - Clones `session-foundation/session-fdroid` into `build/fdroidrepo` if not already present. |
| 186 | + - Creates a `release/<version>` branch. |
| 187 | + - Copies the new APKs into the repo, pruning old versions (keeps the latest |
| 188 | + four releases). |
| 189 | + - Regenerates repository metadata using `fdroid update`. |
| 190 | + - Commits and opens a pull request against `master` for human review and merge. |
| 191 | +4. **Huawei build** — assembles a universal APK for the `huawei` flavor. |
| 192 | +5. **GitHub release upload** (skipped with `--build-only`): |
| 193 | + - Looks for a release draft in this repository matching the version name. |
| 194 | + - If found, uploads the Play split APKs, the AAB bundle, and the Huawei APKs to it. |
| 195 | + - If no draft exists, this step is skipped (no error). |
| 196 | + |
| 197 | +--- |
| 198 | + |
| 199 | +## Contributing code |
| 200 | + |
| 201 | +Code contributions should be submitted via GitHub as pull requests from feature branches, |
| 202 | +[as explained here](https://help.github.com/articles/using-pull-requests). |
0 commit comments