Repository navigation
206 lines (181 loc) · 6.95 KB
/
Copy pathpublish-example-app.yml
File metadata and controls
206 lines (181 loc) · 6.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
name: Publish example app
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: Release tag to publish the example app for, e.g. v6.0.0
required: true
platform:
description: Platform to build. Defaults to all.
required: false
default: all
type: choice
options:
- all
- ios
- android
permissions:
contents: read
defaults:
run:
shell: bash
jobs:
check:
name: Check release is on main
runs-on: ubuntu-latest
env:
TAG: ${{ github.event.release.tag_name || inputs.tag }}
outputs:
on-main: ${{ steps.check.outputs.on-main }}
sha: ${{ steps.check.outputs.sha }}
tag: ${{ env.TAG }}
profile: ${{ steps.check.outputs.profile }}
steps:
- id: check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
status=$(gh api "repos/$GH_REPO/compare/main...$TAG" --jq .status)
if [ "$status" = "identical" ] || [ "$status" = "behind" ]; then
sha=$(gh api "repos/$GH_REPO/commits/$TAG" --jq .sha)
echo "on-main=true" >> "$GITHUB_OUTPUT"
echo "sha=$sha" >> "$GITHUB_OUTPUT"
else
echo "on-main=false" >> "$GITHUB_OUTPUT"
echo "::warning::$TAG is not on main ($status), nothing to deploy."
echo "$TAG is not on main ($status), nothing to deploy." >> "$GITHUB_STEP_SUMMARY"
fi
if [ "${TAG#*-}" != "$TAG" ]; then
echo "profile=preview" >> "$GITHUB_OUTPUT"
else
echo "profile=production" >> "$GITHUB_OUTPUT"
fi
publish:
name: Build and submit example app
needs: check
if: needs.check.outputs.on-main == 'true'
runs-on: ubuntu-latest
concurrency:
# One queue per channel, so a pending preview run doesn't cancel a production one
group: publish-example-app-${{ needs.check.outputs.profile }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ needs.check.outputs.sha }}
- name: Setup
uses: ./.github/actions/setup
- name: Setup Expo
uses: expo/expo-github-action@c7b66a9c327a43a8fa7c0158e7f30d6040d2481e # v8.2.1
with:
eas-version: 24.12.1
token: ${{ secrets.EXPO_TOKEN }}
- name: Check Expo authentication
working-directory: ./example
run: |
if ! eas whoami; then
echo "::error::Could not authenticate with Expo, check EXPO_TOKEN."
exit 1
fi
- name: Set example app version from the release tag
working-directory: ./example
env:
TAG: ${{ needs.check.outputs.tag }}
run: |
version="${TAG#v}"
version="${version%%-*}"
if ! echo "$version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error::Could not read a major.minor.patch version from $TAG."
exit 1
fi
jq --arg version "$version" '.expo.version = $version' app.json > app.json.tmp
mv app.json.tmp app.json
- name: Decide between an update and a build
id: decide
working-directory: ./example
env:
PROFILE: ${{ needs.check.outputs.profile }}
PLATFORM: ${{ inputs.platform || 'all' }}
run: |
platforms="$PLATFORM"
if [ "$PLATFORM" = "all" ]; then
platforms="ios android"
fi
build=()
update=()
for platform in $platforms; do
hash=$(npx expo-updates fingerprint:generate --platform "$platform" | jq -er .hash)
existing=$(eas build:list \
--platform "$platform" \
--channel "$PROFILE" \
--fingerprint-hash "$hash" \
--status finished \
--limit 1 \
--json \
--non-interactive | jq 'if type == "array" then length else "notanarray" end')
case "$existing" in
''|*[!0-9]*)
echo "::error::Could not read builds for $platform."
exit 1
;;
esac
echo "$platform: fingerprint $hash, $existing matching build(s)"
if [ "$existing" -eq 0 ]; then
build+=("$platform")
else
update+=("$platform")
fi
done
# EAS takes a single platform or "all"
to_platform() {
case $# in
0) echo "" ;;
1) echo "$1" ;;
*) echo all ;;
esac
}
echo "build=$(to_platform "${build[@]}")" >> "$GITHUB_OUTPUT"
echo "update=$(to_platform "${update[@]}")" >> "$GITHUB_OUTPUT"
echo "Building: ${build[*]:-none}. Updating: ${update[*]:-none}."
- name: Publish an update
# Before the build, so a slow or timed-out build can't hold up the update
if: steps.decide.outputs.update != ''
working-directory: ./example
env:
PROFILE: ${{ needs.check.outputs.profile }}
PLATFORM: ${{ steps.decide.outputs.update }}
TAG: ${{ needs.check.outputs.tag }}
run: |
eas update \
--channel "$PROFILE" \
--platform "$PLATFORM" \
--message "$TAG" \
--non-interactive
echo "Published an OTA update for $TAG for $PLATFORM on the $PROFILE channel." >> "$GITHUB_STEP_SUMMARY"
- name: Build and submit to the app stores
# Don't let a failed update for one platform skip the other's build
if: ${{ !cancelled() && steps.decide.outputs.build != '' }}
working-directory: ./example
env:
PROFILE: ${{ needs.check.outputs.profile }}
PLATFORM: ${{ steps.decide.outputs.build }}
TAG: ${{ needs.check.outputs.tag }}
run: |
eas build \
--platform "$PLATFORM" \
--profile "$PROFILE" \
--auto-submit-with-profile "$PROFILE" \
--non-interactive
echo "Built and submitted $TAG for $PLATFORM using the $PROFILE profile." >> "$GITHUB_STEP_SUMMARY"
- name: Report failure
if: failure() || cancelled()
env:
TAG: ${{ needs.check.outputs.tag }}
run: |
echo "::error::Example app deployment failed for $TAG. The release itself is fine, only the demo app did not update."
echo "Check EAS and the stores before re-running, a build may still be running or already submitted. Re-running before it finishes starts a second build." >> "$GITHUB_STEP_SUMMARY"
echo "If the build finished but the store upload failed, resubmit that build with \`eas submit --id <build id>\`. Re-running this workflow will publish an OTA update instead." >> "$GITHUB_STEP_SUMMARY"
echo "If only the update failed, re-running is safe." >> "$GITHUB_STEP_SUMMARY"