-
Notifications
You must be signed in to change notification settings - Fork 4
213 lines (189 loc) · 9.35 KB
/
Copy pathworkers.yml
File metadata and controls
213 lines (189 loc) · 9.35 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
name: Deploy edge workers
on:
workflow_dispatch:
inputs:
operation:
description: Deployment operation
required: true
default: deploy
type: choice
options:
- deploy
- remove-canary
environment:
description: Cloudflare environment
required: true
default: staging
type: choice
options:
- staging
- canary
- production
worker:
description: Worker to deploy
required: true
default: documentation
type: choice
options:
- both
- documentation
- redirects
- email
permissions:
contents: read
concurrency:
group: edge-workers-${{ inputs.environment }}
cancel-in-progress: false
jobs:
deploy:
name: Deploy ${{ inputs.worker }} to ${{ inputs.environment }}
runs-on: ubuntu-latest
environment: cloudflare-${{ inputs.environment }}
steps:
- name: Validate production ref
if: inputs.environment == 'production'
env:
DEPLOY_REF: ${{ github.ref }}
DEPLOY_WORKER: ${{ inputs.worker }}
run: |
if [[ "$DEPLOY_REF" == refs/heads/main ]]; then exit 0; fi
if [[ "$DEPLOY_WORKER" == documentation && "$DEPLOY_REF" =~ ^refs/heads/release/[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.-]+)?-website$ ]]; then exit 0; fi
echo "Production requires main, or an approved release website branch for documentation." >&2
exit 2
- name: Validate operation
if: inputs.operation == 'remove-canary' && inputs.environment != 'canary'
run: |
echo "remove-canary requires the canary environment" >&2
exit 2
- name: Validate canary worker
if: inputs.environment == 'canary' && inputs.worker != 'documentation'
run: |
echo "canary operations require the documentation worker" >&2
exit 2
- name: Validate email environment
if: inputs.worker == 'email' && inputs.environment != 'production'
run: |
echo "the email worker is deployed only through the production environment" >&2
exit 2
- name: Checkout
uses: actions/checkout@v7
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
- name: Install dependencies
run: npm ci
- name: Validate documentation Worker
if: inputs.worker == 'both' || inputs.worker == 'documentation'
run: npm run test:docs-worker && npm run check:docs-worker
- name: Validate redirect Worker
if: inputs.worker == 'both' || inputs.worker == 'redirects'
run: npm run test:redirect-worker && npm run check:redirect-worker
- name: Validate email Worker
if: inputs.worker == 'email'
run: npm run test:email-worker && npm run check:email-worker
- name: Deploy documentation Worker to staging
if: inputs.operation == 'deploy' && inputs.environment == 'staging' && (inputs.worker == 'both' || inputs.worker == 'documentation')
run: npx wrangler deploy --env="" --config workers/docs/wrangler.jsonc
- name: Verify staging documentation
if: inputs.operation == 'deploy' && inputs.environment == 'staging' && (inputs.worker == 'both' || inputs.worker == 'documentation')
run: |
for attempt in 1 2 3 4 5 6; do
if node --input-type=module <<'NODE'
import { readFileSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
const config = JSON.parse(readFileSync('workers/docs/wrangler.jsonc', 'utf8'));
const vars = config.vars;
const revisions = JSON.parse(vars.DOC_REVISIONS ?? '{}');
const selected = new Map([[vars.LATEST_DOC_VERSION, revisions[vars.LATEST_DOC_VERSION]]]);
for (const [version, revision] of Object.entries(revisions)) selected.set(version, revision);
let passed = true;
for (const [version, revision] of selected) {
const args = ['scripts/docs/smoke-worker.mjs', 'https://docs-staging.gecode.dev', version];
if (revision) args.push('--revision', revision);
if (version !== vars.LATEST_DOC_VERSION) args.push('--immutable-only');
if (spawnSync(process.execPath, args, { stdio: 'inherit' }).status !== 0) passed = false;
}
process.exit(passed ? 0 : 1);
NODE
then exit 0; fi
if [ "$attempt" -eq 6 ]; then exit 1; fi
echo "Waiting for the documentation deployment and selected revisions to propagate (attempt $attempt)."
sleep 10
done
- name: Deploy documentation Worker to production
if: inputs.operation == 'deploy' && inputs.environment == 'production' && (inputs.worker == 'both' || inputs.worker == 'documentation')
run: npx wrangler deploy --env production --config workers/docs/wrangler.jsonc
- name: Deploy documentation Worker to canary
if: inputs.operation == 'deploy' && inputs.environment == 'canary' && (inputs.worker == 'both' || inputs.worker == 'documentation')
run: npx wrangler deploy --env canary --config workers/docs/wrangler.jsonc
- name: Verify production documentation
if: inputs.operation == 'deploy' && inputs.environment == 'production' && (inputs.worker == 'both' || inputs.worker == 'documentation')
run: |
for attempt in 1 2 3 4 5 6 7 8 9 10 11 12; do
if node --input-type=module <<'NODE'
import { readFileSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
const config = JSON.parse(readFileSync('workers/docs/wrangler.jsonc', 'utf8'));
const vars = config.env.production.vars;
const revisions = JSON.parse(vars.DOC_REVISIONS ?? '{}');
const selected = new Map([[vars.LATEST_DOC_VERSION, revisions[vars.LATEST_DOC_VERSION]]]);
for (const [version, revision] of Object.entries(revisions)) selected.set(version, revision);
let passed = true;
for (const [version, revision] of selected) {
const args = ['scripts/docs/smoke-worker.mjs', 'https://www.gecode.dev', version];
if (revision) args.push('--revision', revision);
if (version !== vars.LATEST_DOC_VERSION) args.push('--immutable-only');
if (spawnSync(process.execPath, args, { stdio: 'inherit' }).status !== 0) passed = false;
}
process.exit(passed ? 0 : 1);
NODE
then exit 0; fi
if [ "$attempt" -eq 12 ]; then exit 1; fi
echo "Waiting for the documentation deployment and selected revisions to propagate (attempt $attempt)."
sleep 30
done
- name: Verify documentation canary
if: inputs.operation == 'deploy' && inputs.environment == 'canary' && inputs.worker == 'documentation'
run: |
for attempt in 1 2 3 4 5 6; do
if node --input-type=module <<'NODE'
import { readFileSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
const config = JSON.parse(readFileSync('workers/docs/wrangler.jsonc', 'utf8'));
const vars = config.env.canary.vars;
const revisions = JSON.parse(vars.DOC_REVISIONS ?? '{}');
const selected = new Map([[vars.LATEST_DOC_VERSION, revisions[vars.LATEST_DOC_VERSION]]]);
let passed = true;
for (const [version, revision] of selected) {
const args = ['scripts/docs/smoke-worker.mjs', 'https://www.gecode.dev', version];
if (revision) args.push('--revision', revision);
args.push('--immutable-only');
if (spawnSync(process.execPath, args, { stdio: 'inherit' }).status !== 0) passed = false;
}
process.exit(passed ? 0 : 1);
NODE
then exit 0; fi
if [ "$attempt" -eq 6 ]; then exit 1; fi
echo "Waiting for the documentation deployment and selected revisions to propagate (attempt $attempt)."
sleep 10
done
- name: Remove documentation canary
if: inputs.operation == 'remove-canary'
run: node scripts/docs/remove-canary.mjs
- name: Deploy redirect Worker to staging
if: inputs.operation == 'deploy' && inputs.environment == 'staging' && (inputs.worker == 'both' || inputs.worker == 'redirects')
run: npx wrangler deploy --env="" --config workers/redirects/wrangler.jsonc
- name: Deploy redirect Worker to production
if: inputs.operation == 'deploy' && inputs.environment == 'production' && (inputs.worker == 'both' || inputs.worker == 'redirects')
run: npx wrangler deploy --env production --config workers/redirects/wrangler.jsonc
- name: Preserve origin fallback for production redirects
if: inputs.operation == 'deploy' && inputs.environment == 'production' && (inputs.worker == 'both' || inputs.worker == 'redirects')
run: node scripts/set-redirects-fail-open.mjs
- name: Deploy email Worker to production
if: inputs.operation == 'deploy' && inputs.environment == 'production' && inputs.worker == 'email'
run: npx wrangler deploy --config workers/email/wrangler.jsonc
env:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}