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