Skip to content

Commit fe0f60c

Browse files
dylanjeffersclaude
andcommitted
ci(mobile): collapse OTA matrix to single job with parallel code-push
The OTA matrix runs ios and android on separate runners, each repeating the ~5min node_modules setup. Combining both platforms into one job and running code-push as background processes (`ios & android & wait`) does the setup once and parallelizes only the publish step, which is the part that actually benefits from parallelism. Captures per-platform logs into collapsible groups and aggregates exit status so a failure on either platform still fails the job. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 342a671 commit fe0f60c

1 file changed

Lines changed: 71 additions & 31 deletions

File tree

.github/workflows/mobile.yml

Lines changed: 71 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,13 @@ jobs:
191191
fi
192192
193193
# OTA Release: publish JS bundle updates when native app version is unchanged.
194-
# Matrixed over platforms so iOS and Android publish in parallel.
194+
# iOS and Android code-push run in parallel as background processes within
195+
# one runner so the node_modules setup only happens once.
195196
mobile-ota-release:
196-
name: Mobile OTA Release (CodePush, ${{ matrix.platform }})
197+
name: Mobile OTA Release (CodePush)
197198
runs-on: ubuntu-latest
198199
needs: [mobile-install, mobile-version-check]
199200
if: (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.mobile-version-check.outputs.version_unchanged == 'true') || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ota_channel == 'rc' || github.event.inputs.ota_channel == ''))
200-
strategy:
201-
fail-fast: false
202-
matrix:
203-
platform: [ios, android]
204201
steps:
205202
- name: Checkout code
206203
uses: actions/checkout@v4
@@ -273,13 +270,13 @@ jobs:
273270
echo "channel=rc" >> "$GITHUB_OUTPUT"
274271
fi
275272
276-
- name: Publish OTA update (${{ matrix.platform }})
273+
- name: Publish OTA update (iOS + Android in parallel)
277274
env:
278275
OTA_S3_BUCKET: ${{ secrets.OTA_S3_BUCKET }}
279276
OTA_S3_PREFIX: mobile-ota
280277
OTA_PUBLIC_BASE_URL: https://download.audius.co/mobile-ota
281278
run: |
282-
set -euo pipefail
279+
set -uo pipefail
283280
BINARY_VERSION="${{ needs.mobile-version-check.outputs.current_version }}"
284281
OTA_CHANNEL="${{ steps.ota-channel.outputs.channel }}"
285282
IFS='.' read -r MAJOR MINOR PATCH <<< "$BINARY_VERSION"
@@ -288,29 +285,49 @@ jobs:
288285
OTA_APP_VERSION="${MAJOR}.${MINOR}.${OTA_PATCH}"
289286
290287
cd packages/mobile
291-
npx code-push create-history --binary-version "$BINARY_VERSION" --platform ${{ matrix.platform }} --identifier "$OTA_CHANNEL" || true
292288
293-
npx code-push release \
294-
--binary-version "$BINARY_VERSION" \
295-
--app-version "$OTA_APP_VERSION" \
296-
--platform ${{ matrix.platform }} \
297-
--identifier "$OTA_CHANNEL" \
298-
--entry-file index.js
289+
publish_platform() {
290+
local platform="$1"
291+
npx code-push create-history --binary-version "$BINARY_VERSION" --platform "$platform" --identifier "$OTA_CHANNEL" || true
292+
npx code-push release \
293+
--binary-version "$BINARY_VERSION" \
294+
--app-version "$OTA_APP_VERSION" \
295+
--platform "$platform" \
296+
--identifier "$OTA_CHANNEL" \
297+
--entry-file index.js
298+
}
299+
300+
publish_platform ios > ios.log 2>&1 &
301+
IOS_PID=$!
302+
publish_platform android > android.log 2>&1 &
303+
ANDROID_PID=$!
304+
305+
wait "$IOS_PID"; IOS_STATUS=$?
306+
wait "$ANDROID_PID"; ANDROID_STATUS=$?
307+
308+
echo "::group::iOS code-push output"
309+
cat ios.log
310+
echo "::endgroup::"
311+
echo "::group::Android code-push output"
312+
cat android.log
313+
echo "::endgroup::"
314+
315+
if [[ $IOS_STATUS -ne 0 || $ANDROID_STATUS -ne 0 ]]; then
316+
echo "iOS exit: $IOS_STATUS, Android exit: $ANDROID_STATUS"
317+
exit 1
318+
fi
299319
300320
# OTA Release (Production): manual + environment approval gate.
301-
# Matrixed over platforms so iOS and Android publish in parallel.
321+
# iOS and Android code-push run in parallel as background processes within
322+
# one runner so the node_modules setup only happens once.
302323
mobile-ota-release-production:
303-
name: Mobile OTA Release (Production, ${{ matrix.platform }})
324+
name: Mobile OTA Release (Production)
304325
runs-on: ubuntu-latest
305326
needs: [mobile-install, mobile-version-check]
306327
if: github.event_name == 'workflow_dispatch' && github.event.inputs.ota_channel == 'production'
307328
environment:
308329
name: mobile-production-ota
309330
url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
310-
strategy:
311-
fail-fast: false
312-
matrix:
313-
platform: [ios, android]
314331
steps:
315332
- name: Checkout code
316333
uses: actions/checkout@v4
@@ -374,28 +391,51 @@ jobs:
374391
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
375392
aws-region: us-east-1
376393

377-
- name: Publish OTA update to production (${{ matrix.platform }})
394+
- name: Publish OTA update to production (iOS + Android in parallel)
378395
env:
379396
OTA_S3_BUCKET: ${{ secrets.OTA_S3_BUCKET }}
380397
OTA_S3_PREFIX: mobile-ota
381398
OTA_PUBLIC_BASE_URL: https://download.audius.co/mobile-ota
382399
run: |
383-
set -euo pipefail
400+
set -uo pipefail
384401
BINARY_VERSION="${{ needs.mobile-version-check.outputs.current_version }}"
385402
OTA_CHANNEL="production"
386403
IFS='.' read -r MAJOR MINOR PATCH <<< "$BINARY_VERSION"
387404
OTA_PATCH=$((PATCH + 100000 + GITHUB_RUN_NUMBER))
388405
OTA_APP_VERSION="${MAJOR}.${MINOR}.${OTA_PATCH}"
389406
390407
cd packages/mobile
391-
npx code-push create-history --binary-version "$BINARY_VERSION" --platform ${{ matrix.platform }} --identifier "$OTA_CHANNEL" || true
392-
393-
npx code-push release \
394-
--binary-version "$BINARY_VERSION" \
395-
--app-version "$OTA_APP_VERSION" \
396-
--platform ${{ matrix.platform }} \
397-
--identifier "$OTA_CHANNEL" \
398-
--entry-file index.js
408+
409+
publish_platform() {
410+
local platform="$1"
411+
npx code-push create-history --binary-version "$BINARY_VERSION" --platform "$platform" --identifier "$OTA_CHANNEL" || true
412+
npx code-push release \
413+
--binary-version "$BINARY_VERSION" \
414+
--app-version "$OTA_APP_VERSION" \
415+
--platform "$platform" \
416+
--identifier "$OTA_CHANNEL" \
417+
--entry-file index.js
418+
}
419+
420+
publish_platform ios > ios.log 2>&1 &
421+
IOS_PID=$!
422+
publish_platform android > android.log 2>&1 &
423+
ANDROID_PID=$!
424+
425+
wait "$IOS_PID"; IOS_STATUS=$?
426+
wait "$ANDROID_PID"; ANDROID_STATUS=$?
427+
428+
echo "::group::iOS code-push output"
429+
cat ios.log
430+
echo "::endgroup::"
431+
echo "::group::Android code-push output"
432+
cat android.log
433+
echo "::endgroup::"
434+
435+
if [[ $IOS_STATUS -ne 0 || $ANDROID_STATUS -ne 0 ]]; then
436+
echo "iOS exit: $IOS_STATUS, Android exit: $ANDROID_STATUS"
437+
exit 1
438+
fi
399439
400440
# iOS Release Candidate: Build and upload
401441
mobile-build-upload-releasecandidate-ios:

0 commit comments

Comments
 (0)