Repository navigation
224 lines (201 loc) · 8.82 KB
/
Copy pathdeploy-web.yml
File metadata and controls
224 lines (201 loc) · 8.82 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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
name: Deploy Web
# Publishes the web beta: the Flutter web build, built against the production
# Convex deployment, to the Cloudflare Pages project `icarus-web`, served at
# https://beta.icarusstrats.com. The server goes first (Deploy Server), so the
# site never runs ahead of the backend it talks to.
#
# A merge never runs this. Web ships with desktop: a stable Release Desktop run
# calls this with its version commit. Actions > Deploy Web > Run workflow is for
# a hotfix or a redeploy, and with no ref it rebuilds the latest stable desktop
# tag, so it cannot ship merges nobody has released. To roll back, promote an
# earlier deployment in Cloudflare instead.
# Setup and secrets: docs/release_process.md, "Web beta deploy".
on:
workflow_dispatch:
inputs:
ref:
description: Tag or commit on main to deploy, containing the latest stable release. Leave empty for the latest stable desktop tag.
type: string
required: false
default: ""
workflow_call:
inputs:
ref:
description: Commit on main to deploy.
type: string
required: true
permissions:
contents: read
jobs:
# Decides what ships before anything deploys.
resolve:
runs-on: ubuntu-latest
outputs:
sha: ${{ steps.resolve.outputs.sha }}
steps:
- name: Require Main
shell: bash
run: |
# Every run replaces the live beta, so a manual run from another
# branch would ship unreviewed code to testers.
if [[ "$GITHUB_REF" != "refs/heads/main" ]]; then
echo "::error::Deploy Web only runs from main. This run is on $GITHUB_REF."
exit 1
fi
# Full history for the tags and the check below. From main rather than
# this run's commit, because a release's version commit is newer than
# the commit that started the run.
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
ref: refs/heads/main
fetch-depth: 0
- name: Resolve The Commit To Deploy
id: resolve
shell: bash
env:
REQUESTED_REF: ${{ inputs.ref }}
run: |
ref="$REQUESTED_REF"
if [[ -z "$ref" ]]; then
ref=$(git tag --list 'desktop-stable-v*' --sort=-v:refname | head -n 1)
if [[ -z "$ref" ]]; then
echo "::error::No desktop-stable-v tag found. Name a ref to deploy."
exit 1
fi
fi
if ! sha=$(git rev-parse --verify --quiet --end-of-options "$ref^{commit}"); then
echo "::error::$ref is not a tag or commit in this repository."
exit 1
fi
if ! git merge-base --is-ancestor "$sha" refs/remotes/origin/main; then
echo "::error::$ref ($sha) is not on main. Only commits on main can deploy."
exit 1
fi
echo "Deploying $ref ($sha)."
echo "sha=$sha" >> "$GITHUB_OUTPUT"
server:
needs: resolve
uses: ./.github/workflows/deploy-server.yml
with:
confirmation: deploy-production
secrets: inherit
web:
needs: [resolve, server]
runs-on: ubuntu-latest
# The production secrets belong in this environment, limited to main.
environment: Production
# queue: max, because the default keeps one pending run and cancels the
# rest, and a manual redeploy must not cancel a release waiting here.
concurrency:
group: deploy-web
cancel-in-progress: false
queue: max
env:
FVM_HOME: ${{ github.workspace }}/.fvm_cache
PUB_CACHE: ${{ github.workspace }}/.pub-cache
steps:
- name: Require Secrets And Production Settings
shell: bash
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
ICARUS_PRODUCTION_CONVEX_DEPLOYMENT_URL: ${{ vars.ICARUS_PRODUCTION_CONVEX_DEPLOYMENT_URL }}
ICARUS_PRODUCTION_CONVEX_CLIENT_ID: ${{ vars.ICARUS_PRODUCTION_CONVEX_CLIENT_ID }}
run: |
missing=0
for name in CLOUDFLARE_API_TOKEN CLOUDFLARE_ACCOUNT_ID ICARUS_PRODUCTION_CONVEX_DEPLOYMENT_URL ICARUS_PRODUCTION_CONVEX_CLIENT_ID; do
if [[ -z "${!name}" ]]; then
echo "::error::Add $name. docs/release_process.md, \"Web beta deploy\", says where each one goes."
missing=1
fi
done
exit $missing
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
ref: ${{ needs.resolve.outputs.sha }}
fetch-depth: 0
# In this job, not resolve, because re-running a failed web job re-runs
# only this one. Re-running an old release must not put its web build
# over a newer one. To go back on purpose, promote a deployment instead.
- name: Refuse To Replace A Newer Release
shell: bash
run: |
latest=$(git tag --list 'desktop-stable-v*' --sort=-v:refname | head -n 1)
if [[ -n "$latest" ]] && ! git merge-base --is-ancestor "$latest" HEAD; then
echo "::error::This commit does not contain $latest, the latest stable release."
exit 1
fi
# wrangler-action runs Wrangler on this Node.
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
# Flutter setup mirrors the linux job in ci.yml: FVM installs the
# version pinned in .fvmrc.
- uses: dart-lang/setup-dart@6afc89df92d6eb3834022f73cd65adc8cdfcb92d # v1.8.1
- name: Cache Pub Packages
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Cache FVM SDK
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .fvm_cache
key: ${{ runner.os }}-fvm-${{ hashFiles('.fvmrc') }}
restore-keys: |
${{ runner.os }}-fvm-
- name: Add Pub Cache To PATH
shell: bash
run: echo "$PUB_CACHE/bin" >> "$GITHUB_PATH"
- name: Install FVM and Flutter SDK
shell: bash
run: |
dart pub global activate fvm
fvm install
- name: Get Dependencies
run: fvm flutter pub get
# Same flags as "Build Web Client" in ci.yml; only the Convex target
# differs. CI builds against development, the beta ships against the
# production deployment the server job just updated.
- name: Build Web Client
env:
ICARUS_PRODUCTION_CONVEX_DEPLOYMENT_URL: ${{ vars.ICARUS_PRODUCTION_CONVEX_DEPLOYMENT_URL }}
ICARUS_PRODUCTION_CONVEX_CLIENT_ID: ${{ vars.ICARUS_PRODUCTION_CONVEX_CLIENT_ID }}
run: >-
fvm flutter build web --no-wasm-dry-run
--dart-define=ICARUS_CLOUD_ENVIRONMENT=production
--dart-define=ICARUS_CONVEX_DEPLOYMENT_URL="$ICARUS_PRODUCTION_CONVEX_DEPLOYMENT_URL"
--dart-define=ICARUS_CONVEX_CLIENT_ID="$ICARUS_PRODUCTION_CONVEX_CLIENT_ID"
- name: Prepare Web Fonts
run: fvm dart run tool/prepare_web_fonts.dart build/web
# --branch=main: Cloudflare Pages treats a deploy to the project's
# production branch (main) as the production deployment, and the custom
# domain beta.icarusstrats.com follows production. Any other branch name
# would only create a preview URL. This Pages branch name is unrelated
# to the git branch, though both are main.
- name: Deploy to Cloudflare Pages
id: deploy
uses: cloudflare/wrangler-action@953926a2e2182532811c01a25e53647d93bf07c0 # v4.1.3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
# wrangler-action v4 installs Wrangler 4 by default.
command: pages deploy build/web --project-name=icarus-web --branch=main --commit-hash=${{ needs.resolve.outputs.sha }}
- name: Summarize Deployment
shell: bash
env:
DEPLOYMENT_URL: ${{ steps.deploy.outputs.deployment-url }}
PAGES_ENVIRONMENT: ${{ steps.deploy.outputs.pages-environment }}
DEPLOYED_SHA: ${{ needs.resolve.outputs.sha }}
run: |
{
echo "### Web beta deployed (production Convex)"
echo ""
echo "- Live: https://beta.icarusstrats.com"
echo "- This deployment: ${DEPLOYMENT_URL:-see the Deploy to Cloudflare Pages log}"
echo "- Pages environment: ${PAGES_ENVIRONMENT:-unknown} (production means the custom domain now serves it)"
echo "- Version: $(sed -n 's/^version: *\([^ ]*\).*/\1/p' pubspec.yaml)"
echo "- Commit: \`$DEPLOYED_SHA\`"
} >> "$GITHUB_STEP_SUMMARY"