name: Android - Build and test on: # Build whenever a file that affects Android is changed in a pull request pull_request: paths: - .github/workflows/android-app.yml - android/** - mullvad-api/** - mullvad-daemon/** - mullvad-jni/** - mullvad-paths/** - mullvad-problem-report/** - mullvad-types/** - talpid-core/** - talpid-platform-metadata/** - talpid-types/** - talpid-types/** - wireguard/** - Cargo.toml - build-apk.sh - update-api-metadata.sh - update-version-metadata.sh - version-metadata.sh # Build if requested manually from the Actions tab workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 - name: Calculate native lib cache hash id: native-lib-cache-hash shell: bash run: | non_android_hash="$(git grep --cached -l '' -- ':!android/' | xargs -d '\n' sha1sum | sha1sum | awk '{print $1}')" echo "::set-output name=native_lib_hash::$non_android_hash" - name: Cache native libraries uses: actions/cache@v2 id: cache-native-libs with: path: | ./android/app/build/extraJni ./dist-assets/relays.json ./dist-assets/api-ip-address.txt key: android-native-libs-${{ runner.os }}-x86_64-${{ steps.native-lib-cache-hash.outputs.native_lib_hash }} - name: Configure Rust if: steps.cache-native-libs.outputs.cache-hit != 'true' uses: actions-rs/toolchain@v1.0.6 with: toolchain: stable target: x86_64-linux-android default: true - name: Configure Go if: steps.cache-native-libs.outputs.cache-hit != 'true' uses: actions/setup-go@v2.1.3 with: go-version: 1.16 - name: Configure Android NDK if: steps.cache-native-libs.outputs.cache-hit != 'true' id: install-android-ndk uses: nttld/setup-ndk@v1 with: ndk-version: r20b - name: Bind Cargo with NDK if: steps.cache-native-libs.outputs.cache-hit != 'true' run: | cat >> $HOME/.cargo/config << EOF [target.x86_64-linux-android] ar = "${{ steps.install-android-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android-ar" linker = "${{ steps.install-android-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang" EOF - name: Build native libraries if: steps.cache-native-libs.outputs.cache-hit != 'true' env: RUSTFLAGS: --deny warnings NDK_TOOLCHAIN_DIR: ${{ steps.install-android-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin AR_x86_64_linux_android: ${{ steps.install-android-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android-ar CC_x86_64_linux_android: ${{ steps.install-android-ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang ABI: x86_64 TARGET: x86_64-linux-android BUILD_TYPE: debug run: | ARCHITECTURES="$ABI" UNSTRIPPED_LIB_PATH="./target/$TARGET/$BUILD_TYPE/libmullvad_jni.so" STRIPPED_LIB_PATH="./android/app/build/extraJni/$ABI/libmullvad_jni.so" NDK_TOOLCHAIN_STRIP_TOOL="$NDK_TOOLCHAIN_DIR/x86_64-linux-android-strip" ./wireguard/build-wireguard-go.sh --android --no-docker source env.sh $TARGET cargo build --target $TARGET --verbose --package mullvad-jni cargo run --bin relay_list > dist-assets/relays.json $NDK_TOOLCHAIN_STRIP_TOOL --strip-debug --strip-unneeded -o "$STRIPPED_LIB_PATH" "$UNSTRIPPED_LIB_PATH" - name: Configure Android SDK uses: maxim-lobanov/setup-android-tools@v1 with: packages: | platforms;android-30 build-tools;30.0.3 cache: true - name: Build Android app uses: burrunan/gradle-cache-action@v1 with: job-id: jdk8 arguments: assembleDebug gradle-version: wrapper build-root-directory: android - name: Run unit tests uses: burrunan/gradle-cache-action@v1 with: job-id: jdk8 arguments: testDebugUnitTest gradle-version: wrapper build-root-directory: android execution-only-caches: true - name: Assemble instrumented test apk uses: burrunan/gradle-cache-action@v1 with: job-id: jdk8 arguments: assembleAndroidTest gradle-version: wrapper build-root-directory: android execution-only-caches: true - name: Upload apks uses: actions/upload-artifact@v2 with: name: apks path: android/app/build/outputs/apk if-no-files-found: error retention-days: 1 instrumented-tests: name: Instrumented tests runs-on: macos-latest timeout-minutes: 30 needs: - build strategy: fail-fast: false steps: - name: Checkout repository uses: actions/checkout@v2 - uses: actions/download-artifact@v2 with: name: apks - name: AVD cache uses: actions/cache@v2 id: avd-cache with: path: | ~/.android/avd/* ~/.android/adb* key: emulator-api-29 - name: Create avd and generate snapshot uses: reactivecircus/android-emulator-runner@v2 if: steps.avd-cache.outputs.cache-hit != 'true' with: force-avd-creation: false api-level: 29 arch: x86_64 emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true profile: pixel script: echo "Generated AVD snapshot for caching." env: API_LEVEL: 29 - name: Run Android instrumented tests uses: reactivecircus/android-emulator-runner@v2 with: force-avd-creation: false api-level: 29 arch: x86_64 emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true profile: pixel script: ./ci/run-android-instrumented-tests.sh $(pwd) env: API_LEVEL: 29