-
Notifications
You must be signed in to change notification settings - Fork 5
485 lines (396 loc) · 15.4 KB
/
release.yml
File metadata and controls
485 lines (396 loc) · 15.4 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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
name: Release
on:
push:
tags:
- "v*"
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: write
id-token: write
env:
CARGO_TERM_COLOR: always
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
test:
name: Test
# Pin to ubuntu-22.04 to match tests.yml — the previous ubuntu-latest
# mismatch contributed to release runs that ran far longer than PR-time
# CI on the same code (no shared rust-cache between PR and release runs
# either). Keeping both workflows on the same image + cache prevents
# surprise behavior differences at release time.
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Rust tests
run: cargo test --workspace
- name: Build aft binary (needed for e2e tests)
run: cargo build -p agent-file-tools
- name: Install JS dependencies
run: bun install
- name: Build aft-bridge (consumers need its dist/ for typecheck)
# Workspace consumers (opencode-plugin, pi-plugin) import from
# @cortexkit/aft-bridge. Bun resolves to the workspace package whose
# dist/ doesn't exist yet (gitignored). Build it first so tsc can
# find its .d.ts files. Required because v0.19.0 hasn't published yet
# (publish-npm runs AFTER this Test job).
run: bun run --cwd packages/aft-bridge build
- name: TypeScript typecheck
run: bun run typecheck
- name: Plugin tests
run: bun run test
- name: Lint
run: bun run lint
- name: Build all JS packages (gate publish)
run: bun run --filter '*' build
# macOS unit-test gate — mirrors the Linux `test` job's cargo + plugin test
# coverage on a real macOS runner. The build-darwin-* jobs below only run
# `cargo build --release`, not `cargo test`, so this is the only place where
# macOS-specific code paths are actually exercised at release time:
# - FSEvents watcher behavior (different coalescing latency from inotify)
# - /var vs /private/var symlink canonicalization
# - Broken-symlink-chain fallback in context.rs
# - bash_background SIGTERM behavior on Apple Silicon
# Lint and `bun run --filter '*' build` only run in the Linux `test` job —
# they are platform-independent so duplicating them on macOS adds no signal.
test-macos:
name: Test (macOS)
runs-on: macos-latest
# Mirror tests.yml's rust-macos timeout. Without this the job inherits
# GitHub Actions' 6h default, which means a flaky macos-latest runner
# that hangs (e.g. stuck network call, frozen test process) keeps the
# whole release blocked for 6 hours before failing. 25min is plenty
# for the actual workload (~3min on a healthy runner) and gives us
# logs instead of a runner timeout.
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Rust tests
run: cargo test --workspace
- name: Install JS dependencies
run: bun install
- name: Build aft-bridge (consumers need its dist/ for typecheck)
run: bun run --cwd packages/aft-bridge build
- name: TypeScript typecheck
run: bun run typecheck
- name: Plugin tests
run: bun run test
env:
AFT_CACHE_DIR: ${{ runner.temp }}/aft-cache
# Bash permission flow on Windows — release-time mirror of the
# bun-windows-bash job in tests.yml. Verifies the runAsk + Effect runtime
# path through real BinaryBridge spawning aft.exe over stdio NDJSON on
# the Windows process model. Scoped to bash.test.ts only because the
# full bun suite blocks on integration-harness JSON-path escape issues
# (see rust-windows comment in tests.yml). continue-on-error is ON for
# now; promote to required once we have stable green runs.
test-windows-bash:
name: Test (Windows — bash permission e2e)
runs-on: windows-2022
timeout-minutes: 20
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install workspace deps
run: bun install --frozen-lockfile
shell: pwsh
- name: Build aft-bridge dist (workspace consumers depend on it)
run: bun run --cwd packages/aft-bridge build
shell: pwsh
- name: Cargo build (debug — bash.test.ts spawns the real aft binary)
run: cargo build -p agent-file-tools
shell: pwsh
- name: Bun test (bash permission flow — full bridge + plugin + Rust)
run: bun test src/__tests__/e2e/bash.test.ts
working-directory: packages/opencode-plugin
shell: pwsh
env:
AFT_CACHE_DIR: ${{ runner.temp }}/aft-cache
# Run the full E2E matrix (Linux Docker + Windows native + macOS native) at
# release time. Reuses the same workflow tests.yml runs at PR time — single
# source of truth, so PR-time and release-time e2e can never drift.
# Build/publish jobs below `needs:` this job, so an e2e regression blocks
# the release.
e2e:
name: E2E
needs: [test, test-macos]
uses: ./.github/workflows/_e2e-suite.yml
publish-crates:
name: Publish to crates.io
runs-on: ubuntu-latest
needs: [test, e2e]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
# Allow re-runs of the same tag: treat "already exists" as success.
run: cargo publish --package agent-file-tools || { ec=$?; cargo publish --package agent-file-tools --dry-run 2>&1 | grep -q "already exists" && exit 0 || exit $ec; }
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
build-darwin-arm64:
name: Build macOS ARM64
runs-on: macos-latest
needs: [test, e2e]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin
- name: Build
run: cargo build --release --target aarch64-apple-darwin
- name: Strip binary
run: strip target/aarch64-apple-darwin/release/aft
- uses: actions/upload-artifact@v4
with:
name: darwin-arm64
path: target/aarch64-apple-darwin/release/aft
if-no-files-found: error
build-darwin-x64:
name: Build macOS x64
runs-on: macos-latest
needs: [test, e2e]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-apple-darwin
- name: Build
run: cargo build --release --target x86_64-apple-darwin
- name: Strip binary
run: strip target/x86_64-apple-darwin/release/aft
- uses: actions/upload-artifact@v4
with:
name: darwin-x64
path: target/x86_64-apple-darwin/release/aft
if-no-files-found: error
build-linux-arm64:
name: Build Linux ARM64
runs-on: ubuntu-latest
needs: [test, e2e]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-unknown-linux-gnu
- name: Install cross
run: cargo install cross --version 0.2.5 --locked
# Use gnu target (not musl) so dlopen works for ONNX Runtime loading.
# musl produces static binaries where dlopen is a stub that always fails.
- name: Build
run: cross build --release --target aarch64-unknown-linux-gnu
- uses: actions/upload-artifact@v4
with:
name: linux-arm64
path: target/aarch64-unknown-linux-gnu/release/aft
if-no-files-found: error
build-linux-x64:
name: Build Linux x64
# Build on Ubuntu 22.04 to link against GLIBC 2.35 — compatible with
# Ubuntu 22.04 LTS (supported until 2027), Pop!OS 22.04, Debian 12+,
# and any distro with GLIBC >= 2.35. Using ubuntu-latest (24.04) would
# require GLIBC 2.39 and break older LTS users.
runs-on: ubuntu-22.04
needs: [test, e2e]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
# Native x64 build on Ubuntu runner — no cross-compilation needed.
# Uses gnu target (not musl) so dlopen works for ONNX Runtime loading.
- name: Build
run: cargo build --release
- uses: actions/upload-artifact@v4
with:
name: linux-x64
path: target/release/aft
if-no-files-found: error
build-win32-x64:
name: Build Windows x64
runs-on: windows-latest
needs: [test, e2e]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-pc-windows-msvc
- name: Build
run: cargo build --release --target x86_64-pc-windows-msvc
- uses: actions/upload-artifact@v4
with:
name: win32-x64
path: target/x86_64-pc-windows-msvc/release/aft.exe
if-no-files-found: error
# npm publish runs AFTER github-release so that checksums.sha256 is already
# available on the GitHub release page when ensureBinary() runs during
# @cortexkit/aft-opencode@latest install.
publish-npm:
name: Publish to npm
runs-on: ubuntu-latest
needs:
- build-darwin-arm64
- build-darwin-x64
- build-linux-arm64
- build-linux-x64
- build-win32-x64
- github-release
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Ensure latest npm (for trusted publishing)
run: npm install -g npm@latest
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Download darwin-arm64 binary
uses: actions/download-artifact@v4
with:
name: darwin-arm64
path: packages/npm/darwin-arm64/bin
- name: Download darwin-x64 binary
uses: actions/download-artifact@v4
with:
name: darwin-x64
path: packages/npm/darwin-x64/bin
- name: Download linux-arm64 binary
uses: actions/download-artifact@v4
with:
name: linux-arm64
path: packages/npm/linux-arm64/bin
- name: Download linux-x64 binary
uses: actions/download-artifact@v4
with:
name: linux-x64
path: packages/npm/linux-x64/bin
- name: Download win32-x64 binary
uses: actions/download-artifact@v4
with:
name: win32-x64
path: packages/npm/win32-x64/bin
- name: Set binary permissions
run: |
chmod +x packages/npm/darwin-arm64/bin/aft
chmod +x packages/npm/darwin-x64/bin/aft
chmod +x packages/npm/linux-arm64/bin/aft
chmod +x packages/npm/linux-x64/bin/aft
- name: Sync versions from tag
run: node scripts/version-sync.mjs --from-tag
- name: Validate packages
run: node scripts/validate-packages.mjs
- name: Install bridge dependencies
run: bun install
working-directory: packages/aft-bridge
- name: Build aft-bridge
run: bun run build
working-directory: packages/aft-bridge
- name: Install plugin dependencies
run: bun install
working-directory: packages/opencode-plugin
- name: Build OpenCode plugin
run: bun run build
working-directory: packages/opencode-plugin
- name: Install Pi plugin dependencies
run: bun install
working-directory: packages/pi-plugin
- name: Build Pi plugin
run: bun run build
working-directory: packages/pi-plugin
- name: Install CLI dependencies
run: bun install
working-directory: packages/aft-cli
- name: Build CLI
run: bun run build
working-directory: packages/aft-cli
# Uses npm Trusted Publishing (OIDC) — configured per-package on npmjs.com
- name: Publish platform packages
run: |
for pkg in darwin-arm64 darwin-x64 linux-arm64 linux-x64 win32-x64; do
npm publish --access public --provenance "packages/npm/$pkg"
done
# aft-bridge MUST publish before the plugins, because @cortexkit/aft-opencode
# and @cortexkit/aft-pi depend on it. Plugins publish from local builds, so
# there's no install-time race here, but consumers installing @latest will
# need aft-bridge resolvable on npm.
#
# Tolerate `already published` so a re-run of the same tag (or the
# initial bootstrap publish that claims the package name with a
# token before Trusted Publishing is configured) doesn't fail the
# whole release. Mirrors the crates.io publish step above.
- name: Publish @cortexkit/aft-bridge
run: |
set +e
out=$(npm publish --access public --provenance 2>&1)
ec=$?
echo "$out"
if [ $ec -ne 0 ] && echo "$out" | grep -q "cannot publish over the previously published versions"; then
echo "::notice::aft-bridge version already published; treating as success"
exit 0
fi
exit $ec
working-directory: packages/aft-bridge
- name: Publish @cortexkit/aft-opencode
run: npm publish --access public --provenance
working-directory: packages/opencode-plugin
- name: Publish @cortexkit/aft-pi
run: npm publish --access public --provenance
working-directory: packages/pi-plugin
- name: Publish @cortexkit/aft (unified CLI)
run: npm publish --access public --provenance
working-directory: packages/aft-cli
# GitHub release must complete before npm publish so that checksums.sha256
# is available when freshly-installed @cortexkit/aft-opencode@latest triggers
# ensureBinary(). crates.io publish is also gated so that a failed crate
# publish blocks the release — no point shipping binaries if the Rust crate
# isn't available yet.
github-release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs:
- build-darwin-arm64
- build-darwin-x64
- build-linux-arm64
- build-linux-x64
- build-win32-x64
- publish-crates
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Prepare release assets
run: |
mkdir -p release-assets
cp artifacts/darwin-arm64/aft release-assets/aft-darwin-arm64
cp artifacts/darwin-x64/aft release-assets/aft-darwin-x64
cp artifacts/linux-arm64/aft release-assets/aft-linux-arm64
cp artifacts/linux-x64/aft release-assets/aft-linux-x64
cp artifacts/win32-x64/aft.exe release-assets/aft-win32-x64.exe
chmod +x release-assets/aft-*
- name: Generate checksums
run: |
cd release-assets
sha256sum aft-* > checksums.sha256
cat checksums.sha256
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: release-assets/*