1name: Updates e2e 2 3on: 4 workflow_dispatch: {} 5 pull_request: 6 paths: 7 - .github/workflows/updates-e2e.yml 8 - packages/expo-json-utils/** 9 - packages/expo-manifests/** 10 - packages/expo-modules-core/** 11 - packages/expo-structured-headers/** 12 - packages/expo-updates-interface/** 13 - packages/expo-updates/** 14 - packages/expo/android/** 15 - packages/expo/ios/** 16 - templates/expo-template-bare-minimum/** 17 push: 18 branches: [main, 'sdk-*'] 19 paths: 20 - .github/workflows/updates-e2e.yml 21 - packages/expo-json-utils/** 22 - packages/expo-manifests/** 23 - packages/expo-modules-core/** 24 - packages/expo-structured-headers/** 25 - packages/expo-updates-interface/** 26 - packages/expo-updates/** 27 - packages/expo/android/** 28 - packages/expo/ios/** 29 - templates/expo-template-bare-minimum/** 30 31concurrency: 32 group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} 33 cancel-in-progress: true 34 35jobs: 36 android: 37 runs-on: ubuntu-20.04 38 env: 39 UPDATES_HOST: 10.0.2.2 # special IP that Android emulators map to host machine's localhost 40 UPDATES_PORT: 4747 41 strategy: 42 matrix: 43 api-level: [31] 44 steps: 45 - name: Checkout 46 uses: actions/checkout@v3 47 - name: ⬢ Setup Node 48 uses: actions/setup-node@v3 49 with: 50 node-version: '14.17' 51 - name: Use JDK 11 52 uses: actions/setup-java@v3 53 with: 54 distribution: 'temurin' 55 java-version: '11' 56 - name: ➕ Add `bin` to GITHUB_PATH 57 run: echo "$(yarn global bin)" >> $GITHUB_PATH 58 - name: ♻️ Restore caches 59 uses: ./.github/actions/expo-caches 60 id: expo-caches 61 with: 62 yarn-workspace: 'true' 63 avd: 'true' 64 avd-api: ${{ matrix.api-level }} 65 - name: Yarn install 66 if: steps.expo-caches.outputs.yarn-workspace-hit != 'true' 67 run: yarn install --frozen-lockfile 68 - name: Build expo-updates CLI 69 working-directory: packages/expo-updates 70 run: yarn build:cli 71 - name: Install Expo CLI 72 run: yarn global add expo-cli 73 - name: Init new expo app 74 working-directory: ../ 75 run: expo-cli init updates-e2e --yes 76 - name: Add yarn resolutions for local dependencies 77 working-directory: ../updates-e2e 78 run: | 79 # A jq filter to add a "resolutions" field 80 JQ_FILTER=$(cat << EOF 81 . + { 82 resolutions: { 83 "expo-application": "file:../expo/packages/expo-application", 84 "expo-constants": "file:../expo/packages/expo-constants", 85 "expo-eas-client": "file:../expo/packages/expo-eas-client", 86 "expo-error-recovery": "file:../expo/packages/expo-error-recovery", 87 "expo-file-system": "file:../expo/packages/expo-file-system", 88 "expo-font": "file:../expo/packages/expo-font", 89 "expo-json-utils": "file:../expo/packages/expo-json-utils", 90 "expo-keep-awake": "file:../expo/packages/expo-keep-awake", 91 "expo-manifests": "file:../expo/packages/expo-manifests", 92 "expo-modules-core": "file:../expo/packages/expo-modules-core", 93 "expo-structured-headers": "file:../expo/packages/expo-structured-headers", 94 "expo-updates-interface": "file:../expo/packages/expo-updates-interface" 95 } 96 } 97 EOF 98 ) 99 jq "$JQ_FILTER" < package.json > new-package.json 100 mv new-package.json package.json 101 - name: Add local expo packages 102 working-directory: ../updates-e2e 103 run: yarn add file:../expo/packages/expo-updates file:../expo/packages/expo file:../expo/packages/expo-splash-screen file:../expo/packages/expo-status-bar 104 - name: Setup app.config.json 105 working-directory: ../updates-e2e 106 run: echo "{\"name\":\"updates-e2e\",\"runtimeVersion\":\"1.0.0\",\"plugins\":[\"expo-updates\"],\"android\":{\"package\":\"dev.expo.updatese2e\"},\"ios\":{\"bundleIdentifier\":\"dev.expo.updatese2e\"},\"updates\":{\"url\":\"http://$UPDATES_HOST:$UPDATES_PORT/update\"}}" > app.config.json 107 - name: Generate code signing 108 working-directory: ../updates-e2e 109 run: yarn expo-updates codesigning:generate --key-output-directory keys --certificate-output-directory certs --certificate-validity-duration-years 1 --certificate-common-name "E2E Test App" 110 - name: Configure code signing 111 working-directory: ../updates-e2e 112 run: yarn expo-updates codesigning:configure --certificate-input-directory certs --key-input-directory keys 113 - name: Pack latest bare-minimum template as tarball for expo prebuild 114 working-directory: templates/expo-template-bare-minimum 115 run: echo "$PWD" && npm pack --pack-destination ../../../updates-e2e/ 116 - name: Prebuild 117 working-directory: ../updates-e2e 118 run: expo-cli prebuild --template expo-template-bare-minimum-*.tgz 119 - name: Copy App.js from test fixtures 120 working-directory: ../updates-e2e 121 run: cp ../expo/packages/expo-updates/e2e/__tests__/fixtures/App.js . 122 - name: Set host and port in App.js 123 working-directory: ../updates-e2e 124 run: sed -i -e "s/UPDATES_HOST/$UPDATES_HOST/" ./App.js && sed -i -e "s/UPDATES_PORT/$UPDATES_PORT/" ./App.js 125 - name: Assemble release APK 126 working-directory: ../updates-e2e/android 127 run: ./gradlew assembleRelease --stacktrace 128 - name: Copy APK to working directory 129 run: cp -R ../updates-e2e/android/app/build/outputs/apk artifact 130 - name: Upload test APK artifact 131 uses: actions/upload-artifact@v3 132 with: 133 name: updates-e2e-android-apk 134 path: artifact 135 - name: Get test APK path 136 id: test-apk-path 137 working-directory: ../updates-e2e/android/app/build/outputs/apk/release 138 run: echo "::set-output name=dir::$(pwd)" 139 - name: Export update for test server to host 140 working-directory: ../updates-e2e 141 run: expo export --public-url https://u.expo.dev/dummy-url --platform android 142 - name: Get test update dist path 143 id: test-update-dist-path 144 working-directory: ../updates-e2e/dist 145 run: echo "::set-output name=dir::$(pwd)" 146 - name: Get test code signing private key path 147 id: test-code-signing-private-key-path 148 working-directory: ../updates-e2e/keys 149 run: echo "::set-output name=dir::$(pwd)/private-key.pem" 150 - name: Run tests 151 env: 152 TEST_APK_PATH: '${{ steps.test-apk-path.outputs.dir }}/app-release.apk' 153 TEST_UPDATE_DIST_PATH: '${{ steps.test-update-dist-path.outputs.dir }}' 154 TEST_PRIVATE_KEY_PATH: '${{ steps.test-code-signing-private-key-path.outputs.dir }}' 155 timeout-minutes: 30 156 uses: reactivecircus/android-emulator-runner@v2 157 with: 158 api-level: ${{ matrix.api-level }} 159 avd-name: avd-${{ matrix.api-level }} 160 arch: x86_64 161 force-avd-creation: false 162 script: yarn test --config e2e/jest.config.android.js 163 working-directory: packages/expo-updates 164 165 ios: 166 runs-on: macos-11 167 timeout-minutes: 60 168 env: 169 UPDATES_HOST: localhost 170 UPDATES_PORT: 4747 171 steps: 172 - name: Checkout 173 uses: actions/checkout@v3 174 - name: Switch to Xcode 13.0 175 run: sudo xcode-select --switch /Applications/Xcode_13.0.app 176 - name: ➕ Add `bin` to GITHUB_PATH 177 run: echo "$(yarn global bin)" >> $GITHUB_PATH 178 - name: ♻️ Restore caches 179 uses: ./.github/actions/expo-caches 180 id: expo-caches 181 with: 182 yarn-workspace: 'true' 183 - name: Yarn install 184 if: steps.expo-caches.outputs.yarn-workspace-hit != 'true' 185 run: yarn install --frozen-lockfile 186 - name: Build expo-updates CLI 187 working-directory: packages/expo-updates 188 run: yarn build:cli 189 - name: Install Expo CLI 190 run: yarn global add expo-cli 191 - name: Init new expo app 192 working-directory: ../ 193 run: expo-cli init updates-e2e --yes 194 - name: Add yarn resolutions for local dependencies 195 working-directory: ../updates-e2e 196 run: | 197 # A jq filter to add a "resolutions" field 198 JQ_FILTER=$(cat << EOF 199 . + { 200 resolutions: { 201 "expo-application": "file:../expo/packages/expo-application", 202 "expo-constants": "file:../expo/packages/expo-constants", 203 "expo-eas-client": "file:../expo/packages/expo-eas-client", 204 "expo-error-recovery": "file:../expo/packages/expo-error-recovery", 205 "expo-file-system": "file:../expo/packages/expo-file-system", 206 "expo-font": "file:../expo/packages/expo-font", 207 "expo-json-utils": "file:../expo/packages/expo-json-utils", 208 "expo-keep-awake": "file:../expo/packages/expo-keep-awake", 209 "expo-manifests": "file:../expo/packages/expo-manifests", 210 "expo-modules-core": "file:../expo/packages/expo-modules-core", 211 "expo-structured-headers": "file:../expo/packages/expo-structured-headers", 212 "expo-updates-interface": "file:../expo/packages/expo-updates-interface" 213 } 214 } 215 EOF 216 ) 217 jq "$JQ_FILTER" < package.json > new-package.json 218 mv new-package.json package.json 219 - name: Add local expo packages 220 working-directory: ../updates-e2e 221 run: yarn add file:../expo/packages/expo-updates file:../expo/packages/expo file:../expo/packages/expo-splash-screen file:../expo/packages/expo-status-bar 222 - name: Setup app.config.json 223 working-directory: ../updates-e2e 224 run: echo "{\"name\":\"updates-e2e\",\"runtimeVersion\":\"1.0.0\",\"plugins\":[\"expo-updates\"],\"android\":{\"package\":\"dev.expo.updatese2e\"},\"ios\":{\"bundleIdentifier\":\"dev.expo.updatese2e\"},\"updates\":{\"url\":\"http://$UPDATES_HOST:$UPDATES_PORT/update\"}}" > app.config.json 225 - name: Generate code signing 226 working-directory: ../updates-e2e 227 run: yarn expo-updates codesigning:generate --key-output-directory keys --certificate-output-directory certs --certificate-validity-duration-years 1 --certificate-common-name "E2E Test App" 228 - name: Configure code signing 229 working-directory: ../updates-e2e 230 run: yarn expo-updates codesigning:configure --certificate-input-directory certs --key-input-directory keys 231 - name: Pack latest bare-minimum template as tarball for expo prebuild 232 working-directory: templates/expo-template-bare-minimum 233 run: npm pack --pack-destination ../../../updates-e2e/ 234 - name: Prebuild --no-install 235 working-directory: ../updates-e2e 236 run: expo-cli prebuild --template expo-template-bare-minimum-*.tgz --no-install && yarn 237 # TODO: not caching pods for now as we don't have a lockfile with which to use in the key 238 # and as this is a minimal project, time savings is not much anyway (~3.5 mins at most) 239 # - name: Restore updates-e2e/ios/Pods from cache 240 # uses: actions/cache@v2 241 # id: pods-cache 242 # with: 243 # path: '../updates-e2e/ios/Pods' 244 # key: ${{ runner.os }}-pods-updatese2e-${{ hashFiles('../updates-e2e/ios/Podfile.lock') }} 245 # # restore-keys: | 246 # # ${{ runner.os }}-pods-updatese2e- 247 - name: Install CocoaPods in `updates-e2e/ios` 248 run: pod install 249 working-directory: ../updates-e2e/ios 250 - name: Copy App.js from test fixtures 251 working-directory: ../updates-e2e 252 run: cp ../expo/packages/expo-updates/e2e/__tests__/fixtures/App.js . 253 - name: Set host and port in App.js 254 working-directory: ../updates-e2e 255 run: sed -i -e "s/UPDATES_HOST/$UPDATES_HOST/" ./App.js && sed -i -e "s/UPDATES_PORT/$UPDATES_PORT/" ./App.js 256 - name: Build release app 257 working-directory: ../updates-e2e/ios 258 run: xcodebuild -workspace updatese2e.xcworkspace -scheme updatese2e -configuration Release -destination "generic/platform=iOS Simulator" -derivedDataPath ./build build 259 - name: Copy app to working directory 260 run: cp -R ../updates-e2e/ios/build/Build/Products/Release-iphonesimulator/updatese2e.app artifact 261 - name: Upload test app artifact 262 uses: actions/upload-artifact@v3 263 with: 264 name: updates-e2e-ios-app 265 path: artifact 266 - name: Get test app path 267 id: test-app-path 268 working-directory: ../updates-e2e/ios/build/Build/Products/Release-iphonesimulator/ 269 run: echo "::set-output name=dir::$(pwd)" 270 - name: Export update for test server to host 271 working-directory: ../updates-e2e 272 run: expo export --public-url https://u.expo.dev/dummy-url --platform ios 273 - name: Get test update dist path 274 id: test-update-dist-path 275 working-directory: ../updates-e2e/dist 276 run: echo "::set-output name=dir::$(pwd)" 277 - name: Get test code signing private key path 278 id: test-code-signing-private-key-path 279 working-directory: ../updates-e2e/keys 280 run: echo "::set-output name=dir::$(pwd)/private-key.pem" 281 - name: Start simulator 282 run: | 283 xcrun simctl list devices -j \ 284 | jq -rc '[ .[] | .[] | .[] | select( .name | contains( "iPhone" ) ) | select( .isAvailable == true ) ] | last.udid ' \ 285 | xargs open -a Simulator --args -CurrentDeviceUDID 286 - name: Run tests 287 env: 288 TEST_APP_PATH: '${{ steps.test-app-path.outputs.dir }}/updatese2e.app' 289 TEST_UPDATE_DIST_PATH: '${{ steps.test-update-dist-path.outputs.dir }}' 290 TEST_PRIVATE_KEY_PATH: '${{ steps.test-code-signing-private-key-path.outputs.dir }}' 291 timeout-minutes: 30 292 working-directory: packages/expo-updates 293 run: yarn test --config e2e/jest.config.ios.js 294