OXYGENHUB
◆ main oxygenhub-android / scripts / release.sh
3.2 KiB · Bourne Again Shell (bash) · executable · last changed The release job moves the signed APK into dist/ (refs #7) 7 days ago source blame history raw
1
#!/usr/bin/env bash
2
# The app's release job (#7), in OxygenFlow's Android image with no network:
3
# a signed release APK of the version in gradle.properties, checked with
4
# apksigner, in dist/ beside its SHA256SUMS, for a release on oxygenhub.io.
5
#
6
# The key comes from the job's secrets, mounted as files and never in the
7
# environment: android-keystore (the PKCS12 keystore, base64) and
8
# android-keystore-password; and firebase-config (google-services.json, for
9
# alerts). Locally, give the same files:
10
#   KEYSTORE_B64=path PASSWORD_FILE=path [FIREBASE_CONFIG=path] scripts/release.sh
11
set -euo pipefail
12
cd "$(dirname "$0")/.."
13
b64=${KEYSTORE_B64:-/run/secrets/android-keystore}
14
password=${PASSWORD_FILE:-/run/secrets/android-keystore-password}
15
# Firebase's client settings for alerts (#16): google-services.json, the
16
# repository's firebase-config secret; without it the release takes no alerts.
17
firebase=${FIREBASE_CONFIG:-/run/secrets/firebase-config}
18
for f in "$b64" "$password"; do
19
    [ -s "$f" ] || { echo "release: no $f: the job needs the android-keystore secrets" >&2; exit 1; }
20
done
21
# The secrets first, in seconds, before a build that takes a quarter of an hour.
22
KEYSTORE_B64="$b64" PASSWORD_FILE="$password" FIREBASE_CONFIG="$firebase" bash scripts/release-check.sh
23
version=$(sed -n 's/^oxygenhub\.version=//p' gradle.properties)
24
[ -n "$version" ] || { echo "release: no oxygenhub.version in gradle.properties" >&2; exit 1; }
25
26
# As ci.sh: the image's JDKs for Gradle's daemon, never a download.
27
jdks=$( (ls -d /opt/gradle-home/jdks/*/ 2>/dev/null || true) | sed 's:/$::' | paste -sd, -)
28
if [ -n "$jdks" ] && [ -n "${GRADLE_USER_HOME:-}" ]; then
29
    mkdir -p "$GRADLE_USER_HOME"
30
    {
31
        echo "org.gradle.java.installations.paths=$jdks"
32
        echo "org.gradle.java.installations.auto-download=false"
33
    } >> "$GRADLE_USER_HOME/gradle.properties"
34
fi
35
36
# The keystore, decoded where only this job can read it, and gone after.
37
keys=$(mktemp -d)
38
trap 'rm -rf "$keys"' EXIT
39
chmod 700 "$keys"
40
base64 -d "$b64" > "$keys/release.p12"
41
export OXYGENHUB_KEYSTORE="$keys/release.p12" OXYGENHUB_KEYSTORE_PASSWORD_FILE="$password"
42
if [ -s "$firebase" ]; then
43
    cp "$firebase" app/google-services.json
44
    trap 'rm -rf "$keys" app/google-services.json' EXIT
45
else
46
    echo "release: no $firebase: this release takes no alerts" >&2
47
fi
48
gradle=$(command -v gradle || echo ./gradlew)
49
"$gradle" --offline --no-daemon :app:assembleRelease
50
51
apk=app/build/outputs/apk/release/app-release.apk
52
[ -f "$apk" ] || { echo "release: no $apk (was it signed? an unsigned build is app-release-unsigned.apk)" >&2; exit 1; }
53
sdk=${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}
54
apksigner=$(ls -d "$sdk"/build-tools/*/apksigner 2>/dev/null | sort -V | tail -1)
55
"$apksigner" verify --print-certs "$apk" | grep -E '^Signer #1 certificate (DN|SHA-256)'
56
57
# Kept as an artifact by a fixed name; SHA256SUMS gives the name it takes
58
# in a release, with the version (as OxygenHub's and OxygenFlow's dist do).
59
rm -rf dist
60
mkdir -p dist
61
# Moved, not copied: the build leaves the workspace's disk nearly full.
62
mv "$apk" dist/oxygenhub-android-universal.apk
63
echo "$(sha256sum < dist/oxygenhub-android-universal.apk | cut -d' ' -f1)  oxygenhub-android-$version-universal.apk" > dist/SHA256SUMS
64
echo "release: oxygenhub-android-$version-universal.apk"