{{ message }}
Repository navigation
268 lines (262 loc) · 11.3 KB
/
Copy pathverify-install-channels.yml
File metadata and controls
268 lines (262 loc) · 11.3 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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
name: Verify Install Channels
# Post-publish verification that the published install channels (Homebrew, Scoop, curl|bash)
# install the just-released CLI and serve artifacts matching the channel manifests' checksums.
# Runs automatically after every brew/scoop publish, and can also be dispatched manually against
# an already-published version.
#
# Performs a real install so a manifest/tarball checksum mismatch (as in CLI v2.107.0) reproduces
# here instead of being trusted from the publish step. Each leg also directly checks that the
# `supabase-go` sidecar binary is present and executable in the install directory, checking the
# file rather than a CLI command, since a command could later be natively ported off the sidecar.
on:
workflow_call:
inputs:
version:
description: Supabase CLI version that was just published (with or without leading v)
required: true
type: string
brew_name:
description: Homebrew formula name (e.g. supabase or supabase-beta)
required: true
type: string
scoop_name:
description: Scoop manifest name (e.g. supabase or supabase-beta)
required: true
type: string
workflow_dispatch:
inputs:
version:
description: Supabase CLI version to verify (must already be published; with or without leading v)
required: true
type: string
brew_name:
description: Homebrew formula name (e.g. supabase or supabase-beta)
required: false
type: string
default: supabase
scoop_name:
description: Scoop manifest name (e.g. supabase or supabase-beta)
required: false
type: string
default: supabase
permissions:
contents: read
jobs:
homebrew:
# macOS and Linux exercise different formula stanzas (`on_macos` vs `on_linux`), each with
# its own URL + sha256, so both must install for the tap to be considered verified.
name: Homebrew ${{ inputs.brew_name }} (${{ matrix.runner }})
strategy:
fail-fast: false
matrix:
runner:
- macos-latest
- ubuntu-latest
runs-on: ${{ matrix.runner }}
timeout-minutes: 10
env:
VERSION: ${{ inputs.version }}
BREW_NAME: ${{ inputs.brew_name }}
# Skips Homebrew's own auto-update; `brew install <user>/<tap>/<formula>` taps
# supabase/homebrew-tap from git HEAD regardless, so the fresh formula is picked up anyway.
#
# Do not also set HOMEBREW_NO_INSTALL_FROM_API: it only affects homebrew/core + cask taps,
# and on Linux it forces a slow homebrew/core checkout that hangs this job for 10+ minutes.
HOMEBREW_NO_AUTO_UPDATE: "1"
steps:
- name: Set up Homebrew on PATH
if: runner.os == 'Linux'
run: |
set -euo pipefail
# Homebrew ships preinstalled on GitHub's Ubuntu runners but is not on
# PATH in the non-login shells `run:` steps use, so expose it for the
# steps below. macOS runners already have `brew` on PATH.
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
echo "${HOMEBREW_PREFIX}/bin" >> "$GITHUB_PATH"
echo "${HOMEBREW_PREFIX}/sbin" >> "$GITHUB_PATH"
- name: Install from Homebrew tap
run: |
set -euo pipefail
# `brew install <user>/<tap>/<formula>` taps supabase/homebrew-tap at
# its current git HEAD and installs from source, verifying the
# formula's sha256 against the downloaded tarball. A checksum mismatch
# (the v2.107.0 failure mode) aborts the install here.
#
# Retry ONLY Homebrew's intermittent "Broken pipe" failures. During its
# bash startup brew runs pipelines like
# grep -E "^(flags|Features)" /proc/cpuinfo | grep -q ssse3
# where the downstream `grep -q` matches and exits early, closing the
# pipe; the still-writing upstream takes SIGPIPE and brew aborts with
# `Error: Broken pipe` (exit 1). It is a timing race (more likely on
# multi-core runners with a larger /proc/cpuinfo), so it is flaky, not
# deterministic, and a re-run succeeds. macOS reads CPU features via
# sysctl, not /proc/cpuinfo, which is why only the Linux leg hits it.
# Upstream fix: Homebrew/brew#21366.
#
# Any OTHER failure (notably a sha256 mismatch — the regression this
# job exists to catch) is non-transient and fails immediately, so the
# retry never masks a genuinely broken release.
attempts=0
max_attempts=3
while :; do
attempts=$((attempts + 1))
if out="$(brew install "supabase/tap/${BREW_NAME}" 2>&1)"; then
printf '%s\n' "${out}"
break
fi
printf '%s\n' "${out}" >&2
case "${out}" in
*"Broken pipe"*)
if [ "${attempts}" -ge "${max_attempts}" ]; then
echo "brew install still failing with 'Broken pipe' after ${attempts} attempts" >&2
exit 1
fi
echo "Transient Homebrew 'Broken pipe' on attempt ${attempts}; retrying in $((attempts * 5))s..." >&2
sleep "$((attempts * 5))"
;;
*)
echo "brew install failed with a non-transient error; not retrying." >&2
exit 1
;;
esac
done
- name: Verify supabase --version
run: |
set -euo pipefail
# `supabase --version` prints the version without the leading `v`,
# while release tags / dispatch inputs may include it, so strip it
# before comparing.
expected="${VERSION#v}"
actual="$(supabase --version | tr -d '\r' | head -n1)"
echo "supabase --version: ${actual}"
if [ "${actual}" != "${expected}" ]; then
echo "Version mismatch: expected ${expected}, got ${actual}" >&2
exit 1
fi
- name: Verify Go sidecar
run: |
set -euo pipefail
# Homebrew's `bin.install` symlinks both `supabase` and `supabase-go`
# into the same prefix bin/ directory, so the sidecar must sit right
# next to whichever `supabase` resolved from PATH.
bin_dir="$(dirname "$(command -v supabase)")"
sidecar="${bin_dir}/supabase-go"
if [ ! -e "${sidecar}" ]; then
echo "Go sidecar probe failed: ${sidecar} does not exist" >&2
exit 1
fi
if [ ! -x "${sidecar}" ]; then
echo "Go sidecar probe failed: ${sidecar} exists but is not executable" >&2
exit 1
fi
echo "Go sidecar probe OK: ${sidecar}"
scoop:
name: Scoop (${{ inputs.scoop_name }})
runs-on: windows-latest
timeout-minutes: 10
env:
VERSION: ${{ inputs.version }}
SCOOP_NAME: ${{ inputs.scoop_name }}
steps:
- name: Install Scoop
shell: pwsh
run: |
iex "& {$(irm get.scoop.sh)} -RunAsAdmin"
Join-Path (Resolve-Path ~).Path "scoop\shims" >> $env:GITHUB_PATH
- name: Install from Scoop bucket
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
# Adding the bucket clones supabase/scoop-bucket at its current HEAD;
# `scoop install` then verifies the manifest hash against the
# downloaded tarball before extracting it. A hash mismatch (the
# v2.107.0 failure mode) aborts the install here.
scoop bucket add supabase https://github.com/supabase/scoop-bucket
scoop install "supabase/$env:SCOOP_NAME"
- name: Verify supabase --version
# Force bash so ${VERSION} expands the same way as the other legs — windows-latest
# defaults to pwsh, which treats it as an empty PowerShell variable.
shell: bash
run: |
set -euo pipefail
expected="${VERSION#v}"
actual="$(supabase --version | tr -d '\r' | head -n1)"
echo "supabase --version: ${actual}"
if [ "${actual}" != "${expected}" ]; then
echo "Version mismatch: expected ${expected}, got ${actual}" >&2
exit 1
fi
- name: Verify Go sidecar
shell: bash
run: |
set -euo pipefail
# Scoop's manifest only declares `supabase.exe` in `bin` (see
# apps/cli/scripts/update-scoop.ts), so only `supabase` gets a shim in
# ~/scoop/shims — `dirname "$(command -v supabase)"` would resolve to
# the shim directory, not the real install directory supabase-go.exe
# actually lives in. Go straight to the app's current version
# directory instead, which Scoop always maintains regardless of shims.
app_dir="${HOME}/scoop/apps/${SCOOP_NAME}/current"
sidecar="${app_dir}/supabase-go.exe"
if [ ! -e "${sidecar}" ]; then
echo "Go sidecar probe failed: ${sidecar} does not exist" >&2
exit 1
fi
echo "Go sidecar probe OK: ${sidecar}"
install-script:
name: install script (${{ matrix.runner }})
strategy:
fail-fast: false
matrix:
runner:
- ubuntu-latest
- macos-latest
runs-on: ${{ matrix.runner }}
timeout-minutes: 10
env:
VERSION: ${{ inputs.version }}
steps:
- name: Install via the published install script
shell: bash
run: |
set -euo pipefail
version="${VERSION#v}"
# Fetch the install script that shipped with THIS release (uploaded as
# a release asset by release-shared.yml's publish job) rather than the
# copy in the repo checkout — users run the published script, which can
# diverge from the release branch. The script downloads the GitHub
# Release tarball plus checksums.txt and aborts on a sha256 mismatch.
# --no-modify-path keeps it from editing the runner's shell rc files;
# in GitHub Actions it still appends the install dir to $GITHUB_PATH,
# so `supabase` is on PATH for the verification steps below.
curl -fsSL "https://github.com/supabase/cli/releases/download/v${version}/install" -o install.sh
bash install.sh --version "${version}" --no-modify-path
- name: Verify supabase --version
shell: bash
run: |
set -euo pipefail
expected="${VERSION#v}"
actual="$(supabase --version | tr -d '\r' | head -n1)"
echo "supabase --version: ${actual}"
if [ "${actual}" != "${expected}" ]; then
echo "Version mismatch: expected ${expected}, got ${actual}" >&2
exit 1
fi
- name: Verify Go sidecar
shell: bash
run: |
set -euo pipefail
# The install script places `supabase-go` right next to `supabase`,
# so the sidecar must sit in the same directory `supabase` resolved
# from on PATH.
bin_dir="$(dirname "$(command -v supabase)")"
sidecar="${bin_dir}/supabase-go"
if [ ! -e "${sidecar}" ]; then
echo "Go sidecar probe failed: ${sidecar} does not exist" >&2
exit 1
fi
if [ ! -x "${sidecar}" ]; then
echo "Go sidecar probe failed: ${sidecar} exists but is not executable" >&2
exit 1
fi
echo "Go sidecar probe OK: ${sidecar}"
You can’t perform that action at this time.
