Skip to content

Commit ea7a4c4

Browse files
authored
Merge pull request #13 from andre487/add-aab-build
Add AAB build
2 parents a7f119d + 1b22dc2 commit ea7a4c4

3 files changed

Lines changed: 165 additions & 8 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Release APKs
1+
name: Release Android artifacts
22

33
on:
44
push:
@@ -14,7 +14,7 @@ concurrency:
1414

1515
jobs:
1616
release:
17-
name: Build and publish signed APKs
17+
name: Build and publish signed Android artifacts
1818
runs-on: ubuntu-latest
1919
timeout-minutes: 90
2020
steps:
@@ -88,11 +88,18 @@ jobs:
8888
MEGAPROXY_GIT_COMMIT: ${{ github.sha }}
8989
run: ./scripts/build-release-apks.sh
9090

91+
- name: Build signed App Bundle
92+
env:
93+
MEGAPROXY_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
94+
MEGAPROXY_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
95+
MEGAPROXY_GIT_COMMIT: ${{ github.sha }}
96+
run: ./scripts/build-release-bundle.sh
97+
9198
- name: Publish GitHub Release
9299
env:
93100
GH_TOKEN: ${{ github.token }}
94101
run: |
95-
assets=(dist/release/*.apk dist/release/SHA256SUMS)
102+
assets=(dist/release/*.apk dist/release/*.aab dist/release/SHA256SUMS)
96103
if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
97104
gh release upload "$GITHUB_REF_NAME" "${assets[@]}" \
98105
--repo "$GITHUB_REPOSITORY" \

‎README.md‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,15 +288,18 @@ universal APK used for reproducible F-Droid verification:
288288

289289
```shell
290290
./scripts/build-release-apks.sh
291+
./scripts/build-release-bundle.sh
291292
```
292293

293-
The script reads its default signing key from `$HOME/AndroidApkKey` and its password from
294+
The scripts read the default signing key from `$HOME/AndroidApkKey` and its password from
294295
`$HOME/.my-tokens/android-key-password`. Override these with `MEGAPROXY_KEYSTORE_PATH`,
295-
`MEGAPROXY_KEY_ALIAS`, `MEGAPROXY_KEY_PASSWORD_FILE`, and `MEGAPROXY_KEY_PASSWORD`. Outputs and
296-
`SHA256SUMS` are written to `dist/release`.
296+
`MEGAPROXY_KEY_ALIAS`, `MEGAPROXY_KEY_PASSWORD_FILE`, and `MEGAPROXY_KEY_PASSWORD`. The signed
297+
ABI-specific and universal APKs, the signed universal App Bundle, and `SHA256SUMS` are
298+
written to `dist/release`. The App Bundle contains every supported ABI; app stores generate and
299+
serve optimized device-specific APK splits from it.
297300

298-
Pushing a version tag runs the GitHub release workflow, builds and verifies every APK, and attaches
299-
the artifacts to a GitHub Release. The tag must match `versionName` exactly:
301+
Pushing a version tag runs the GitHub release workflow, builds and verifies every APK and the App
302+
Bundle, and attaches the artifacts to a GitHub Release. The tag must match `versionName` exactly:
300303

301304
```shell
302305
git tag v0.0.4

‎scripts/build-release-bundle.sh‎

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
project_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5+
6+
if [[ -f "$HOME/.zshrc.extra" ]]; then
7+
source "$HOME/.zshrc.extra"
8+
fi
9+
10+
: "${JAVA_HOME:=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home}"
11+
: "${ANDROID_HOME:=$HOME/Library/Android/sdk}"
12+
: "${ANDROID_NDK_HOME:=$ANDROID_HOME/ndk/29.0.14206865}"
13+
: "${MEGAPROXY_KEYSTORE_PATH:=$HOME/AndroidApkKey}"
14+
: "${MEGAPROXY_KEY_PASSWORD_FILE:=$HOME/.my-tokens/android-key-password}"
15+
: "${MEGAPROXY_KEY_ALIAS:=key0}"
16+
: "${MEGAPROXY_RELEASE_DIR:=$project_dir/dist/release}"
17+
: "${MEGAPROXY_EXPECTED_CERT_SHA256:=8a014a2a558a75b5f900ee0c33cd50f24b7432734912406699fc08866747f822}"
18+
19+
export JAVA_HOME ANDROID_HOME ANDROID_NDK_HOME
20+
export PATH="$JAVA_HOME/bin:$HOME/go/bin:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH"
21+
22+
for command in go gomobile java jarsigner keytool unzip; do
23+
if ! command -v "$command" >/dev/null 2>&1; then
24+
echo "Required command is unavailable: $command" >&2
25+
exit 1
26+
fi
27+
done
28+
29+
if [[ ! -x "$project_dir/gradlew" ]]; then
30+
echo "Gradle wrapper is missing or not executable: $project_dir/gradlew" >&2
31+
exit 1
32+
fi
33+
if [[ ! -f "$MEGAPROXY_KEYSTORE_PATH" ]]; then
34+
echo "Release keystore is missing: $MEGAPROXY_KEYSTORE_PATH" >&2
35+
exit 1
36+
fi
37+
if [[ ! -f "$MEGAPROXY_KEY_PASSWORD_FILE" ]]; then
38+
echo "Keystore password file is missing: $MEGAPROXY_KEY_PASSWORD_FILE" >&2
39+
exit 1
40+
fi
41+
if [[ ! -d "$ANDROID_NDK_HOME" ]]; then
42+
echo "Android NDK is missing: $ANDROID_NDK_HOME" >&2
43+
exit 1
44+
fi
45+
46+
keystore_password="$(<"$MEGAPROXY_KEY_PASSWORD_FILE")"
47+
if [[ -z "$keystore_password" ]]; then
48+
echo "Keystore password file is empty" >&2
49+
exit 1
50+
fi
51+
: "${MEGAPROXY_KEY_PASSWORD:=$keystore_password}"
52+
53+
keytool -list \
54+
-keystore "$MEGAPROXY_KEYSTORE_PATH" \
55+
-storepass:file "$MEGAPROXY_KEY_PASSWORD_FILE" \
56+
-alias "$MEGAPROXY_KEY_ALIAS" >/dev/null
57+
58+
mkdir -p "$MEGAPROXY_RELEASE_DIR" "$project_dir/app/libs"
59+
find "$MEGAPROXY_RELEASE_DIR" -maxdepth 1 -type f -name 'mega-proxy.aab' -delete
60+
61+
temporary_dir="$(mktemp -d "${TMPDIR:-/tmp}/megaproxy-bundle.XXXXXX")"
62+
original_aar="$project_dir/app/libs/megaproxy.aar"
63+
had_original_aar=false
64+
if [[ -f "$original_aar" ]]; then
65+
cp "$original_aar" "$temporary_dir/megaproxy.aar"
66+
had_original_aar=true
67+
fi
68+
restore_workspace() {
69+
if [[ "$had_original_aar" == true ]]; then
70+
cp "$temporary_dir/megaproxy.aar" "$original_aar"
71+
else
72+
rm -f "$original_aar"
73+
fi
74+
rm -rf "$temporary_dir"
75+
}
76+
trap restore_workspace EXIT
77+
78+
export MEGAPROXY_KEYSTORE_PATH
79+
export MEGAPROXY_KEYSTORE_PASSWORD="$keystore_password"
80+
export MEGAPROXY_KEY_ALIAS
81+
export MEGAPROXY_KEY_PASSWORD
82+
83+
echo "Building universal native AAR for the App Bundle"
84+
(
85+
cd "$project_dir/native"
86+
gomobile bind \
87+
-target=android \
88+
-androidapi 26 \
89+
-trimpath \
90+
-ldflags="-s -w -buildid=" \
91+
-o ../app/libs/megaproxy.aar \
92+
./mobile
93+
)
94+
95+
echo "Building signed App Bundle"
96+
(
97+
cd "$project_dir"
98+
./gradlew clean
99+
./gradlew bundleRelease -PmegaproxyVersionVariant=universal
100+
)
101+
102+
built_bundle="$project_dir/app/build/outputs/bundle/release/app-release.aab"
103+
output_bundle="$MEGAPROXY_RELEASE_DIR/mega-proxy.aab"
104+
if [[ ! -f "$built_bundle" ]]; then
105+
echo "Gradle did not produce the expected App Bundle: $built_bundle" >&2
106+
exit 1
107+
fi
108+
cp "$built_bundle" "$output_bundle"
109+
110+
jarsigner -verify "$output_bundle" >/dev/null
111+
actual_fingerprint="$(
112+
keytool -printcert -jarfile "$output_bundle" \
113+
| awk '/SHA256:/{print $2; exit}' \
114+
| tr -d ':' \
115+
| tr '[:upper:]' '[:lower:]'
116+
)"
117+
if [[ "$actual_fingerprint" != "$MEGAPROXY_EXPECTED_CERT_SHA256" ]]; then
118+
echo "Unexpected signing certificate for $output_bundle: $actual_fingerprint" >&2
119+
exit 1
120+
fi
121+
122+
expected_abis=(arm64-v8a armeabi-v7a x86 x86_64)
123+
bundle_entries="$temporary_dir/bundle-entries.txt"
124+
unzip -Z1 "$output_bundle" > "$bundle_entries"
125+
for abi in "${expected_abis[@]}"; do
126+
for library in libandroidx.graphics.path.so libgojni.so; do
127+
entry="base/lib/$abi/$library"
128+
if ! grep -Fxq "$entry" "$bundle_entries"; then
129+
echo "App Bundle is missing $entry" >&2
130+
exit 1
131+
fi
132+
done
133+
done
134+
135+
(
136+
cd "$MEGAPROXY_RELEASE_DIR"
137+
checksum_files=()
138+
while IFS= read -r file; do
139+
checksum_files+=("$file")
140+
done < <(find . -maxdepth 1 -type f \( -name 'mega-proxy-*.apk' -o -name 'mega-proxy.aab' \) -print | sort)
141+
shasum -a 256 "${checksum_files[@]}" > SHA256SUMS
142+
)
143+
144+
echo
145+
echo "Signed release App Bundle:"
146+
ls -lh "$output_bundle"
147+
echo "Checksums: $MEGAPROXY_RELEASE_DIR/SHA256SUMS"

0 commit comments

Comments
 (0)