mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-15 06:56:30 +00:00
Merge pull request #871 from permissionlesstech/watch-release-0.1.0
Prepare Wear 0.1.0 reproducible release
This commit is contained in:
commit
1a0d8713e4
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -102,7 +102,7 @@ jobs:
|
||||
"$RUNNER_TEMP/attestation-subjects/BITCHAT_SHA256SUMS.unsigned"
|
||||
cp "$RUNNER_TEMP"/release-a/bitchat-android-*-unsigned.apk \
|
||||
"$RUNNER_TEMP/attestation-subjects/"
|
||||
cp "$RUNNER_TEMP/release-a/bitchat-android-release-unsigned.aab" \
|
||||
cp "$RUNNER_TEMP"/release-a/bitchat-android-*-unsigned.aab \
|
||||
"$RUNNER_TEMP/attestation-subjects/"
|
||||
|
||||
- name: Attest verified unsigned release
|
||||
|
||||
@ -11,11 +11,10 @@ The central rule is:
|
||||
No keystore or password is stored in GitHub, GitHub Actions, the repository,
|
||||
release notes, or workflow artifacts.
|
||||
|
||||
This runbook currently releases only the phone app, `com.bitchat.droid`.
|
||||
The `:wear` module is tested and dependency-locked in CI but is not included in
|
||||
the canonical release artifact set. Do not publish its development-signed
|
||||
outputs. Wear distribution requires a separate signing identity, reproducible
|
||||
artifact contract, Play listing, and maintainer runbook.
|
||||
This runbook releases both the phone and Wear OS apps under the shared Play
|
||||
application ID `com.bitchat.droid`. Wear releases use the independent version
|
||||
code range beginning at `1000000001`; every phone and Wear artifact uploaded to
|
||||
one Play listing must have a unique version code.
|
||||
|
||||
For the technical trust model and third-party verification instructions, see
|
||||
[Reproducible builds](reproducible-builds.md).
|
||||
@ -28,7 +27,7 @@ For the technical trust model and third-party verification instructions, see
|
||||
| Create tag | Maintainer machine | Signed `vX.Y.Z` tag |
|
||||
| Build twice | GitHub Actions | Two identical unsigned APK/AAB builds |
|
||||
| Promote build | GitHub Actions | Attested `verified-unsigned-release` artifact |
|
||||
| Sign | Maintainer machine | Three installable APKs and one Play upload AAB |
|
||||
| Sign | Maintainer machine | Four installable APKs and two Play upload AABs |
|
||||
| Test Play build | Play Console internal track | Play-generated APKs tested before public rollout |
|
||||
| Prepare release | Maintainer machine and GitHub draft | Checksummed public release assets |
|
||||
| Publish | GitHub Releases and Play Console | Public GitHub release and promoted Play rollout |
|
||||
@ -42,8 +41,8 @@ These are four separate signing identities:
|
||||
2. **GitHub APK signature**: lets Android install and update the APKs published
|
||||
on GitHub. Use the existing GitHub release key. Its certificate SHA-256 must
|
||||
match `BITCHAT_GITHUB_RELEASE_CERT_SHA256` in `gradle.properties`.
|
||||
3. **Play upload signature**: the maintainer signs the AAB with the Play upload
|
||||
key so Play will accept it.
|
||||
3. **Play upload signature**: the maintainer signs both AABs with the Play
|
||||
upload key so Play will accept them.
|
||||
4. **Play app signature**: Google generates device APKs and signs them with the
|
||||
separate Play app-signing key.
|
||||
|
||||
@ -119,9 +118,10 @@ a command line, in a shell profile, or in a release-notes file.
|
||||
|
||||
## 1. Prepare and approve the release commit
|
||||
|
||||
1. Update `versionCode` and `versionName` in `app/build.gradle.kts`.
|
||||
`versionCode` must be greater than every build previously uploaded to Play.
|
||||
`versionName` must match the release tag without the leading `v`.
|
||||
1. Update `versionCode` and `versionName` in `app/build.gradle.kts`. For a Wear
|
||||
release, also update them in `wear/build.gradle.kts` using the reserved Wear
|
||||
version-code range. Every code must be unique across both form factors.
|
||||
The phone `versionName` must match the release tag without the leading `v`.
|
||||
2. Merge all intended release changes into `main`.
|
||||
3. Confirm required CI checks are green.
|
||||
4. Complete the
|
||||
@ -147,6 +147,7 @@ Set shell variables for the rest of the release:
|
||||
export REPOSITORY=permissionlesstech/bitchat-android
|
||||
export TAG=vX.Y.Z
|
||||
export VERSION_CODE=NN
|
||||
export WEAR_VERSION_CODE=1000000001
|
||||
export RELEASE_DIR="release-${TAG#v}"
|
||||
```
|
||||
|
||||
@ -156,6 +157,7 @@ Confirm the source version:
|
||||
grep -nE 'versionCode|versionName' app/build.gradle.kts
|
||||
test "$(sed -n 's/.*versionName = "\([^"]*\)".*/\1/p' app/build.gradle.kts)" = "${TAG#v}"
|
||||
test "$(sed -n 's/.*versionCode = \([0-9][0-9]*\).*/\1/p' app/build.gradle.kts)" = "$VERSION_CODE"
|
||||
test "$(sed -n 's/.*versionCode = \([0-9_][0-9_]*\).*/\1/p' wear/build.gradle.kts | tr -d _)" = "$WEAR_VERSION_CODE"
|
||||
```
|
||||
|
||||
Stop if either `test` command fails.
|
||||
@ -251,6 +253,8 @@ The directory must initially contain exactly these canonical files:
|
||||
- `bitchat-android-x86-unsigned.apk`
|
||||
- `bitchat-android-x86_64-unsigned.apk`
|
||||
- `bitchat-android-release-unsigned.aab`
|
||||
- `bitchat-android-wear-unsigned.apk`
|
||||
- `bitchat-android-wear-release-unsigned.aab`
|
||||
|
||||
Verify the checksum manifest:
|
||||
|
||||
@ -328,6 +332,7 @@ It creates:
|
||||
|
||||
- `bitchat-android-arm64.apk`
|
||||
- `bitchat-android-universal.apk`
|
||||
- `bitchat-android-wear.apk`
|
||||
- `bitchat-android-x86_64.apk`
|
||||
|
||||
The unsigned armv7 and x86 APKs remain available for reproducibility, but are
|
||||
@ -337,7 +342,7 @@ If the helper stops after creating any signed file, do not continue or overwrite
|
||||
files manually. Start again in a new directory downloaded from the same
|
||||
successful workflow run.
|
||||
|
||||
## 6. Sign the Google Play AAB locally
|
||||
## 6. Sign the Google Play AABs locally
|
||||
|
||||
Set the pinned JDK and Play upload-key locations, then load the passwords:
|
||||
|
||||
@ -361,18 +366,20 @@ Run:
|
||||
tools/reproducible-builds/sign-play-bundle.sh "$RELEASE_DIR"
|
||||
```
|
||||
|
||||
The helper creates `bitchat-android-play-upload.aab`, verifies its JAR
|
||||
signature, proves that every non-signature payload entry matches the canonical
|
||||
The helper creates `bitchat-android-play-upload.aab` and
|
||||
`bitchat-android-wear-play-upload.aab`, verifies their JAR signatures, proves
|
||||
that every non-signature payload entry matches the corresponding canonical
|
||||
unsigned AAB, and updates `SHA256SUMS`.
|
||||
|
||||
This is the only file to upload to Play Console:
|
||||
These are the only files to upload to Play Console:
|
||||
|
||||
```text
|
||||
release-X.Y.Z/bitchat-android-play-upload.aab
|
||||
release-X.Y.Z/bitchat-android-wear-play-upload.aab
|
||||
```
|
||||
|
||||
Do not upload an APK or `bitchat-android-release-unsigned.aab` to Play. Do not
|
||||
open Android Studio and rebuild the bundle.
|
||||
Do not upload an APK or either `*-release-unsigned.aab` to Play. Do not open
|
||||
Android Studio and rebuild the bundles.
|
||||
|
||||
Remove passwords from the environment after both signing steps:
|
||||
|
||||
@ -394,16 +401,20 @@ tools/reproducible-builds/prepare-github-release.sh "$RELEASE_DIR"
|
||||
The helper verifies all checksums and renames the public build information and
|
||||
checksum manifests. It refuses missing or pre-existing release files.
|
||||
|
||||
The final GitHub Release must contain all 13 files below:
|
||||
The final GitHub Release must contain all 17 files below:
|
||||
|
||||
| Asset | Signed? | Why it is published |
|
||||
|---|---:|---|
|
||||
| `bitchat-android-arm64.apk` | APK release key | Primary direct-install APK |
|
||||
| `bitchat-android-universal.apk` | APK release key | Fallback direct-install APK |
|
||||
| `bitchat-android-x86_64.apk` | APK release key | x86_64 install APK |
|
||||
| Five `bitchat-android-*-unsigned.apk` files | No | Reproducibility inputs for every ABI target |
|
||||
| `bitchat-android-wear.apk` | APK release key | Wear OS direct-install APK |
|
||||
| Five phone `bitchat-android-*-unsigned.apk` files | No | Reproducibility inputs for every phone ABI target |
|
||||
| `bitchat-android-release-unsigned.aab` | No | Canonical reproducible Play input |
|
||||
| `bitchat-android-play-upload.aab` | Play upload key | Exact bundle uploaded to Play |
|
||||
| `bitchat-android-wear-unsigned.apk` | No | Canonical reproducible Wear install input |
|
||||
| `bitchat-android-wear-release-unsigned.aab` | No | Canonical reproducible Wear Play input |
|
||||
| `bitchat-android-wear-play-upload.aab` | Play upload key | Exact bundle uploaded to the Wear OS track |
|
||||
| `BITCHAT_BUILDINFO.json` | GitHub attestation | Source commit and pinned toolchain |
|
||||
| `BITCHAT_SHA256SUMS.unsigned` | GitHub attestation | Original canonical CI manifest |
|
||||
| `BITCHAT_SHA256SUMS` | No detached signature | SHA-256 for every published asset |
|
||||
@ -432,12 +443,13 @@ Create a local release-notes file. At minimum it must contain:
|
||||
## Bitchat Android vX.Y.Z
|
||||
|
||||
- Version code: NN
|
||||
- Wear version: 0.1.0 (code 1000000001)
|
||||
- Source tag: vX.Y.Z
|
||||
- GitHub APK signing certificate SHA-256: FINGERPRINT
|
||||
- Play upload certificate SHA-256: FINGERPRINT
|
||||
- Play app-signing certificate SHA-256: FINGERPRINT
|
||||
|
||||
Checksums, canonical unsigned APK/AAB inputs, the exact Play upload AAB, and
|
||||
Checksums, canonical unsigned APK/AAB inputs, the exact Play upload AABs, and
|
||||
build information are attached. See `docs/reproducible-builds.md` for public
|
||||
verification instructions.
|
||||
|
||||
@ -474,7 +486,7 @@ gh release view "$TAG" --repo "$REPOSITORY" --web
|
||||
|
||||
Keep it as a draft until the Play internal-track checks below pass.
|
||||
|
||||
## 9. Upload and test the AAB in Google Play
|
||||
## 9. Upload and test the AABs in Google Play
|
||||
|
||||
1. Open Play Console and select `com.bitchat.droid`.
|
||||
2. Open **Test and release > Testing > Internal testing**.
|
||||
@ -495,16 +507,23 @@ Keep it as a draft until the Play internal-track checks below pass.
|
||||
10. In **Setup > App integrity**, confirm the Play app-signing certificate
|
||||
SHA-256 is the value recorded in the GitHub release notes.
|
||||
|
||||
Promote this same tested Play release from internal testing to production.
|
||||
Do not rebuild or upload a second AAB for production. Use a staged production
|
||||
rollout when appropriate.
|
||||
For the initial Wear release, open **Test and release > Advanced settings >
|
||||
Form factors**, add Wear OS, upload the required Wear screenshot, and use the
|
||||
dedicated **Wear OS only** test track. Upload exactly
|
||||
`bitchat-android-wear-play-upload.aab`, confirm version code `1000000001`, and
|
||||
complete the Wear OS opt-in and review flow. Promote the already-tested Wear
|
||||
artifact on its dedicated track; do not add it to the mobile track.
|
||||
|
||||
Promote these same tested Play releases from their test tracks to their
|
||||
respective production tracks. Do not rebuild or upload replacement AABs for
|
||||
production. Use staged production rollouts when appropriate.
|
||||
|
||||
Google signs the device APKs with the Play app-signing key, so Play-delivered
|
||||
APKs will not be byte-identical to the GitHub APKs. That is expected.
|
||||
|
||||
## 10. Publish GitHub and promote Play
|
||||
|
||||
After the internal Play build passes and the GitHub draft has all 13 assets:
|
||||
After both Play test builds pass and the GitHub draft has all 17 assets:
|
||||
|
||||
```bash
|
||||
gh release edit "$TAG" \
|
||||
@ -539,7 +558,7 @@ tools/reproducible-builds/verify-github-release.sh "$TAG"
|
||||
Also verify:
|
||||
|
||||
- the GitHub release is marked **Latest**;
|
||||
- the three signed APKs install and show the expected version;
|
||||
- the four signed APKs install and show the expected version;
|
||||
- the Play listing shows the intended production version and rollout state;
|
||||
- a Play-installed build is signed by the app-signing certificate recorded in
|
||||
the release notes; and
|
||||
@ -572,10 +591,10 @@ Also verify:
|
||||
- [ ] `verified-unsigned-release` downloaded by run ID
|
||||
- [ ] Checksums, source commit, and attestations verified
|
||||
- [ ] GitHub APKs signed locally with the pinned certificate
|
||||
- [ ] Play AAB signed locally with the registered upload key
|
||||
- [ ] `BITCHAT_SHA256SUMS` verifies all 13 release assets
|
||||
- [ ] Phone and Wear Play AABs signed locally with the registered upload key
|
||||
- [ ] `BITCHAT_SHA256SUMS` verifies all 17 release assets
|
||||
- [ ] GitHub draft created with certificate fingerprints and all assets
|
||||
- [ ] Exact signed AAB uploaded to and tested on Play internal track
|
||||
- [ ] Exact signed phone and Wear AABs uploaded to and tested on their tracks
|
||||
- [ ] GitHub Release published
|
||||
- [ ] Same tested Play release promoted to production
|
||||
- [ ] Public GitHub and Play verification completed
|
||||
@ -586,3 +605,5 @@ Also verify:
|
||||
- [GitHub CLI: create a release](https://cli.github.com/manual/gh_release_create)
|
||||
- [Google Play App Signing](https://support.google.com/googleplay/android-developer/answer/9842756)
|
||||
- [Play Console App bundle explorer](https://support.google.com/googleplay/android-developer/answer/9859152)
|
||||
- [Package and distribute Wear OS apps](https://developer.android.com/training/wearables/packaging)
|
||||
- [Manage form-factor releases on dedicated tracks](https://support.google.com/googleplay/android-developer/answer/13295490)
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
# Reproducible builds
|
||||
|
||||
Bitchat's canonical phone-app release build produces byte-for-byte reproducible
|
||||
unsigned APKs and an unsigned Android App Bundle (AAB). CI builds the release
|
||||
Bitchat's canonical release build produces byte-for-byte reproducible unsigned
|
||||
phone and Wear OS APKs and Android App Bundles (AABs). CI builds the release
|
||||
twice in independent jobs and exposes a verified release artifact only when
|
||||
every canonical byte matches. The `:wear` module is tested and
|
||||
dependency-locked but is outside this phone artifact contract until a separate
|
||||
Wear release and signing process is defined.
|
||||
every canonical byte matches.
|
||||
|
||||
Signing remains local: no keystore or signing password is stored in or exposed
|
||||
to GitHub Actions. Anyone can reproduce the unsigned artifacts; maintainers
|
||||
download the verified CI output, sign the selected GitHub APKs and Play upload
|
||||
AAB locally, then manually publish those exact files.
|
||||
AABs locally, then manually publish those exact files.
|
||||
|
||||
Maintainers should use the complete
|
||||
[Android maintainer release guide](maintainer-release-guide.md) for the
|
||||
@ -71,6 +69,8 @@ The output contains:
|
||||
|
||||
- unsigned APKs for arm64, armv7, x86, x86_64, and universal installs
|
||||
- `bitchat-android-release-unsigned.aab`
|
||||
- `bitchat-android-wear-unsigned.apk`
|
||||
- `bitchat-android-wear-release-unsigned.aab`
|
||||
- `BUILDINFO.json`
|
||||
- `SHA256SUMS.unsigned`
|
||||
|
||||
@ -104,13 +104,13 @@ tools/reproducible-builds/verify-github-release.sh vX.Y.Z
|
||||
|
||||
That command:
|
||||
|
||||
1. downloads all release APKs, the AAB, build information, and checksum files;
|
||||
1. downloads all release APKs, AABs, build information, and checksum files;
|
||||
2. verifies the canonical unsigned build's GitHub artifact-attestation subjects
|
||||
against this repository;
|
||||
3. verifies `BITCHAT_SHA256SUMS`;
|
||||
4. checks that the local source commit is the release commit;
|
||||
5. rebuilds in the pinned container; and
|
||||
6. byte-compares every unsigned APK, the unsigned AAB, build information, and
|
||||
6. byte-compares every unsigned APK, both unsigned AABs, build information, and
|
||||
the unsigned checksum manifest.
|
||||
|
||||
To verify the published checksums and attestations without rebuilding:
|
||||
@ -154,8 +154,8 @@ gh attestation verify bitchat-android-universal-unsigned.apk \
|
||||
|
||||
Google Play App Signing changes the verification boundary:
|
||||
|
||||
- maintainers upload a signed AAB using the upload key;
|
||||
- Google Play generates optimized, device-specific APK splits from that AAB;
|
||||
- maintainers upload signed phone and Wear AABs using the upload key;
|
||||
- Google Play generates optimized, device-specific APK splits from those AABs;
|
||||
- Google signs the delivered APKs with the app-signing key.
|
||||
|
||||
Consequently, a Play-delivered APK is not expected to be byte-identical to the
|
||||
@ -163,8 +163,8 @@ GitHub universal APK or to a locally built APK. Use this procedure instead:
|
||||
|
||||
1. In Play Console, open **Test and release > App bundle explorer**, select the
|
||||
release/version code, and download the original app bundle if that option is
|
||||
available to your account. Compare its unsigned payload with the reproduced
|
||||
`bitchat-android-release-unsigned.aab`:
|
||||
available to your account. Compare its unsigned payload with the matching
|
||||
reproduced phone or Wear AAB:
|
||||
|
||||
```bash
|
||||
tools/reproducible-builds/compare-archive-payloads.sh \
|
||||
@ -204,9 +204,10 @@ maintainers to retain the uploaded AAB, publish its digest and provenance, and
|
||||
record the Play version code and app-signing certificate fingerprint alongside
|
||||
the release.
|
||||
|
||||
The GitHub workflow builds and attests the canonical unsigned AAB. A maintainer
|
||||
locally creates `bitchat-android-play-upload.aab` from that exact file and
|
||||
uploads it manually to Google Play.
|
||||
The GitHub workflow builds and attests both canonical unsigned AABs. A
|
||||
maintainer locally creates `bitchat-android-play-upload.aab` and
|
||||
`bitchat-android-wear-play-upload.aab` from those exact files and uploads them
|
||||
manually to Google Play.
|
||||
|
||||
## Maintainer release process
|
||||
|
||||
|
||||
@ -56,11 +56,20 @@ cd "$PROJECT_ROOT"
|
||||
|
||||
aab_source="$PROJECT_ROOT/app/build/outputs/bundle/release/app-release.aab"
|
||||
if [ ! -f "$aab_source" ]; then
|
||||
echo "error: expected release AAB not found" >&2
|
||||
echo "error: expected phone release AAB not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
cp "$aab_source" "$OUTPUT_DIR/bitchat-android-release-unsigned.aab"
|
||||
|
||||
./gradlew "${gradle_args[@]}" :wear:clean :wear:bundleRelease
|
||||
|
||||
wear_aab_source="$PROJECT_ROOT/wear/build/outputs/bundle/release/wear-release.aab"
|
||||
if [ ! -f "$wear_aab_source" ]; then
|
||||
echo "error: expected Wear release AAB not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
cp "$wear_aab_source" "$OUTPUT_DIR/bitchat-android-wear-release-unsigned.aab"
|
||||
|
||||
# AGP cannot build split APKs and an app bundle from the same intermediates.
|
||||
./gradlew "${gradle_args[@]}" :app:clean :app:assembleRelease
|
||||
|
||||
@ -81,6 +90,15 @@ for source_name in "${!apk_names[@]}"; do
|
||||
cp "$source_path" "$OUTPUT_DIR/${apk_names[$source_name]}"
|
||||
done
|
||||
|
||||
./gradlew "${gradle_args[@]}" :wear:clean :wear:assembleRelease
|
||||
|
||||
wear_apk_source="$PROJECT_ROOT/wear/build/outputs/apk/release/wear-release-unsigned.apk"
|
||||
if [ ! -f "$wear_apk_source" ]; then
|
||||
echo "error: expected Wear release APK not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
cp "$wear_apk_source" "$OUTPUT_DIR/bitchat-android-wear-unsigned.apk"
|
||||
|
||||
source_commit="${BITCHAT_SOURCE_COMMIT:-$(git -C "$PROJECT_ROOT" rev-parse HEAD)}"
|
||||
if ! [[ "$source_commit" =~ ^([0-9a-f]{40}|[0-9a-f]{64})$ ]]; then
|
||||
echo "error: source commit must be a full Git object ID" >&2
|
||||
@ -109,6 +127,7 @@ EOF
|
||||
sha256sum BUILDINFO.json
|
||||
sha256sum bitchat-android-*-unsigned.apk
|
||||
sha256sum bitchat-android-release-unsigned.aab
|
||||
sha256sum bitchat-android-wear-release-unsigned.aab
|
||||
} | sort -k2 > SHA256SUMS.unsigned
|
||||
)
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ artifacts=(
|
||||
bitchat-android-armv7-unsigned.apk
|
||||
bitchat-android-release-unsigned.aab
|
||||
bitchat-android-universal-unsigned.apk
|
||||
bitchat-android-wear-release-unsigned.aab
|
||||
bitchat-android-wear-unsigned.apk
|
||||
bitchat-android-x86-unsigned.apk
|
||||
bitchat-android-x86_64-unsigned.apk
|
||||
)
|
||||
|
||||
@ -30,6 +30,10 @@ required=(
|
||||
bitchat-android-release-unsigned.aab
|
||||
bitchat-android-universal-unsigned.apk
|
||||
bitchat-android-universal.apk
|
||||
bitchat-android-wear-play-upload.aab
|
||||
bitchat-android-wear-release-unsigned.aab
|
||||
bitchat-android-wear-unsigned.apk
|
||||
bitchat-android-wear.apk
|
||||
bitchat-android-x86-unsigned.apk
|
||||
bitchat-android-x86_64-unsigned.apk
|
||||
bitchat-android-x86_64.apk
|
||||
@ -53,6 +57,8 @@ for artifact_path in "$RELEASE_DIR"/*; do
|
||||
bitchat-android-armv7-unsigned.apk|\
|
||||
bitchat-android-play-upload.aab|bitchat-android-release-unsigned.aab|\
|
||||
bitchat-android-universal-unsigned.apk|bitchat-android-universal.apk|\
|
||||
bitchat-android-wear-play-upload.aab|bitchat-android-wear-release-unsigned.aab|\
|
||||
bitchat-android-wear-unsigned.apk|bitchat-android-wear.apk|\
|
||||
bitchat-android-x86-unsigned.apk|\
|
||||
bitchat-android-x86_64-unsigned.apk|bitchat-android-x86_64.apk)
|
||||
;;
|
||||
|
||||
@ -48,13 +48,6 @@ fi
|
||||
"${SHA256[@]}" -c SHA256SUMS.unsigned
|
||||
)
|
||||
|
||||
UNSIGNED_AAB="$RELEASE_DIR/bitchat-android-release-unsigned.aab"
|
||||
SIGNED_AAB="$RELEASE_DIR/bitchat-android-play-upload.aab"
|
||||
if [ -e "$SIGNED_AAB" ]; then
|
||||
echo "error: signed Play upload AAB already exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TEMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TEMP_DIR"' EXIT
|
||||
STOREPASS_FILE="$TEMP_DIR/storepass"
|
||||
@ -63,17 +56,40 @@ printf '%s\n' "$BITCHAT_PLAY_KEYSTORE_PASSWORD" > "$STOREPASS_FILE"
|
||||
printf '%s\n' "$BITCHAT_PLAY_KEY_PASSWORD" > "$KEYPASS_FILE"
|
||||
chmod 600 "$STOREPASS_FILE" "$KEYPASS_FILE"
|
||||
|
||||
"$JARSIGNER" \
|
||||
-keystore "$KEYSTORE" \
|
||||
-storepass:file "$STOREPASS_FILE" \
|
||||
-keypass:file "$KEYPASS_FILE" \
|
||||
-digestalg SHA-256 \
|
||||
-signedjar "$SIGNED_AAB" \
|
||||
"$UNSIGNED_AAB" \
|
||||
"$BITCHAT_PLAY_UPLOAD_KEY_ALIAS"
|
||||
unsigned_names=(
|
||||
"bitchat-android-release-unsigned.aab"
|
||||
"bitchat-android-wear-release-unsigned.aab"
|
||||
)
|
||||
signed_names=(
|
||||
"bitchat-android-play-upload.aab"
|
||||
"bitchat-android-wear-play-upload.aab"
|
||||
)
|
||||
|
||||
"$JARSIGNER" -verify "$SIGNED_AAB" >/dev/null
|
||||
"$SCRIPT_DIR/compare-archive-payloads.sh" "$UNSIGNED_AAB" "$SIGNED_AAB"
|
||||
for ((index = 0; index < ${#unsigned_names[@]}; index++)); do
|
||||
unsigned_aab="$RELEASE_DIR/${unsigned_names[$index]}"
|
||||
signed_aab="$RELEASE_DIR/${signed_names[$index]}"
|
||||
|
||||
if [ ! -f "$unsigned_aab" ]; then
|
||||
echo "error: unsigned Play AAB not found: ${unsigned_names[$index]}" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -e "$signed_aab" ]; then
|
||||
echo "error: signed Play upload AAB already exists: ${signed_names[$index]}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$JARSIGNER" \
|
||||
-keystore "$KEYSTORE" \
|
||||
-storepass:file "$STOREPASS_FILE" \
|
||||
-keypass:file "$KEYPASS_FILE" \
|
||||
-digestalg SHA-256 \
|
||||
-signedjar "$signed_aab" \
|
||||
"$unsigned_aab" \
|
||||
"$BITCHAT_PLAY_UPLOAD_KEY_ALIAS"
|
||||
|
||||
"$JARSIGNER" -verify "$signed_aab" >/dev/null
|
||||
"$SCRIPT_DIR/compare-archive-payloads.sh" "$unsigned_aab" "$signed_aab"
|
||||
done
|
||||
|
||||
(
|
||||
cd "$RELEASE_DIR"
|
||||
@ -86,4 +102,4 @@ chmod 600 "$STOREPASS_FILE" "$KEYPASS_FILE"
|
||||
} | sort -k2 > SHA256SUMS
|
||||
)
|
||||
|
||||
echo "Verified unsigned AAB was signed locally with the Play upload key and checksummed."
|
||||
echo "Verified unsigned phone and Wear AABs were signed locally with the Play upload key and checksummed."
|
||||
|
||||
@ -68,11 +68,13 @@ export BITCHAT_GITHUB_KEY_PASSWORD
|
||||
unsigned_names=(
|
||||
"bitchat-android-arm64-unsigned.apk"
|
||||
"bitchat-android-universal-unsigned.apk"
|
||||
"bitchat-android-wear-unsigned.apk"
|
||||
"bitchat-android-x86_64-unsigned.apk"
|
||||
)
|
||||
signed_names=(
|
||||
"bitchat-android-arm64.apk"
|
||||
"bitchat-android-universal.apk"
|
||||
"bitchat-android-wear.apk"
|
||||
"bitchat-android-x86_64.apk"
|
||||
)
|
||||
|
||||
|
||||
@ -50,6 +50,8 @@ attested_artifacts=(
|
||||
bitchat-android-armv7-unsigned.apk
|
||||
bitchat-android-release-unsigned.aab
|
||||
bitchat-android-universal-unsigned.apk
|
||||
bitchat-android-wear-release-unsigned.aab
|
||||
bitchat-android-wear-unsigned.apk
|
||||
bitchat-android-x86-unsigned.apk
|
||||
bitchat-android-x86_64-unsigned.apk
|
||||
)
|
||||
|
||||
@ -9,14 +9,17 @@ plugins {
|
||||
android {
|
||||
namespace = "com.bitchat.watch"
|
||||
compileSdk = libs.versions.compileSdk.get().toInt()
|
||||
buildToolsVersion = libs.versions.buildTools.get()
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.bitchat.watch"
|
||||
applicationId = "com.bitchat.droid"
|
||||
minSdk = 33 // Wear OS 4 (Pixel Watch 1+): the S+ Bluetooth permissions the app
|
||||
// declares only exist from API 31, and API 30 would additionally require location
|
||||
// for BLE scan results, which the app deliberately refuses.
|
||||
targetSdk = libs.versions.targetSdk.get().toInt()
|
||||
versionCode = 1
|
||||
// Wear releases use a separate high range because Play requires every artifact in
|
||||
// one application ID to have a unique version code across all form factors.
|
||||
versionCode = 1_000_000_001
|
||||
versionName = "0.1.0"
|
||||
|
||||
vectorDrawables {
|
||||
@ -24,6 +27,11 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
includeInBundle = false
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
@ -32,9 +40,9 @@ android {
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
// Sign with the debug key so release builds can be installed over the
|
||||
// debug app during development (same signature = seamless upgrade).
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
vcsInfo {
|
||||
include = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +166,7 @@ tasks.matching { it.name.contains("UnitTest", ignoreCase = true) }.configureEach
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(21)
|
||||
compilerOptions {
|
||||
jvmTarget.set(JvmTarget.JVM_11)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user