diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 12fd076..ddad224 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -20,6 +20,7 @@ name: CI on: push: branches: [master] + tags: ['v*'] pull_request: concurrency: @@ -71,9 +72,13 @@ jobs: # 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' + # ONLY on version tags (v*). The native build is heavy (NDK/whisper.cpp) and + # slow on the shared prod runner; building it on every push would peg the box + # (and degrade the live web apps). Cut a release with: git tag v1.2.3 && git push --tags + needs: [test] + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest + timeout-minutes: 120 steps: - uses: actions/checkout@v4 - name: Stage signing secrets as files @@ -92,13 +97,15 @@ jobs: --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 + - name: Extract APK + publish to the host (served at /wisp.apk via the compose volume) 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 + # Stream the APK into a host-mounted dir so it survives web container + # recreation (the wisp container mounts /srv/wisp/wisp.apk read-only). + docker run --rm -i -v /srv/wisp:/out alpine:3 sh -c 'mkdir -p /out && cat > /out/wisp.apk' < ./app-release.apk - name: Cleanup staged secrets if: always() run: rm -rf "$RUNNER_TEMP/sec" diff --git a/deploy/wisp.compose.yml b/deploy/wisp.compose.yml index fe87f06..f0a4988 100644 --- a/deploy/wisp.compose.yml +++ b/deploy/wisp.compose.yml @@ -27,6 +27,12 @@ services: - "traefik.http.routers.wisp.entrypoints=websecure" - "traefik.http.routers.wisp.tls.certresolver=letsencrypt" - "traefik.http.services.wisp.loadbalancer.server.port=8080" + # The downloadable Android APK, published to the host by the build-apk CI job + # (or a local build). Mounted read-only so it survives web container rebuilds. + # NOTE: /srv/wisp/wisp.apk must exist on the host before `up` (else Docker + # creates a directory there). The publish step creates it. + volumes: + - /srv/wisp/wisp.apk:/usr/share/nginx/html/wisp.apk:ro networks: - proxy diff --git a/docker/android.Dockerfile b/docker/android.Dockerfile index 42df6d3..ea33db4 100644 --- a/docker/android.Dockerfile +++ b/docker/android.Dockerfile @@ -97,7 +97,9 @@ RUN --mount=type=secret,id=ks_b64 \ ANDROID_KEY_PASSWORD="$(cat /run/secrets/ks_keypass)" \ bash scripts/ci-android-sign.sh \ && cd android \ - && ./gradlew assembleRelease --no-daemon -x lint --stacktrace + && ./gradlew assembleRelease \ + -PreactNativeArchitectures=arm64-v8a \ + --no-daemon --max-workers=2 -x lint --stacktrace # The signed APK (handy for `docker create` + `docker cp` extraction in CI). # /workspace/android/app/build/outputs/apk/release/app-release.apk