An ATproto social media client -- with an independent Appview.
1---
2name: Build and Submit iOS
3
4on:
5 workflow_dispatch:
6 inputs:
7 profile:
8 type: choice
9 description: Build profile to use
10 options:
11 - testflight
12 - production
13
14jobs:
15 build:
16 if: github.repository == 'bluesky-social/social-app'
17 name: Build and Submit iOS
18 runs-on: macos-15
19 steps:
20 - name: Check for EXPO_TOKEN
21 run: >
22 if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
23 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"
24 exit 1
25 fi
26
27 - name: ⬇️ Checkout
28 uses: actions/checkout@v4
29 with:
30 fetch-depth: 5
31
32 - name: 🔧 Setup Node
33 uses: actions/setup-node@v4
34 with:
35 node-version-file: .nvmrc
36 cache: yarn
37
38 - name: 🪛 Setup jq
39 uses: dcarbone/install-jq-action@v2
40
41 - name: 🔨 Setup EAS
42 uses: expo/expo-github-action@v8
43 with:
44 expo-version: latest
45 eas-version: latest
46 token: ${{ secrets.EXPO_TOKEN }}
47
48 - name: ⛏️ Setup EAS local builds
49 run: yarn global add eas-cli-local-build-plugin
50
51 - name: ⚙️ Install dependencies
52 run: yarn install
53
54 - uses: maxim-lobanov/setup-xcode@v1
55 with:
56 xcode-version: "16.4"
57
58 - name: ☕️ Setup Cocoapods
59 uses: maxim-lobanov/setup-cocoapods@v1
60 with:
61 version: 1.16.2
62
63 - name: 💾 Cache Pods
64 uses: actions/cache@v3
65 id: pods-cache
66 with:
67 path: ./ios/Pods
68 # We'll use the yarn.lock for our hash since we don't yet have a Podfile.lock. Pod versions will not
69 # change unless the yarn version changes as well.
70 key: ${{ runner.os }}-pods-${{ hashFiles('yarn.lock') }}
71
72 - name: 🔤 Compile translations
73 run: yarn intl:build 2>&1 | tee i18n.log
74
75 - name: Check for i18n compilation errors
76 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
77
78 # EXPO_PUBLIC_ENV is handled in eas.json
79 - name: ✏️ Write environment variables
80 id: env
81 run: |
82 echo "${{ secrets.ENV_TOKEN }}" > .env
83 echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
84 echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
85 echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
86 echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
87 echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
88 echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
89 echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
90 echo "EXPO_PUBLIC_GCP_PROJECT_ID=${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}" >> .env
91 echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json
92
93 - name: 🏗️ EAS Build
94 run: >
95 SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
96 SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
97 SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
98 yarn use-build-number-with-bump
99 eas build -p ios
100 --profile ${{ inputs.profile || 'testflight' }}
101 --local --output build.ipa --non-interactive
102
103 - name: 🚀 Deploy
104 run: eas submit -p ios --non-interactive --path build.ipa
105
106 - name: 📚 Get version from package.json
107 id: get-build-info
108 run: bash scripts/setGitHubOutput.sh
109
110 - name: 🔔 Notify Slack of Production Build
111 if: ${{ inputs.profile == 'production' }}
112 uses: slackapi/slack-github-action@v1.25.0
113 with:
114 payload: |
115 {
116 "text": "iOS production build for App Store submission is ready!\n```Artifact: Check TestFlight to know when it is available\nVersion Number: ${{ steps.get-build-info.outputs.PACKAGE_VERSION }}\nBuild Number: ${{ steps.get-build-info.outputs.BSKY_IOS_BUILD_NUMBER }}```"
117 }
118 env:
119 SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
120 SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
121
122 - name: ⬇️ Restore Cache
123 id: get-base-commit
124 uses: actions/cache@v4
125 if: ${{ inputs.profile == 'testflight' }}
126 with:
127 path: most-recent-testflight-commit.txt
128 key: most-recent-testflight-commit
129
130 - name: ✏️ Write commit hash to cache
131 if: ${{ inputs.profile == 'testflight' }}
132 run: echo ${{ github.sha }} > most-recent-testflight-commit.txt