Repository navigation
313 lines (306 loc) · 13.5 KB
/
Copy pathci.yml
File metadata and controls
313 lines (306 loc) · 13.5 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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# Seeded from the socket-wheelhouse CI preset, then owned by this repo:
# edit it here. Fleet CI runs check + test through the LOCAL composite
# actions under .github/actions/, inlined, so there is no cross-repo
# reusable workflow and no first-party `uses:@sha`.
name: 'ci: native package'
run-name: 'ci: native package'
# PUSH, never pull_request. The fleet takes no outside contributions and
# lands on main directly, so a pull_request trigger adds no coverage a push
# trigger does not already give — and it is the fragile half: GitHub has
# narrowed pull_request defaults for security, and a silently non-firing
# trigger reads as a green repo with no CI at all.
on:
push:
branches: [main]
tags: ['*']
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# First step of every job is the third-party actions/checkout (GitHub fetches
# it independently) to populate the workspace so the LOCAL `./.github/actions/*`
# composites resolve. setup-and-install then re-checks-out — full history
# (fetch-depth 0) in the check job, since the commit-history checks it runs
# (AI-attribution, release-boundary) read the default branch's history and
# refuse a shallow clone rather than false-green; the test matrix stays at
# the default depth (25 — covers CI's other git operations) and runs the
# zizmor Actions audit (its own `strategy.job-total < 2` skip runs it in the
# non-matrix check job, skips it in the test matrix).
check:
name: Check
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
# First step can't call the local ./.github/actions/fleet/checkout
# composite (nothing checked out yet); bootstrap the workspace with an
# inline git-fetch, matching release-reconcile.yml's pattern. The full
# history this job needs comes from setup-and-install's own
# checkout-fetch-depth: '0' re-checkout below, so this bootstrap fetch
# stays shallow.
- name: Bootstrap checkout
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
SERVER_URL: ${{ github.server_url }}
REPOSITORY: ${{ github.repository }}
TRIGGER_REF: ${{ github.sha }}
run: |
set -euo pipefail
git init -q
git config --local advice.detachedHead false
git remote remove origin 2>/dev/null || true
git remote add origin "${SERVER_URL}/${REPOSITORY}"
FETCH_ARGS=(--no-tags --prune --depth 1 origin "${TRIGGER_REF}")
if [ -n "${GITHUB_TOKEN}" ]; then
AUTH_B64="$(printf 'x-access-token:%s' "${GITHUB_TOKEN}" | base64 | tr -d '\n')"
git -c "http.${SERVER_URL}/.extraheader=AUTHORIZATION: basic ${AUTH_B64}" fetch "${FETCH_ARGS[@]}"
else
git fetch "${FETCH_ARGS[@]}"
fi
git checkout -q --detach FETCH_HEAD
- name: Set up and install
uses: ./.github/actions/fleet/setup-and-install
with:
# Authorizes a thin member's bundle download during install. Both
# stay empty on a member with no payload App, which skips the mint.
payload-token-client-id: ${{ secrets.SOCKET_RELEASE_CLIENT_ID || vars.SOCKET_RELEASE_CLIENT_ID }}
payload-token-private-key: ${{ secrets.SOCKET_RELEASE_APP_PRIVATE_KEY }}
# Full history: the commit-history checks (AI-attribution,
# release-boundary) read the default branch's history and refuse a
# shallow clone rather than false-green.
checkout-fetch-depth: '0'
socket-api-token: ${{ secrets.SOCKET_API_TOKEN_FOR_CLI_AND_SFW }}
- name: Run checks
uses: ./.github/actions/fleet/run-script
with:
main-script: pnpm run check --all
test:
name: Test (${{ matrix.os }})
strategy:
fail-fast: false
max-parallel: 4
matrix:
# JS/TS tests only need a fast Linux run; cross-platform behavior is
# covered by unit tests, not the CI matrix.
os: [ubuntu-24.04]
runs-on: ${{ matrix.os }}
timeout-minutes: 15
steps:
# First step can't call the local ./.github/actions/fleet/checkout
# composite (nothing checked out yet); bootstrap the workspace with an
# inline git-fetch, matching release-reconcile.yml's pattern.
- name: Bootstrap checkout
shell: bash
env:
GITHUB_TOKEN: ${{ github.token }}
SERVER_URL: ${{ github.server_url }}
REPOSITORY: ${{ github.repository }}
TRIGGER_REF: ${{ github.sha }}
run: |
set -euo pipefail
git init -q
git config --local advice.detachedHead false
git remote remove origin 2>/dev/null || true
git remote add origin "${SERVER_URL}/${REPOSITORY}"
FETCH_ARGS=(--no-tags --prune --depth 1 origin "${TRIGGER_REF}")
if [ -n "${GITHUB_TOKEN}" ]; then
AUTH_B64="$(printf 'x-access-token:%s' "${GITHUB_TOKEN}" | base64 | tr -d '\n')"
git -c "http.${SERVER_URL}/.extraheader=AUTHORIZATION: basic ${AUTH_B64}" fetch "${FETCH_ARGS[@]}"
else
git fetch "${FETCH_ARGS[@]}"
fi
git checkout -q --detach FETCH_HEAD
- name: Set up and install
uses: ./.github/actions/fleet/setup-and-install
with:
# Authorizes a thin member's bundle download during install. Both
# stay empty on a member with no payload App, which skips the mint.
payload-token-client-id: ${{ secrets.SOCKET_RELEASE_CLIENT_ID || vars.SOCKET_RELEASE_CLIENT_ID }}
payload-token-private-key: ${{ secrets.SOCKET_RELEASE_APP_PRIVATE_KEY }}
socket-api-token: ${{ secrets.SOCKET_API_TOKEN_FOR_CLI_AND_SFW }}
- name: Mint sdxgen read token
id: sdxgen-token
uses: ./.github/actions/fleet/github-payload-app-token
with:
client-id: ${{ secrets.SOCKET_RELEASE_CLIENT_ID || vars.SOCKET_RELEASE_CLIENT_ID }}
private-key: ${{ secrets.SOCKET_RELEASE_APP_PRIVATE_KEY }}
repositories: sdxgen
- name: Run checks
uses: ./.github/actions/fleet/run-script
env:
# Authenticate build-time GitHub API reads (release listings,
# prebuilt-artifact downloads). Unauthenticated calls share the
# hosted runner's IP-scoped rate limit and 403 under load.
GH_TOKEN: ${{ github.token }}
SDXGEN_GITHUB_TOKEN: ${{ steps.sdxgen-token.outputs.token }}
with:
setup-script: pnpm run build
main-script: pnpm test --ci
build:
name: Build native matrix
runs-on: ubuntu-24.04
timeout-minutes: 30
outputs:
artifact-name: ${{ steps.pack.outputs.artifact-name }}
package-sha256: ${{ steps.pack.outputs.package-sha256 }}
verifier-sha256: ${{ steps.pack.outputs.verifier-sha256 }}
steps:
- name: Bootstrap checkout
shell: bash
env:
SERVER_URL: ${{ github.server_url }}
REPOSITORY: ${{ github.repository }}
TRIGGER_REF: ${{ github.sha }}
run: |
set -euo pipefail
git init -q
git remote add origin "${SERVER_URL}/${REPOSITORY}"
git fetch --no-tags --depth 1 origin "${TRIGGER_REF}"
git checkout -q --detach FETCH_HEAD
- name: Set up and install
uses: ./.github/actions/fleet/setup-and-install
with:
payload-token-client-id: ${{ secrets.SOCKET_RELEASE_CLIENT_ID || vars.SOCKET_RELEASE_CLIENT_ID }}
payload-token-private-key: ${{ secrets.SOCKET_RELEASE_APP_PRIVATE_KEY }}
socket-api-token: ${{ secrets.SOCKET_API_TOKEN_FOR_CLI_AND_SFW }}
- name: Mint sdxgen read token
id: sdxgen-token
uses: ./.github/actions/fleet/github-payload-app-token
with:
client-id: ${{ secrets.SOCKET_RELEASE_CLIENT_ID || vars.SOCKET_RELEASE_CLIENT_ID }}
private-key: ${{ secrets.SOCKET_RELEASE_APP_PRIVATE_KEY }}
repositories: sdxgen
- name: Build production CLI payload and all native targets
env:
GH_TOKEN: ${{ github.token }}
SDXGEN_GITHUB_TOKEN: ${{ steps.sdxgen-token.outputs.token }}
run: pnpm run build:native:prod
- name: Build standalone package verifier
run: pnpm run build:native:verifier
- name: Pack shipping package
id: pack
shell: bash
env:
ARTIFACT_DIR: ${{ runner.temp }}/native-package
ARTIFACT_NAME: native-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
run: |
set -euo pipefail
mkdir -p "$ARTIFACT_DIR"
pnpm pack --pack-destination "$ARTIFACT_DIR"
mv "$ARTIFACT_DIR"/*.tgz "$ARTIFACT_DIR/package.tgz"
cp build/sea/package-check.generated.mjs "$ARTIFACT_DIR/verifier.generated.mjs"
node --input-type=module <<'NODE'
import { createHash } from 'node:crypto';
import { appendFileSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
appendFileSync(process.env.GITHUB_OUTPUT, `artifact-name=${process.env.ARTIFACT_NAME}\n`);
for (const [name, file] of [['package', 'package.tgz'], ['verifier', 'verifier.generated.mjs']]) {
const hash = createHash('sha256').update(readFileSync(join(process.env.ARTIFACT_DIR, file))).digest('hex');
appendFileSync(process.env.GITHUB_OUTPUT, `${name}-sha256=${hash}\n`);
}
NODE
- name: Upload immutable native build
uses: ./.github/actions/fleet/upload-artifact
with:
name: ${{ steps.pack.outputs.artifact-name }}
path: ${{ runner.temp }}/native-package
if-no-files-found: error
- name: Test native tooling
run: pnpm run test:native
qualify:
name: Qualify (${{ matrix.target }})
needs: build
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
permissions:
actions: read
contents: read
env:
DO_NOT_TRACK: '1'
GH_TELEMETRY: '0'
strategy:
fail-fast: false
matrix:
include:
- target: darwin-arm64
runner: macos-15
- target: darwin-x64
runner: macos-15-intel
- target: linux-arm64
runner: ubuntu-24.04-arm
- target: linux-arm64-musl
runner: ubuntu-24.04-arm
musl: true
- target: linux-x64
runner: ubuntu-24.04
- target: linux-x64-musl
runner: ubuntu-24.04
musl: true
- target: win32-arm64
runner: windows-11-arm
- target: win32-x64
runner: windows-2025
steps:
- name: Set artifact directory
shell: bash
env:
ARTIFACT_DIR: ${{ runner.temp }}/native-package
run: printf 'ARTIFACT_DIR=%s\n' "$ARTIFACT_DIR" >> "$GITHUB_ENV"
- name: Download shipping package and verifier
shell: bash
env:
GH_TOKEN: ${{ github.token }}
ARTIFACT_NAME: ${{ needs.build.outputs.artifact-name }}
run: |
set -euo pipefail
node -e 'if (Number(process.versions.node.split(".")[0]) < 20) { throw new Error("Package qualification requires Node 20 or newer"); }'
gh run download "$GITHUB_RUN_ID" --repo "$GITHUB_REPOSITORY" --name "$ARTIFACT_NAME" --dir "$ARTIFACT_DIR"
- name: Verify transfer and extract package
shell: bash
env:
PACKAGE_SHA256: ${{ needs.build.outputs.package-sha256 }}
VERIFIER_SHA256: ${{ needs.build.outputs.verifier-sha256 }}
run: |
set -euo pipefail
node --input-type=module <<'NODE'
import { createHash } from 'node:crypto';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
for (const [expected, file] of [[process.env.PACKAGE_SHA256, 'package.tgz'], [process.env.VERIFIER_SHA256, 'verifier.generated.mjs']]) {
const actual = createHash('sha256').update(readFileSync(join(process.env.ARTIFACT_DIR, file))).digest('hex');
if (actual !== expected) { throw new Error(`Artifact digest mismatch: ${file}`); }
}
NODE
artifact_dir="$ARTIFACT_DIR"
if [[ "$RUNNER_OS" == "Windows" ]]; then
artifact_dir="$(cygpath -u "$artifact_dir")"
fi
archive="$artifact_dir/package.tgz"
tar -tzf "$archive" > "$artifact_dir/members.txt"
while IFS= read -r member; do
case "$member" in
/*|../*|*/../*|*/..|*\\*|*:*) echo "Unsafe package entry: $member" >&2; exit 1 ;;
package|package/*) ;;
*) echo "Unexpected package entry: $member" >&2; exit 1 ;;
esac
done < "$artifact_dir/members.txt"
tar -tvzf "$archive" > "$artifact_dir/types.txt"
while IFS= read -r member; do
case "$member" in
-*|d*) ;;
*) echo 'Package contains a link or special file' >&2; exit 1 ;;
esac
done < "$artifact_dir/types.txt"
mkdir "$artifact_dir/extracted"
tar -xzf "$archive" -C "$artifact_dir/extracted"
- name: Install musl runtime
if: ${{ matrix.musl }}
run: sudo apt-get update && sudo apt-get install --yes musl
- name: Verify and execute built target
shell: bash
env:
NATIVE_TARGET: ${{ matrix.target }}
run: node "$ARTIFACT_DIR/verifier.generated.mjs" --package-root "$ARTIFACT_DIR/extracted/package" --target "$NATIVE_TARGET" --json