1name: Mobile EAS Preview
2
3on:
4 pull_request:
5 types: [opened, reopened, synchronize, labeled]
6
7jobs:
8 preview:
9 name: EAS Preview
10 if: |
11 contains(github.event.pull_request.labels.*.name, '🚀 Mobile Continuous Deployment') &&
12 (github.event.action != 'labeled' || github.event.label.name == '🚀 Mobile Continuous Deployment')
13 runs-on: blacksmith-8vcpu-ubuntu-2404
14 concurrency:
15 group: mobile-eas-preview-${{ github.event.pull_request.number }}
16 cancel-in-progress: true
17 permissions:
18 contents: read
19 pull-requests: write
20 env:
21 APP_VARIANT: preview
22 NODE_OPTIONS: --max-old-space-size=8192
23 MOBILE_VERSION_POLICY: fingerprint
24 steps:
25 - id: expo-token
26 name: Check for EXPO_TOKEN
27 env:
28 EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
29 run: |
30 if [ -n "$EXPO_TOKEN" ]; then
31 echo "present=true" >> "$GITHUB_OUTPUT"
32 else
33 echo "present=false" >> "$GITHUB_OUTPUT"
34 echo "EXPO_TOKEN is not available; skipping EAS preview."
35 fi
36
37 - name: Checkout
38 if: steps.expo-token.outputs.present == 'true'
39 uses: actions/checkout@v6
40 with:
41 fetch-depth: 0
42 # No sparse-checkout here: it makes actions/checkout fetch with
43 # --filter=blob:none, and eas-cli archives the project via
44 # `git clone --depth 1 file://<workspace>`, which fails (exit 128)
45 # when the partial clone can't serve the unfetched blobs.
46
47 - name: Setup Vite+
48 if: steps.expo-token.outputs.present == 'true'
49 uses: voidzero-dev/setup-vp@v1
50 with:
51 node-version-file: package.json
52 cache: true
53 run-install: |
54 args:
55 - --filter=@t3tools/mobile...
56
57 - name: Expose pnpm
58 if: steps.expo-token.outputs.present == 'true'
59 run: |
60 pnpm_version="$(node --print "require('./package.json').packageManager.split('@').pop()")"
61 vp_pnpm_bin="$HOME/.vite-plus/package_manager/pnpm/$pnpm_version/pnpm/bin"
62 echo "$vp_pnpm_bin" >> "$GITHUB_PATH"
63 "$vp_pnpm_bin/pnpm" --version
64
65 - name: Setup EAS
66 if: steps.expo-token.outputs.present == 'true'
67 uses: expo/expo-github-action@v8
68 with:
69 # eas-cli 22 renamed `project` to `app` in build JSON, and
70 # continuous-deploy-fingerprint still reads `build.project.ownerAccount`.
71 # Unpin once https://github.com/expo/expo-github-action/issues/358 is fixed.
72 eas-version: 21.8.0
73 token: ${{ secrets.EXPO_TOKEN }}
74 # npm, not pnpm: this only installs eas-cli into the action's own
75 # tool dir, and pnpm 11 hard-fails that install on dtrace-provider's
76 # ignored build script (no allowBuilds config outside the repo).
77 packager: npm
78
79 - name: Pull preview environment variables
80 if: steps.expo-token.outputs.present == 'true'
81 working-directory: apps/mobile
82 env:
83 EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
84 run: |
85 eas env:pull preview --non-interactive
86 # EAS Update disables dotenv loading. Keep the downloaded native config
87 # in its process environment so Android build and OTA fingerprints match.
88 node --input-type=module <<'NODE'
89 import { appendFileSync, readFileSync } from "node:fs";
90 import { parseEnv } from "node:util";
91 const env = parseEnv(readFileSync(".env.local", "utf8"));
92 const googleServicesFile = env.T3CODE_ANDROID_GOOGLE_SERVICES_FILE;
93 if (googleServicesFile) {
94 appendFileSync(process.env.GITHUB_ENV, `T3CODE_ANDROID_GOOGLE_SERVICES_FILE=${googleServicesFile}\n`);
95 }
96 NODE
97
98 - name: Deploy with fingerprint check
99 if: steps.expo-token.outputs.present == 'true'
100 uses: expo/expo-github-action/continuous-deploy-fingerprint@main
101 env:
102 EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
103 # The Expo action otherwise suppresses the EAS command's failure output.
104 RUNNER_DEBUG: "1"
105 with:
106 profile: preview:dev
107 branch: pr-${{ github.event.pull_request.number }}
108 platform: all
109 environment: preview
110 working-directory: apps/mobile
111 github-token: ${{ secrets.GITHUB_TOKEN }}