Skip to content

iOS TestFlight Deploy #25

iOS TestFlight Deploy

iOS TestFlight Deploy #25

name: iOS TestFlight Deploy
permissions:
contents: read
on:
push:
branches: [main]
paths: ['app/**']
workflow_dispatch:
inputs:
build_id:
description: 'Existing EAS build ID to submit without rebuilding'
required: false
type: string
jobs:
build-and-submit:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./app
steps:
- name: Setup repo
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4.0.2
with:
# eas-cli 23 requires Node >=22; pin the runner toolchain accordingly.
node-version: 22.x
cache: 'npm'
cache-dependency-path: ./app/package-lock.json
- name: Setup Expo
uses: expo/expo-github-action@v8
with:
expo-version: latest
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- name: Install dependencies
run: npm ci
- name: Write and validate ASC API key
env:
ASC_API_KEY_P8: ${{ secrets.ASC_API_KEY_P8 }}
run: |
set -euo pipefail
if [ -z "$ASC_API_KEY_P8" ]; then
echo "ASC_API_KEY_P8 is not configured"
exit 1
fi
printf '%s\n' "$ASC_API_KEY_P8" > asc-api-key.p8
chmod 600 asc-api-key.p8
openssl pkey -in asc-api-key.p8 -noout -check
# Read the key/issuer ids from eas.json rather than repeating them, so the
# build and submit steps can never disagree about which key they mean.
node -e '
const ios = require("./eas.json").submit.testflight.ios;
const out = require("fs");
out.appendFileSync(process.env.GITHUB_ENV,
`EXPO_ASC_KEY_ID=${ios.ascApiKeyId}\nEXPO_ASC_ISSUER_ID=${ios.ascApiKeyIssuerId}\n`);
'
- name: Build and submit to TestFlight
if: inputs.build_id == ''
# The ASC key is exported for the *build*, not just the submit step: a new
# target (the share extension) needs its own provisioning profile, and
# without Apple auth EAS falls back to an interactive login and fails
# non-interactive builds with "Failed to set up credentials".
env:
EXPO_ASC_API_KEY_PATH: ${{ github.workspace }}/app/asc-api-key.p8
# Without this EAS prompts "Apple Team ID:" and dies on unreadable stdin.
# It is the OU of the team's distribution certificate, not a secret.
EXPO_APPLE_TEAM_ID: '39Z45MQX8Z'
run: eas build --platform ios --profile testflight --auto-submit --non-interactive
- name: Submit existing build to TestFlight
if: inputs.build_id != ''
env:
EAS_BUILD_ID: ${{ inputs.build_id }}
run: >-
eas build:submit
--platform ios
--profile testflight
--id "$EAS_BUILD_ID"
--non-interactive
--wait