mirror of
https://github.com/vercel-labs/fx.git
synced 2026-10-28 10:15:17 +08:00
Build fx with Zig 0.17.0. build.zig.zon requires it, every workflow installs it, and PGSO qualification uses LLVM 22.1.8 to match. Zig 0.17 removes `**`, `errdefer |err|`, `@cImport`, and the old type info field lists. The source moves to `@splat`, a comptime `text_utils.repeat` helper, split cleanup functions, and the new field_names and field_types arrays. The Node-API addon translates node_api.h with a build step. Test fakes checked with `@hasDecl` become pub, because `@hasDecl` no longer sees private declarations. `zig build test` gives the test binary its fx and source paths through a generated test_paths module, since the build no longer exposes install paths for environment variables. Zig 0.17's SafeAllocator grows a small allocation in place only when it sits at the end of a bucket, and buckets are never reused, so an allocation-failure sweep could count a different number of allocations on each run. Sweeps and allocation-count tests now use testing_allocator.no_resize, which never resizes in place. allocRemaining now treats its limit as inclusive. readFileToEnd keeps rejecting a file of exactly max_bytes by reading through appendRemaining. Direct allocRemaining callers for remote responses now accept a body exactly at their limit. Zig 0.17's memset stores a full vector per iteration, so the Linux memset replacement is removed. macOS release binaries now require macOS 15, Zig 0.17's default minimum.
670 lines
21 KiB
YAML
670 lines
21 KiB
YAML
name: CI
|
|
|
|
# Linux is the gate for every change. Behavior that can differ on macOS runs in
|
|
# .github/workflows/macos.yml only when a change needs it.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
acp_live:
|
|
description: Also run the full ACP suite with live model calls
|
|
type: boolean
|
|
default: false
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
|
|
concurrency:
|
|
# A manual dispatch gets its own group so it cannot cancel the push run on
|
|
# main.
|
|
group: ci-${{ github.event_name == 'workflow_dispatch' && 'dispatch-' || '' }}${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
zig_mode:
|
|
name: Build & Test (${{ matrix.optimize }})
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- optimize: ReleaseSafe
|
|
test_timeout_seconds: 1500
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Zig
|
|
id: zig
|
|
uses: ./.github/actions/setup-zig
|
|
with:
|
|
version: "0.17.0"
|
|
cache-key: ci-unit-${{ matrix.optimize }}
|
|
|
|
- name: Check formatting
|
|
run: zig fmt --check src/
|
|
|
|
- name: Validate PGSO corpus classification
|
|
run: python3 -m scripts.pgso.corpus --manifest scripts/pgso/corpus.json --list
|
|
|
|
- name: Audit public surface
|
|
run: ./scripts/check-public-surface.sh
|
|
|
|
- name: Check compactor boundary
|
|
run: ./scripts/check-compactor-boundary.sh
|
|
|
|
- name: Test CI and release scripts
|
|
run: python3 -m unittest scripts.tests.test_macos_signing scripts.tests.test_signed_macos scripts.tests.test_detect_macos_need -q
|
|
|
|
- name: Build
|
|
run: zig build -Doptimize=${{ matrix.optimize }}
|
|
|
|
- name: Test
|
|
env:
|
|
TEST_TIMEOUT_SECONDS: ${{ matrix.test_timeout_seconds }}
|
|
run: |
|
|
started_at=$SECONDS
|
|
trap 'printf "Unit tests elapsed: %ss\n" "$((SECONDS - started_at))"' EXIT
|
|
timeout "${TEST_TIMEOUT_SECONDS}s" zig build test -Doptimize=${{ matrix.optimize }}
|
|
|
|
- name: Save Zig cache
|
|
uses: ./.github/actions/save-zig-cache
|
|
with:
|
|
cache-key: ${{ steps.zig.outputs.cache-key }}
|
|
cache-hit: ${{ steps.zig.outputs.cache-hit }}
|
|
|
|
# The SDK jobs are part of this required check because Publish libfx relies
|
|
# on them instead of rerunning the package qualification before publishing.
|
|
zig:
|
|
name: Build & Test
|
|
if: ${{ always() }}
|
|
needs: [zig_mode, sdk-node-wasm, sdk-node-napi, sdk-bun, sdk-browser-wasm]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Require unit tests and every SDK job
|
|
env:
|
|
RESULTS: ${{ toJSON(needs.*.result) }}
|
|
run: |
|
|
printf '%s\n' "$RESULTS"
|
|
jq -e 'length == 5 and all(.[]; . == "success")' <<<"$RESULTS"
|
|
|
|
build:
|
|
name: Build fx (ReleaseSafe)
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 30
|
|
env:
|
|
AI_GATEWAY_API_KEY: ""
|
|
VERCEL_OIDC_TOKEN: ""
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Zig
|
|
id: zig
|
|
uses: ./.github/actions/setup-zig
|
|
with:
|
|
version: "0.17.0"
|
|
cache-key: ci-build-ReleaseSafe
|
|
|
|
# Other runners execute this binary, and their CPUs can differ from this
|
|
# one. A native build can emit instructions such as AVX-512 that those
|
|
# runners lack, so target the baseline CPU like the release builds do.
|
|
- name: Build
|
|
run: zig build -Doptimize=ReleaseSafe -Dcpu=baseline
|
|
|
|
- name: Smoke test fresh binary
|
|
run: scripts/smoke-binary.sh zig-out/bin/fx
|
|
|
|
- name: Share the binary with E2E jobs
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: fx-linux-x86_64
|
|
path: zig-out/bin/fx
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
- name: Save Zig cache
|
|
uses: ./.github/actions/save-zig-cache
|
|
with:
|
|
cache-key: ${{ steps.zig.outputs.cache-key }}
|
|
cache-hit: ${{ steps.zig.outputs.cache-hit }}
|
|
|
|
sdk-wasm:
|
|
name: SDK build (WASM)
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Zig
|
|
id: zig
|
|
uses: ./.github/actions/setup-zig
|
|
with:
|
|
version: "0.17.0"
|
|
cache-key: ci-sdk-wasm
|
|
|
|
- name: Build WASM surfaces (ReleaseSmall)
|
|
run: |
|
|
zig build fx-core-wasm -Dwasm-surface=core -Doptimize=ReleaseSmall
|
|
zig build fx-term-wasm -Dwasm-surface=term -Doptimize=ReleaseSmall
|
|
|
|
- name: Share WASM surfaces with SDK jobs
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: sdk-wasm
|
|
path: |
|
|
zig-out/bin/fx-core.wasm
|
|
zig-out/bin/fx-term.wasm
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
- name: Save Zig cache
|
|
uses: ./.github/actions/save-zig-cache
|
|
with:
|
|
cache-key: ${{ steps.zig.outputs.cache-key }}
|
|
cache-hit: ${{ steps.zig.outputs.cache-hit }}
|
|
|
|
sdk-napi:
|
|
name: SDK build (N-API, ${{ matrix.platform }})
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- platform: linux-x64
|
|
target_flags: -Dtarget=x86_64-linux-gnu.2.34 -Dcpu=baseline
|
|
- platform: linux-arm64
|
|
target_flags: -Dtarget=aarch64-linux-gnu.2.34 -Dcpu=baseline
|
|
- platform: darwin-x64
|
|
target_flags: -Dtarget=x86_64-macos -Dcpu=baseline
|
|
- platform: darwin-arm64
|
|
target_flags: -Dtarget=aarch64-macos -Dcpu=baseline
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# build.zig locates node_api.h through the node on PATH.
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "24"
|
|
|
|
- name: Setup Zig
|
|
id: zig
|
|
uses: ./.github/actions/setup-zig
|
|
with:
|
|
version: "0.17.0"
|
|
cache-key: ci-sdk-napi-${{ matrix.platform }}
|
|
|
|
- name: Build N-API addon (ReleaseSafe)
|
|
run: |
|
|
zig build libfx-napi -Dnapi-surface=core -Doptimize=ReleaseSafe ${{ matrix.target_flags }}
|
|
mkdir -p native-addons
|
|
cp zig-out/lib/libfx.node native-addons/libfx.${{ matrix.platform }}.node
|
|
|
|
- name: Share the addon with SDK jobs
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: sdk-napi-${{ matrix.platform }}
|
|
path: native-addons/libfx.${{ matrix.platform }}.node
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
- name: Save Zig cache
|
|
uses: ./.github/actions/save-zig-cache
|
|
with:
|
|
cache-key: ${{ steps.zig.outputs.cache-key }}
|
|
cache-hit: ${{ steps.zig.outputs.cache-hit }}
|
|
|
|
sdk-node-wasm:
|
|
name: SDK (Node + WASM)
|
|
needs: sdk-wasm
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "24"
|
|
|
|
- name: Download WASM surfaces
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: sdk-wasm
|
|
path: zig-out/bin
|
|
|
|
- name: Install terminal test dependencies
|
|
run: npm ci --prefix sdk/node
|
|
|
|
- name: Test Node + WASM
|
|
run: npm run --prefix sdk test:node-wasm
|
|
|
|
- name: Test libfx Wasm integrations
|
|
run: |
|
|
node --experimental-wasm-jspi sdk/tests/test-host-tools.mjs wasm
|
|
node --experimental-wasm-jspi sdk/tests/test-host-tool-cancel.mjs wasm
|
|
node --experimental-wasm-jspi sdk/tests/test-mcp-adapter.mjs http wasm
|
|
node --experimental-wasm-jspi sdk/tests/test-skills-adapter.mjs host wasm
|
|
|
|
sdk-node-napi:
|
|
name: SDK (Node + N-API)
|
|
needs: sdk-napi
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "24"
|
|
|
|
- name: Download Linux addon
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: sdk-napi-linux-x64
|
|
path: native-addons
|
|
|
|
- name: Install the addon
|
|
run: |
|
|
mkdir -p zig-out/lib
|
|
cp native-addons/libfx.linux-x64.node zig-out/lib/libfx.node
|
|
|
|
- name: Test Node + N-API
|
|
run: npm run --prefix sdk test:node-napi
|
|
|
|
- name: Test minimal native integrations
|
|
run: |
|
|
node sdk/tests/test-minimal-api.mjs
|
|
node sdk/tests/test-host-tools.mjs native
|
|
node sdk/tests/test-host-tool-cancel.mjs native
|
|
node sdk/tests/test-mcp-adapter.mjs stdio native
|
|
node sdk/tests/test-skills-adapter.mjs disk native
|
|
|
|
sdk-bun:
|
|
name: SDK (Bun + N-API/WASM)
|
|
needs: [sdk-wasm, sdk-napi]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "24"
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: "1.4.2"
|
|
|
|
- name: Download WASM surfaces
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: sdk-wasm
|
|
path: zig-out/bin
|
|
|
|
- name: Download native addons
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
pattern: sdk-napi-*
|
|
path: native-addons
|
|
merge-multiple: true
|
|
|
|
- name: Install the Linux addon
|
|
run: |
|
|
mkdir -p zig-out/lib
|
|
cp native-addons/libfx.linux-x64.node zig-out/lib/libfx.node
|
|
|
|
- name: Install terminal test dependencies
|
|
run: npm ci --prefix sdk/node
|
|
|
|
- name: Test Bun + N-API
|
|
run: bun sdk/tests/test-node-napi.mjs
|
|
|
|
- name: Test Bun + WASM
|
|
run: bun sdk/tests/test-node-wasm.mjs
|
|
|
|
- name: Test Bun benchmark path
|
|
run: bun sdk/tests/test-libfx-benchmark.mjs
|
|
|
|
- name: Test Bun cross-backend integrations
|
|
run: |
|
|
bun sdk/tests/test-agent-bootstrap.mjs auto
|
|
bun sdk/tests/test-checkpoint.mjs native wasm
|
|
bun sdk/tests/test-checkpoint.mjs wasm native
|
|
bun sdk/tests/test-host-tools.mjs native
|
|
bun sdk/tests/test-host-tools.mjs wasm
|
|
bun sdk/tests/test-host-tool-cancel.mjs native
|
|
bun sdk/tests/test-host-tool-cancel.mjs wasm
|
|
bun sdk/tests/test-mcp-adapter.mjs stdio native
|
|
bun sdk/tests/test-mcp-adapter.mjs http wasm
|
|
bun sdk/tests/test-skills-adapter.mjs disk native
|
|
bun sdk/tests/test-skills-adapter.mjs host wasm
|
|
|
|
- name: Check Linux addon compatibility
|
|
run: |
|
|
python3 sdk/tests/test-linux-abi.py
|
|
python3 sdk/scripts/check-linux-abi.py zig-out/lib/libfx.node
|
|
docker run --rm --network none --entrypoint /bin/bash \
|
|
--volume "$PWD:/workspace:ro" --workdir /workspace \
|
|
public.ecr.aws/lambda/nodejs@sha256:2472f0273d8848d8b2aa6528f5526b8a514b70703596199efe5a4b84d3d59b0b -euc '
|
|
node sdk/tests/test-native-core-ready.mjs
|
|
node sdk/tests/test-host-tools.mjs native
|
|
node sdk/tests/test-host-tool-cancel.mjs native
|
|
'
|
|
|
|
- name: Test Node package and backend diagnostics
|
|
run: |
|
|
node --experimental-wasm-jspi sdk/tests/test-backend-info.mjs
|
|
node --experimental-wasm-jspi sdk/tests/test-node-bundled-assets.mjs
|
|
node sdk/tests/test-node-package.mjs
|
|
node sdk/tests/test-term-demo-package.mjs
|
|
node sdk/scripts/package-libfx.mjs sdk/dist/libfx native-addons/libfx.linux-x64.node native-addons/libfx.linux-arm64.node native-addons/libfx.darwin-x64.node native-addons/libfx.darwin-arm64.node
|
|
node --experimental-wasm-jspi sdk/tests/test-node-async-assets.mjs sdk/dist/libfx
|
|
npm pack ./sdk/dist/libfx --ignore-scripts --json > /tmp/libfx-pack.json
|
|
mv "$(node -p 'require("/tmp/libfx-pack.json")[0].filename')" /tmp/libfx-package.tgz
|
|
node sdk/tests/test-packed-example.mjs /tmp/libfx-package.tgz native esm
|
|
node --no-experimental-require-module sdk/tests/test-packed-example.mjs /tmp/libfx-package.tgz native cjs
|
|
node --experimental-wasm-jspi sdk/tests/test-packed-example.mjs /tmp/libfx-package.tgz wasm esm
|
|
node --experimental-wasm-jspi --no-experimental-require-module sdk/tests/test-packed-example.mjs /tmp/libfx-package.tgz wasm cjs
|
|
|
|
- name: Test package recovery and lifecycle boundaries
|
|
run: |
|
|
node sdk/tests/test-package-resilience.mjs --package /tmp/libfx-package.tgz \
|
|
--cheap-cycles 100 --tool-workflows 20 --duration-ms 5000 --concurrency 4 \
|
|
--json-out "${{ runner.temp }}/libfx-package-evidence/resilience.json"
|
|
|
|
- name: Install Next fixture package manager
|
|
run: npm install --global pnpm@11.1.1
|
|
|
|
- name: Test installed package through Next
|
|
env:
|
|
LIBFX_TEST_ARTIFACT_ROOT: ${{ runner.temp }}/libfx-package-evidence
|
|
run: |
|
|
node sdk/tests/test-next-package.mjs /tmp/libfx-package.tgz
|
|
node sdk/tests/test-next-package.mjs /tmp/libfx-package.tgz --webpack
|
|
node sdk/tests/test-next-package.mjs /tmp/libfx-package.tgz --next15
|
|
|
|
- name: Retain package qualification evidence
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: libfx-next-package-evidence
|
|
path: |
|
|
${{ runner.temp }}/libfx-package-evidence/resilience.json
|
|
${{ runner.temp }}/libfx-package-evidence/libfx-next-*/*.log
|
|
${{ runner.temp }}/libfx-package-evidence/libfx-next-*/results.json
|
|
${{ runner.temp }}/libfx-package-evidence/libfx-trace-*/*.log
|
|
${{ runner.temp }}/libfx-package-evidence/libfx-trace-*/results.json
|
|
if-no-files-found: ignore
|
|
|
|
sdk-browser-wasm:
|
|
name: SDK (Browser + WASM)
|
|
needs: sdk-wasm
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "24"
|
|
|
|
- name: Setup Chrome
|
|
id: setup-chrome
|
|
uses: browser-actions/setup-chrome@v2
|
|
|
|
- name: Download WASM surfaces
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: sdk-wasm
|
|
path: zig-out/bin
|
|
|
|
- name: Test Browser + WASM
|
|
env:
|
|
CHROME_PATH: ${{ steps.setup-chrome.outputs.chrome-path }}
|
|
run: npm run --prefix sdk test:browser-wasm
|
|
|
|
e2e_mode:
|
|
name: E2E (deterministic, shard ${{ matrix.shard.label }})
|
|
needs: build
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 60
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
shard:
|
|
- index: 0
|
|
label: "1/4"
|
|
- index: 1
|
|
label: "2/4"
|
|
- index: 2
|
|
label: "3/4"
|
|
- index: 3
|
|
label: "4/4"
|
|
env:
|
|
AI_GATEWAY_API_KEY: ""
|
|
VERCEL_OIDC_TOKEN: ""
|
|
FX_REQUIRE_TMUX: "1"
|
|
SHARD_INDEX: ${{ matrix.shard.index }}
|
|
SHARD_COUNT: 4
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Download fx
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: fx-linux-x86_64
|
|
path: zig-out/bin
|
|
|
|
- name: Restore executable mode
|
|
run: chmod +x zig-out/bin/fx
|
|
|
|
# Some E2E files build their own Zig fixtures.
|
|
- name: Setup Zig
|
|
id: zig
|
|
uses: ./.github/actions/setup-zig
|
|
with:
|
|
version: "0.17.0"
|
|
cache-key: ci-e2e-fixtures
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: "1.3.14"
|
|
|
|
- name: Install E2E system dependencies
|
|
timeout-minutes: 17
|
|
run: |
|
|
missing=()
|
|
command -v tmux >/dev/null 2>&1 || missing+=(tmux)
|
|
command -v zsh >/dev/null 2>&1 || missing+=(zsh)
|
|
if [ "${#missing[@]}" -gt 0 ]; then
|
|
retry() {
|
|
local attempt
|
|
for attempt in 1 2; do
|
|
if "$@"; then
|
|
return 0
|
|
fi
|
|
if [ "$attempt" -lt 2 ]; then
|
|
printf 'Dependency install attempt %s failed; retrying in 5s\n' "$attempt" >&2
|
|
sleep 5
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
# The Azure mirror can stall after APT has already fetched release
|
|
# metadata from the direct Ubuntu fallback. Prefer that fallback
|
|
# for the whole update when the runner's mirror list provides it.
|
|
if [ -f /etc/apt/apt-mirrors.txt ] &&
|
|
grep -Eq '^https?://(archive|ports)\.ubuntu\.com/' /etc/apt/apt-mirrors.txt
|
|
then
|
|
sudo sed -i '/:\/\/azure\..*ubuntu\.com\//d' /etc/apt/apt-mirrors.txt
|
|
fi
|
|
retry sudo timeout --kill-after=15s 4m apt-get \
|
|
-o Acquire::Retries=3 \
|
|
-o Acquire::http::Timeout=30 \
|
|
-o Acquire::https::Timeout=30 \
|
|
update
|
|
retry sudo timeout --kill-after=15s 3m apt-get \
|
|
-o Dpkg::Use-Pty=0 \
|
|
install -y "${missing[@]}"
|
|
fi
|
|
printf 'set-option -g history-limit 100000\n' > "$HOME/.tmux.conf"
|
|
tmux -V
|
|
zsh --version
|
|
|
|
- name: Install E2E dependencies
|
|
run: bun install --frozen-lockfile
|
|
working-directory: tests/e2e
|
|
|
|
- name: Run deterministic E2E shard
|
|
working-directory: tests/e2e
|
|
run: |
|
|
selected=()
|
|
selection_file="$RUNNER_TEMP/fx-e2e-shard-${SHARD_INDEX}.txt"
|
|
bun ci-shards.ts \
|
|
--shard-count "$SHARD_COUNT" \
|
|
--shard-index "$SHARD_INDEX" > "$selection_file"
|
|
while IFS= read -r test_file; do
|
|
selected+=("$test_file")
|
|
done < "$selection_file"
|
|
|
|
test "${#selected[@]}" -gt 0
|
|
printf 'Running E2E shard %s/%s (%s files):\n' "$((SHARD_INDEX + 1))" "$SHARD_COUNT" "${#selected[@]}"
|
|
printf ' %s\n' "${selected[@]}"
|
|
./ci-run-files.sh "${selected[@]}"
|
|
|
|
- name: Save Zig cache
|
|
if: matrix.shard.index == 0
|
|
uses: ./.github/actions/save-zig-cache
|
|
with:
|
|
cache-key: ${{ steps.zig.outputs.cache-key }}
|
|
cache-hit: ${{ steps.zig.outputs.cache-hit }}
|
|
|
|
e2e_conformance:
|
|
name: E2E (MCP conformance)
|
|
needs: build
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 30
|
|
env:
|
|
AI_GATEWAY_API_KEY: ""
|
|
VERCEL_OIDC_TOKEN: ""
|
|
FX_SOUND: "0"
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Download fx
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: fx-linux-x86_64
|
|
path: zig-out/bin
|
|
|
|
- name: Restore executable mode
|
|
run: chmod +x zig-out/bin/fx
|
|
|
|
# The client-request-state scenario builds a Zig dispatcher fixture.
|
|
- name: Setup Zig
|
|
id: zig
|
|
uses: ./.github/actions/setup-zig
|
|
with:
|
|
version: "0.17.0"
|
|
cache-key: ci-mcp-fixtures
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: "1.3.14"
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
|
|
- name: Install E2E dependencies
|
|
run: bun install --frozen-lockfile
|
|
working-directory: tests/e2e
|
|
|
|
- name: Install isolated MCP conformance package
|
|
run: npm ci
|
|
working-directory: tests/e2e/conformance
|
|
|
|
- name: Run isolated MCP conformance baseline
|
|
run: npm test
|
|
working-directory: tests/e2e/conformance
|
|
|
|
- name: Save Zig cache
|
|
uses: ./.github/actions/save-zig-cache
|
|
with:
|
|
cache-key: ${{ steps.zig.outputs.cache-key }}
|
|
cache-hit: ${{ steps.zig.outputs.cache-hit }}
|
|
|
|
e2e:
|
|
name: E2E (deterministic)
|
|
if: ${{ always() }}
|
|
needs: [e2e_mode, e2e_conformance]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Require every shard and the conformance baseline
|
|
env:
|
|
SHARD_RESULT: ${{ needs.e2e_mode.result }}
|
|
CONFORMANCE_RESULT: ${{ needs.e2e_conformance.result }}
|
|
run: |
|
|
test "$SHARD_RESULT" = success
|
|
test "$CONFORMANCE_RESULT" = success
|
|
|
|
lint-scripts:
|
|
name: Shellcheck
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Shellcheck Fx scripts
|
|
run: |
|
|
scripts=(
|
|
benchmarks/startup.sh
|
|
scripts/check-compactor-boundary.sh
|
|
scripts/check-public-surface.sh
|
|
scripts/detect-macos-need.sh
|
|
scripts/smoke-binary.sh
|
|
tests/e2e/ci-run-files.sh
|
|
)
|
|
# bash -n parses only its first argument, so check each script.
|
|
for script in "${scripts[@]}"; do
|
|
bash -n "$script"
|
|
done
|
|
shellcheck "${scripts[@]}"
|
|
|
|
e2e_acp_live:
|
|
name: E2E ACP (live models)
|
|
if: github.event_name == 'workflow_dispatch' && inputs.acp_live
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Zig
|
|
id: zig
|
|
uses: ./.github/actions/setup-zig
|
|
with:
|
|
version: "0.17.0"
|
|
cache-key: ci-unit-ReleaseSafe
|
|
|
|
- name: Build
|
|
run: zig build -Doptimize=ReleaseSafe
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: "1.3.14"
|
|
|
|
- name: Install e2e deps
|
|
run: bun install
|
|
working-directory: tests/e2e
|
|
|
|
- name: Run full ACP tests
|
|
run: bun test acp.test.ts
|
|
working-directory: tests/e2e
|
|
env:
|
|
AI_GATEWAY_API_KEY: ${{ secrets.AI_GATEWAY_API_KEY }}
|