Repository navigation
219 lines (201 loc) · 8.83 KB
/
Copy pathbench-deploy.yml
File metadata and controls
219 lines (201 loc) · 8.83 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
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright the Vortex contributors
#
# Deploy bench (bench/web) to its own Vercel project, `benchmarks-website`,
# with the Vercel CLI. Git integration is off on that project, so these runs
# are its only deploys, and they never touch the `vortex` project that serves
# the marketing site. The project's Root Directory must be `bench/web`: the CLI
# runs from the repository root and uses the pulled project settings to find
# the app.
#
# Triggers: a production deploy on every push to main that touches bench/ or
# the root files bench/web builds from (package.json, bun.lock, bunfig.toml,
# tsconfig.base.json); a preview deploy on every same-repo pull request that
# does, with the preview URL posted back to the PR as a sticky comment; and
# `workflow_dispatch` for manual preview or production runs. Fork PRs are
# skipped, since they can't read VERCEL_TOKEN.
#
# The job runs in the `bench-production` or `bench-preview` GitHub environment.
# Each holds VERCEL_TOKEN, a token scoped to the `benchmarks-website` project,
# and `bench-production` only accepts runs from main. The environment also gives
# the PR its "View deployment" button. The job is skipped while the
# BENCH_VERCEL_PROJECT_ID variable is unset.
name: Bench Deploy
on:
push:
branches: [main]
paths:
- 'bench/**'
- 'package.json'
- 'bun.lock'
- 'bunfig.toml'
- 'tsconfig.base.json'
- '.github/workflows/bench-deploy.yml'
pull_request:
branches: [main]
paths:
- 'bench/**'
- 'package.json'
- 'bun.lock'
- 'bunfig.toml'
- 'tsconfig.base.json'
- '.github/workflows/bench-deploy.yml'
workflow_dispatch:
inputs:
environment:
description: "Vercel target environment"
type: choice
options: [preview, production]
default: preview
concurrency:
# Push and manual production runs share one queue and never cancel an active
# run, so each promotion finishes its verification before the next starts. A
# newer preview run can cancel an older preview of the same event and ref.
group: ${{ (github.event_name == 'push' || inputs.environment == 'production') && 'bench-deploy-production' || format('bench-deploy-preview-{0}-{1}', github.event_name, github.ref) }}
cancel-in-progress: ${{ github.event_name != 'push' && inputs.environment != 'production' }}
permissions:
contents: read
# The sticky preview-URL comment.
pull-requests: write
env:
VERCEL_ORG_ID: ${{ vars.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ vars.BENCH_VERCEL_PROJECT_ID }}
# renovate: datasource=npm depName=vercel
VERCEL_CLI_VERSION: "64.0.2"
jobs:
# Run bench's checks on the exact commit this run deploys. main takes squash
# merges and does not require a branch to be up to date before it merges, so
# the pushed commit itself is never checked before it lands, and Bench CI on
# main runs beside this workflow, not before it.
checks:
name: Check the deployed commit
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: read
if: >-
vars.BENCH_VERCEL_PROJECT_ID != '' && (
github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository
)
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Bench checks
uses: ./.github/actions/bench-checks
deploy:
name: Build & deploy to Vercel
needs: checks
runs-on: ubuntu-24.04
timeout-minutes: 20
# Fork PRs have no access to VERCEL_TOKEN, and we do not auto-deploy untrusted
# code; same-repo PRs, pushes, and manual dispatches run normally. Until the
# bench Vercel project is configured here, the job stays off.
if: >-
vars.BENCH_VERCEL_PROJECT_ID != '' && (
github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository
)
# push to main => production; pull_request => preview; manual dispatch => the
# input. `environment` can't read the job's `env`, so TARGET repeats this
# expression; keep the two in step.
environment:
name: bench-${{ (github.event_name == 'push' || inputs.environment == 'production') && 'production' || 'preview' }}
url: ${{ steps.deploy.outputs.url }}
env:
TARGET: ${{ (github.event_name == 'push' || inputs.environment == 'production') && 'production' || 'preview' }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# `vercel build` below builds ON THE RUNNER (not Vercel's infra). It runs
# bench/web's install command from vercel.json and `next build`, so Bun and
# Node must be on PATH. Mirror the bench-checks setup.
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.4.3
- name: Setup Node
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: .nvmrc
# An exact version, and `--before` gives the CLI's whole dependency tree
# the repository's 14-day cooldown, so this job, which holds VERCEL_TOKEN,
# never installs a freshly published package. There's no lockfile: the
# CLI pins vulnerable versions of its own dependencies that nothing here
# can patch (see CLAUDE.md "bench advisories"), and a lockfile would put
# them in front of dependency review on every PR.
- name: Install Vercel CLI
run: |
npm install -g --ignore-scripts --no-audit --no-fund \
--before="$(date -u -d '14 days ago' +%Y-%m-%dT%H:%M:%SZ)" \
"vercel@${VERCEL_CLI_VERSION}"
# Production verification probes the public domain, so it has to be set.
- name: Require a public production verification URL
if: env.TARGET == 'production'
env:
PROD_URL: ${{ vars.BENCH_SITE_BASE_URL }}
run: |
[[ "${PROD_URL}" == https://* ]] || { echo "::error::Set BENCH_SITE_BASE_URL to the public HTTPS production URL."; exit 1; }
# bench/web is a member of the root Bun workspace, so install from the
# root: bun.lock is there, and bunfig.toml's cooldown and linker apply.
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Pull Vercel project settings
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: vercel pull --yes --environment="${TARGET}"
- name: Build
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
# next.config.js embeds this, so /api/health reports the deployed commit.
BENCH_BUILD_SHA: ${{ github.sha }}
run: |
set -Eeuo pipefail
if [ "${TARGET}" = "production" ]; then
vercel build --prod
else
vercel build
fi
- name: Deploy (prebuilt)
id: deploy
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: |
set -Eeuo pipefail
if [ "${TARGET}" = "production" ]; then
url="$(vercel deploy --prebuilt --prod | tail -n1)"
else
url="$(vercel deploy --prebuilt | tail -n1)"
fi
echo "url=${url}" >> "$GITHUB_OUTPUT"
printf 'Deployed: %s\n' "$url"
# On a pull_request, post the preview URL back to the PR as a single sticky
# comment (edited in place on each push) so the preview is one click from the PR.
# The header keeps it apart from the Lighthouse comment, which the same bot posts.
- name: Comment preview URL on the PR
if: github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5
with:
header: bench-preview
message: "Bench preview for `${{ github.event.pull_request.head.sha }}`: ${{ steps.deploy.outputs.url }}"
# Check the build commit, the read paths and CDN caching. Production is
# probed on the public domain, and any failure fails the run. Previews sit
# behind Vercel Authentication, so their verification reports as blocked.
- name: Verify deployed build and read paths
id: verify
timeout-minutes: 4
env:
DEPLOY_URL: ${{ steps.deploy.outputs.url }}
PROD_URL: ${{ vars.BENCH_SITE_BASE_URL }}
EXPECTED_SHA: ${{ github.sha }}
run: |
set -Eeuo pipefail
if [ "${TARGET}" = "production" ]; then
node bench/scripts/verify-web-deploy.mjs "${PROD_URL}" "${EXPECTED_SHA}" production
else
node bench/scripts/verify-web-deploy.mjs "${DEPLOY_URL}" "${EXPECTED_SHA}" preview
fi