ci: build + serve signed Android APK on push to master
- docker/android.Dockerfile: full socket-safe build (JDK17 + SDK + NDK 27 + CMake + Bun) -> expo prebuild -> sign (BuildKit --secret) -> assembleRelease. - ci.yml build-apk job: buildx build, extract APK via docker create/cp, copy into the running wisp container so it serves at /wisp.apk; artifact upload. - app.json: set android.package = dev.briggen.wisp (required by prebuild). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+44
-12
@@ -64,15 +64,47 @@ jobs:
|
||||
done
|
||||
echo "wisp container did not become healthy" >&2; exit 1
|
||||
|
||||
# =========================================================================
|
||||
# TODO (next iteration, once the runner is validated): build-apk.
|
||||
# The Android build is genuinely risky (whisper.rn C++/NDK on RN 0.85) and
|
||||
# untested locally (no Android SDK on the dev box). It must be socket-safe:
|
||||
# a FULL `docker build` of a build-stage in docker/android.Dockerfile (repo
|
||||
# COPYed in, prebuild + gradlew assembleRelease, signing via BuildKit
|
||||
# --secret using the ANDROID_* secrets), then extract the APK with
|
||||
# `docker create`/`docker cp` (NO host bind-mounts — they don't resolve over
|
||||
# the mounted socket) and `docker cp` it into the running `wisp` container at
|
||||
# /usr/share/nginx/html/wisp.apk (served at https://wisp.briggen.dev/wisp.apk),
|
||||
# plus upload it as a CI artifact. Keystore secrets are already configured.
|
||||
# =========================================================================
|
||||
# ---- build-apk: signed release APK, served at /wisp.apk ------------------
|
||||
# Socket-safe: the whole Android build runs inside `docker buildx build`
|
||||
# (context streamed to the host BuildKit — no host bind-mounts), signed via
|
||||
# BuildKit --secret from the ANDROID_* repo secrets. We then extract the APK
|
||||
# with docker create/cp and copy it into the running `wisp` web container so
|
||||
# it is downloadable at https://wisp.briggen.dev/wisp.apk.
|
||||
build-apk:
|
||||
needs: [test, deploy-web]
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Stage signing secrets as files
|
||||
run: |
|
||||
umask 077
|
||||
mkdir -p "$RUNNER_TEMP/sec"
|
||||
printf '%s' "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" > "$RUNNER_TEMP/sec/ks_b64"
|
||||
printf '%s' "${{ secrets.ANDROID_KEYSTORE_PASSWORD }}" > "$RUNNER_TEMP/sec/ks_pass"
|
||||
printf '%s' "${{ secrets.ANDROID_KEY_ALIAS }}" > "$RUNNER_TEMP/sec/ks_alias"
|
||||
printf '%s' "${{ secrets.ANDROID_KEY_PASSWORD }}" > "$RUNNER_TEMP/sec/ks_keypass"
|
||||
- name: Build signed APK image
|
||||
run: |
|
||||
docker buildx build \
|
||||
--secret id=ks_b64,src="$RUNNER_TEMP/sec/ks_b64" \
|
||||
--secret id=ks_pass,src="$RUNNER_TEMP/sec/ks_pass" \
|
||||
--secret id=ks_alias,src="$RUNNER_TEMP/sec/ks_alias" \
|
||||
--secret id=ks_keypass,src="$RUNNER_TEMP/sec/ks_keypass" \
|
||||
-f docker/android.Dockerfile -t wisp-android:ci --load .
|
||||
- name: Extract + publish APK to /wisp.apk
|
||||
run: |
|
||||
cid=$(docker create wisp-android:ci)
|
||||
docker cp "$cid:/workspace/android/app/build/outputs/apk/release/app-release.apk" ./app-release.apk
|
||||
docker rm "$cid"
|
||||
ls -lh app-release.apk
|
||||
docker cp ./app-release.apk wisp:/usr/share/nginx/html/wisp.apk
|
||||
- name: Cleanup staged secrets
|
||||
if: always()
|
||||
run: rm -rf "$RUNNER_TEMP/sec"
|
||||
- name: Upload APK artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: wisp-release-apk
|
||||
path: app-release.apk
|
||||
|
||||
Reference in New Issue
Block a user