summaryrefslogtreecommitdiffhomepage
path: root/.github/workflows/android-app.yml
blob: 00161fecd98240b07623989341406de7fe62ba57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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