mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1---
2name: Bundle and Deploy EAS Update
3
4on:
5 push:
6 branches:
7 - main
8 workflow_dispatch:
9 inputs:
10 channel:
11 type: choice
12 description: Deployment channel to use
13 options:
14 - testflight
15 - production
16 runtimeVersion:
17 type: string
18 description: Runtime version (in x.x.x format) that this update is for
19 required: true
20
21jobs:
22 bundleDeploy:
23 name: Bundle and Deploy EAS Update
24 runs-on: ubuntu-latest
25 concurrency:
26 group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-deploy
27 cancel-in-progress: true
28 outputs:
29 changes-detected: ${{ steps.fingerprint.outputs.includes-changes }}
30
31 steps:
32 - name: Check for EXPO_TOKEN
33 run: >
34 if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
35 echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions"
36 exit 1
37 fi
38
39 # Validate the version if one is supplied. This should generally happen if the update is for a production client
40 - name: 🧐 Validate version
41 if: ${{ inputs.runtimeVersion }}
42 run: |
43 if [ -z "${{ inputs.runtimeVersion }}" ]; then
44 [[ "${{ inputs.runtimeVersion }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && echo "Version is valid" || exit 1
45 fi
46
47 - name: ⬇️ Checkout
48 uses: actions/checkout@v4
49 with:
50 fetch-depth: 0
51
52 - name: ⬇️ Fetch commits from base branch
53 if: ${{ github.ref != 'refs/heads/main' }}
54 run: git fetch origin main:main --depth 100
55
56 - name: 🔧 Setup Node
57 uses: actions/setup-node@v4
58 with:
59 node-version-file: .nvmrc
60 cache: yarn
61
62 - name: 📷 Check fingerprint and install dependencies
63 id: fingerprint
64 uses: bluesky-social/github-actions/fingerprint-native@main
65 with:
66 profile: ${{ inputs.channel || 'testflight' }}
67 previous-commit-tag: ${{ inputs.runtimeVersion }}
68
69 - name: Lint check
70 run: yarn lint
71
72 - name: Lint lockfile
73 run: yarn lockfile-lint
74
75 - name: Prettier check
76 run: yarn prettier --check .
77
78 - name: 🔤 Compile translations
79 run: yarn intl:build 2>&1 | tee i18n.log
80
81 - name: Check for i18n compilation errors
82 run: if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compilation errors!\n\n"; fi
83
84 - name: Type check
85 run: yarn typecheck
86
87 - name: 🔨 Setup EAS
88 uses: expo/expo-github-action@v8
89 if: ${{ !steps.fingerprint.outputs.includes-changes }}
90 with:
91 expo-version: latest
92 eas-version: latest
93 token: ${{ secrets.EXPO_TOKEN }}
94
95 - name: ⛏️ Setup Expo
96 if: ${{ !steps.fingerprint.outputs.includes-changes }}
97 run: yarn global add eas-cli-local-build-plugin
98
99 - name: 🪛 Setup jq
100 if: ${{ !steps.fingerprint.outputs.includes-changes }}
101 uses: dcarbone/install-jq-action@v2
102
103 - name: ✏️ Write environment variables
104 if: ${{ !steps.fingerprint.outputs.includes-changes }}
105 run: |
106 export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
107 echo "${{ secrets.ENV_TOKEN }}" > .env
108 echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
109 echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
110 echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
111 echo "$json" > google-services.json
112
113 - name: Setup Sentry vars for build-time injection
114 id: sentry
115 run: |
116 echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
117 echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
118
119 - name: 🏗️ Create Bundle
120 if: ${{ !steps.fingerprint.outputs.includes-changes }}
121 run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} EXPO_PUBLIC_ENV="${{ inputs.channel || 'testflight' }}" yarn export
122
123 - name: 📦 Package Bundle and 🚀 Deploy
124 if: ${{ !steps.fingerprint.outputs.includes-changes }}
125 run: yarn use-build-number bash scripts/bundleUpdate.sh
126 env:
127 DENIS_API_KEY: ${{ secrets.DENIS_API_KEY }}
128 RUNTIME_VERSION: ${{ inputs.runtimeVersion }}
129 CHANNEL_NAME: ${{ inputs.channel || 'testflight' }}
130
131 - name: ⬇️ Restore Cache
132 id: get-base-commit
133 uses: actions/cache@v4
134 if: ${{ !steps.fingerprint.outputs.includes-changes }}
135 with:
136 path: most-recent-testflight-commit.txt
137 key: most-recent-testflight-commit
138
139 - name: ✏️ Write commit hash to cache
140 if: ${{ !steps.fingerprint.outputs.includes-changes }}
141 run: echo ${{ github.sha }} > most-recent-testflight-commit.txt
142
143 # GitHub actions are horrible so let's just copy paste this in
144 buildIfNecessaryIOS:
145 name: Build and Submit iOS
146 runs-on: macos-15
147 concurrency:
148 group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-build-ios
149 cancel-in-progress: true
150 needs: [bundleDeploy]
151 # Gotta check if its NOT '[]' because any md5 hash in the outputs is detected as a possible secret and won't be
152 # available here
153 if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.changes-detected }}
154 steps:
155 - name: Check for EXPO_TOKEN
156 run: >
157 if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
158 echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions"
159 exit 1
160 fi
161
162 - name: ⬇️ Checkout
163 uses: actions/checkout@v4
164 with:
165 fetch-depth: 5
166
167 - name: 🔧 Setup Node
168 uses: actions/setup-node@v4
169 with:
170 node-version-file: .nvmrc
171 cache: yarn
172
173 - name: 🔨 Setup EAS
174 uses: expo/expo-github-action@v8
175 with:
176 expo-version: latest
177 eas-version: latest
178 token: ${{ secrets.EXPO_TOKEN }}
179
180 - name: ⛏️ Setup EAS local builds
181 run: yarn global add eas-cli-local-build-plugin
182
183 - name: ⚙️ Install dependencies
184 run: yarn install
185
186 - uses: maxim-lobanov/setup-xcode@v1
187 with:
188 xcode-version: '16.2'
189
190 - name: ☕️ Setup Cocoapods
191 uses: maxim-lobanov/setup-cocoapods@v1
192 with:
193 version: 1.14.3
194
195 - name: 💾 Cache Pods
196 uses: actions/cache@v3
197 id: pods-cache
198 with:
199 path: ./ios/Pods
200 # We'll use the yarn.lock for our hash since we don't yet have a Podfile.lock. Pod versions will not
201 # change unless the yarn version changes as well.
202 key: ${{ runner.os }}-pods-${{ hashFiles('yarn.lock') }}
203
204 - name: 🔤 Compile translations
205 run: yarn intl:build
206
207 - name: ✏️ Write environment variables
208 run: |
209 echo "${{ secrets.ENV_TOKEN }}" > .env
210 echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
211 echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
212 echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
213 echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json
214
215 - name: 🏗️ EAS Build
216 run: yarn use-build-number-with-bump eas build -p ios --profile testflight --local --output build.ipa --non-interactive
217
218 - name: 🚀 Deploy
219 run: eas submit -p ios --non-interactive --path build.ipa
220
221 - name: ⬇️ Restore Cache
222 id: get-base-commit
223 uses: actions/cache@v4
224 if: ${{ inputs.channel == 'testflight' }}
225 with:
226 path: most-recent-testflight-commit.txt
227 key: most-recent-testflight-commit
228
229 - name: ✏️ Write commit hash to cache
230 if: ${{ inputs.channel == 'testflight' }}
231 run: echo ${{ github.sha }} > most-recent-testflight-commit.txt
232
233 buildIfNecessaryAndroid:
234 name: Build and Submit Android
235 runs-on: ubuntu-latest
236 concurrency:
237 group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-build-android
238 cancel-in-progress: false
239 needs: [bundleDeploy]
240 # Gotta check if its NOT '[]' because any md5 hash in the outputs is detected as a possible secret and won't be
241 # available here
242 if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.changes-detected }}
243
244 steps:
245 - name: Check for EXPO_TOKEN
246 run: >
247 if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
248 echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions"
249 exit 1
250 fi
251
252 - name: ⬇️ Checkout
253 uses: actions/checkout@v4
254 with:
255 fetch-depth: 5
256
257 - name: 🔧 Setup Node
258 uses: actions/setup-node@v4
259 with:
260 node-version-file: .nvmrc
261 cache: yarn
262
263 - name: 🔨 Setup EAS
264 uses: expo/expo-github-action@v8
265 with:
266 expo-version: latest
267 eas-version: latest
268 token: ${{ secrets.EXPO_TOKEN }}
269
270 - name: ⛏️ Setup EAS local builds
271 run: yarn global add eas-cli-local-build-plugin
272
273 - uses: actions/setup-java@v4
274 with:
275 distribution: 'temurin'
276 java-version: '17'
277
278 - name: ⚙️ Install dependencies
279 run: yarn install
280
281 - name: 🔤 Compile translations
282 run: yarn intl:build
283
284 - name: ✏️ Write environment variables
285 run: |
286 export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
287 echo "${{ secrets.ENV_TOKEN }}" > .env
288 echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
289 echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
290 echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
291 echo "$json" > google-services.json
292
293 - name: 🏗️ EAS Build
294 run: yarn use-build-number-with-bump eas build -p android --profile testflight-android --local --output build.apk --non-interactive
295
296 - name: ⏰ Get a timestamp
297 id: timestamp
298 uses: nanzm/get-time-action@master
299 with:
300 format: 'MM-DD-HH-mm-ss'
301
302 - name: 🚀 Upload Artifact
303 id: upload-artifact
304 uses: actions/upload-artifact@v4
305 with:
306 retention-days: 30
307 compression-level: 0
308 name: build-${{ steps.timestamp.outputs.time }}.apk
309 path: build.apk
310
311 - name: 🔔 Notify Slack
312 uses: slackapi/slack-github-action@v1.25.0
313 with:
314 payload: |
315 {
316 "text": "Android build is ready for testing. Download the artifact here: ${{ steps.upload-artifact.outputs.artifact-url }}"
317 }
318 env:
319 SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
320 SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
321
322 - name: ⬇️ Restore Cache
323 id: get-base-commit
324 uses: actions/cache@v4
325 if: ${{ inputs.channel != 'testflight' && inputs.channel != 'production' }}
326 with:
327 path: most-recent-testflight-commit.txt
328 key: most-recent-testflight-commit
329
330 - name: ✏️ Write commit hash to cache
331 if: ${{ inputs.channel != 'testflight' && inputs.channel != 'production' }}
332 run: echo ${{ github.sha }} > most-recent-testflight-commit.txt