1name: Android Client 2 3on: 4 workflow_dispatch: 5 inputs: 6 releaseAPK: 7 description: 'type "release-apk" to confirm upload to S3' 8 required: false 9 releaseGooglePlay: 10 description: 'type "release-google-play" to confirm release to Google Play' 11 required: false 12 schedule: 13 - cron: '20 5 * * 1,3,5' # 5:20 AM UTC time on every Monday, Wednesday and Friday 14 pull_request: 15 paths: 16 - .github/workflows/client-android.yml 17 - secrets/** 18 - android/** 19 - fastlane/** 20 - Gemfile.lock 21 - .ruby-version 22 - yarn.lock 23 push: 24 branches: [master, sdk-*] 25 paths: 26 - .github/workflows/client-android.yml 27 - secrets/** 28 - android/** 29 - fastlane/** 30 - Gemfile.lock 31 - .ruby-version 32 - yarn.lock 33 34concurrency: 35 group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} 36 cancel-in-progress: true 37 38jobs: 39 build: 40 runs-on: ubuntu-18.04 41 steps: 42 - name: Checkout 43 uses: actions/checkout@v2 44 with: 45 submodules: true 46 - name: ♻️ Restore workspace node modules 47 uses: actions/cache@v2 48 id: node-modules-cache 49 with: 50 path: | 51 # See "workspaces" → "packages" in the root package.json for the source of truth of 52 # which node_modules are affected by the root yarn.lock 53 node_modules 54 apps/*/node_modules 55 home/node_modules 56 packages/*/node_modules 57 packages/@unimodules/*/node_modules 58 react-native-lab/react-native/node_modules 59 key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }} 60 - run: echo "$(pwd)/bin" >> $GITHUB_PATH 61 - name: ♻️ Restore node modules in tools 62 uses: actions/cache@v2 63 with: 64 path: tools/node_modules 65 key: ${{ runner.os }}-tools-modules-${{ hashFiles('tools/yarn.lock') }} 66 - name: Yarn install 67 run: yarn install --frozen-lockfile 68 - name: Setup Ruby and install gems 69 uses: ruby/setup-ruby@v1 70 with: 71 bundler-cache: true 72 - name: Install git-crypt 73 run: sudo apt-get install git-crypt 74 - name: Decrypt secrets if possible 75 env: 76 GIT_CRYPT_KEY_BASE64: ${{ secrets.GIT_CRYPT_KEY_BASE64 }} 77 run: | 78 if [ -z "${GIT_CRYPT_KEY_BASE64}" ]; then 79 echo 'git-crypt key not present in environment' 80 else 81 git crypt unlock <(echo $GIT_CRYPT_KEY_BASE64 | base64 --decode) 82 fi 83 - name: ♻️ Restore Gradle caches 84 uses: actions/cache@v2 85 with: 86 path: ~/.gradle/caches 87 key: ${{ runner.os }}-gradle-${{ hashFiles('android/*.gradle*') }} 88 restore-keys: | 89 ${{ runner.os }}-gradle- 90 - name: ♻️ Restore Android NDK from cache 91 uses: actions/cache@v2 92 id: cache-android-ndk 93 with: 94 path: /usr/local/lib/android/sdk/ndk/19.2.5345600/ 95 key: ${{ runner.os }}-ndk-19.2.5345600 96 restore-keys: | 97 ${{ runner.os }}-ndk- 98 - name: Install NDK 99 if: steps.cache-android-ndk.outputs.cache-hit != 'true' 100 run: | 101 sudo $ANDROID_SDK_ROOT/tools/bin/sdkmanager --install "ndk;19.2.5345600" 102 - name: Check which flavor to build 103 id: flavor 104 uses: dorny/paths-filter@v2 105 with: 106 # this action fails when base is not set on schedule event 107 base: ${{ github.ref }} 108 filters: | 109 versioned: 110 - android/versioned-abis/** 111 - android/versioned-react-native/** 112 - android/expoview/src/versioned/** 113 - android/expoview/src/main/java/versioned/** 114 - android/**/*.gradle 115 - name: Build APK 116 env: 117 ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_B64 }} 118 ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} 119 ANDROID_KEY_ALIAS: ExponentKey 120 ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} 121 ANDROID_NDK_HOME: /usr/local/lib/android/sdk/ndk/19.2.5345600/ 122 IS_RELEASE_BUILD: ${{ github.event.inputs.releaseAPK == 'release-apk' || github.event.inputs.releaseGooglePlay == 'release-google-play' }} 123 IS_VERSIONED_FLAVOR: ${{ github.event_name == 'schedule' || steps.flavor.outputs.versioned == 'true' }} 124 run: | 125 if [ "$IS_RELEASE_BUILD" == "false" ]; then 126 export NDK_ABI_FILTERS="x86_64" 127 BUILD_TYPE="Debug" 128 echo "Using ABI filters: $NDK_ABI_FILTERS" 129 else 130 BUILD_TYPE="Release" 131 fi 132 [[ "$IS_VERSIONED_FLAVOR" == "true" ]] && FLAVOR="Versioned" || FLAVOR="Unversioned" 133 echo "Building with $FLAVOR flavor" 134 if [ -z "$ANDROID_KEYSTORE_B64" ]; then 135 echo "External build detected, APK will not be signed" 136 bin/fastlane android build build_type:$BUILD_TYPE flavor:$FLAVOR sign:false 137 else 138 echo "Internal build detected, APK will be signed" 139 echo $ANDROID_KEYSTORE_B64 | base64 -d > android/app/release-key.jks 140 bin/fastlane android build build_type:$BUILD_TYPE flavor:$FLAVOR 141 fi 142 - name: Upload APK artifact 143 uses: actions/upload-artifact@v2 144 with: 145 name: android-apk 146 path: android/app/build/outputs/apk 147 - name: Store daemon logs for debugging crashes 148 if: failure() 149 uses: actions/upload-artifact@v2 150 with: 151 name: gradle-daemon-logs 152 path: ~/.gradle/daemon 153 - name: Upload APK to S3 and update staging versions endpoint 154 if: ${{ github.event.inputs.releaseAPK == 'release-apk' }} 155 run: bin/expotools client-build --platform android --release 156 env: 157 AWS_ACCESS_KEY_ID: AKIAJ3SWUQ4QLNQC7FXA 158 AWS_SECRET_ACCESS_KEY: ${{ secrets.android_client_build_aws_secret_key }} 159 EXPO_VERSIONS_SECRET: ${{ secrets.expo_versions_secret }} 160 - name: Upload APK to Google Play and release to production 161 if: ${{ github.event.inputs.releaseGooglePlay == 'release-google-play' }} 162 run: bin/fastlane android prod_release 163 env: 164 SUPPLY_JSON_KEY_DATA: ${{ secrets.SUPPLY_JSON_KEY_DATA }} 165 - name: Notify on Slack 166 uses: 8398a7/action-slack@v3 167 if: failure() && (github.event.ref == 'refs/heads/master' || startsWith(github.event.ref, 'refs/heads/sdk-')) 168 env: 169 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 170 SLACK_WEBHOOK_URL: ${{ secrets.slack_webhook_android }} 171 with: 172 channel: '#platform-android' 173 status: ${{ job.status }} 174 fields: job,message,ref,eventName,author,took 175 author_name: Expo Go (Android) 176