Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion .github/workflows/abi-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
# Need at least two commits so `git diff origin/<base>...HEAD`
# can compute the changed-cartridge set on pull_request events.
# `0` = full history (cheap on this repo).
fetch-depth: 0

- name: Install Rust toolchain (stable)
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # stable
Expand Down Expand Up @@ -165,11 +170,59 @@ jobs:
echo 'EOF'
} >> "$GITHUB_OUTPUT"

- name: Emit + verify each cartridge
# On pull_request, restrict the verify loop to cartridges that
# actually changed in this PR — unrelated cartridge drift is the
# main branch's problem, not this PR's. On push to main, scan the
# full allowlist so cross-cutting regressions are still caught at
# trunk. Empty changed-set on a PR ⇒ skip the loop (handled in
# the verify step's defensive empty check below).
#
# Single output, always-correct: scope.outputs.carts is the
# PR-filtered allowlist on pull_request, the full allowlist on
# push. Avoids the `${{ X && Y || Z }}` ternary footgun where Y
# being an empty string short-circuits to Z (which would silently
# re-expand to the full sweep — exactly the bug we're trying to
# fix).
- name: Scope cartridges to verify
id: scope
env:
EVENT: ${{ github.event_name }}
BASE_REF: ${{ github.base_ref }}
CARTS: ${{ steps.discover.outputs.carts }}
run: |
set -euo pipefail
if [ "$EVENT" = "pull_request" ]; then
git fetch --no-tags --depth=50 origin "$BASE_REF" || true
changed=$(git diff --name-only "origin/${BASE_REF}...HEAD" -- 'cartridges/**' \
| awk -F/ '{print $2}' | sort -u)
scope=""
while IFS= read -r cart; do
[ -z "$cart" ] && continue
if printf '%s\n' "$changed" | grep -qx "$cart"; then
scope="${scope}${cart}"$'\n'
fi
done <<< "$CARTS"
else
scope="$CARTS"
fi
{
echo 'carts<<EOF'
printf '%s' "$scope"
echo
echo 'EOF'
} >> "$GITHUB_OUTPUT"
echo "Cartridges in scope for this run:"
printf ' • %s\n' $(printf '%s\n' "$scope" | grep -v '^$' || true)

- name: Emit + verify each cartridge
env:
CARTS: ${{ steps.scope.outputs.carts }}
run: |
set -euo pipefail
if [ -z "$(printf '%s' "$CARTS" | tr -d '[:space:]')" ]; then
echo "::notice::No allowlisted cartridges changed in this PR — skipping drift verify."
exit 0
fi
failed=""
while IFS= read -r cart; do
[ -z "$cart" ] && continue
Expand Down
67 changes: 61 additions & 6 deletions .github/workflows/zig-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ on:
paths:
- 'ffi/**'
- 'cartridges/**/ffi/**'
- '.github/workflows/zig-test.yml'
pull_request:
branches: [main]
paths:
- 'ffi/**'
- 'cartridges/**/ffi/**'
- '.github/workflows/zig-test.yml'

permissions:
contents: read
Expand All @@ -26,22 +28,68 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
# Needed so `git diff origin/<base>...HEAD` can identify the
# cartridges actually changed in this PR. Full history is cheap
# on this repo; cuts down on cross-cartridge false-positive
# gating where a PR is blocked by pre-existing breakage in
# unrelated cartridges (browser-mcp, orchestrator-lsp-mcp,
# etc.). On push/main we keep the full per-cartridge sweep.
fetch-depth: 0

- name: Install Zig
uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2
with:
version: 0.15.2

- name: Determine cartridges to test
id: scope
env:
EVENT: ${{ github.event_name }}
BASE_REF: ${{ github.base_ref }}
run: |
set -euo pipefail
all="$(ls -d cartridges/*/ffi/ 2>/dev/null | sed 's|cartridges/||;s|/ffi/||' | sort)"
if [ "$EVENT" = "pull_request" ]; then
git fetch --no-tags --depth=50 origin "$BASE_REF" || true
changed="$(git diff --name-only "origin/${BASE_REF}...HEAD" -- 'cartridges/**' \
| awk -F/ '{print $2}' | sort -u)"
scope=""
while IFS= read -r cart; do
[ -z "$cart" ] && continue
if printf '%s\n' "$changed" | grep -qx "$cart"; then
scope="$scope$cart"$'\n'
fi
done <<< "$all"
else
scope="$all"
fi
{
echo 'carts<<EOF'
printf '%s' "$scope"
echo
echo 'EOF'
} >> "$GITHUB_OUTPUT"
echo "Cartridges in scope for this run:"
printf ' • %s\n' $(printf '%s\n' "$scope" | grep -v '^$' || true)

- name: Run catalogue tests
run: cd ffi/zig && zig build test --summary all

- name: Run readiness tests
run: cd ffi/zig && zig build readiness --summary all

- name: Run cartridge FFI tests (all 73 cartridges)
- name: Run cartridge FFI tests
env:
CARTS: ${{ steps.scope.outputs.carts }}
run: |
if [ -z "$(printf '%s' "$CARTS" | tr -d '[:space:]')" ]; then
echo "::notice::No cartridges changed in this PR — skipping per-cartridge FFI tests."
exit 0
fi
failed=""
for cart in $(ls -d cartridges/*/ffi/ 2>/dev/null | sed 's|cartridges/||;s|/ffi/||' | sort); do
while IFS= read -r cart; do
[ -z "$cart" ] && continue
echo "::group::Testing $cart..."
if cd "cartridges/$cart/ffi" && zig build test --summary all 2>&1; then
echo " ✓ $cart passed"
Expand All @@ -51,19 +99,26 @@ jobs:
fi
cd "$GITHUB_WORKSPACE"
echo "::endgroup::"
done
done <<< "$CARTS"
if [ -n "$failed" ]; then
echo "::error::Failed cartridges:$failed"
exit 1
fi

- name: Build cartridge shared libraries (all 73 cartridges)
- name: Build cartridge shared libraries
env:
CARTS: ${{ steps.scope.outputs.carts }}
run: |
for cart in $(ls -d cartridges/*/ffi/ 2>/dev/null | sed 's|cartridges/||;s|/ffi/||' | sort); do
if [ -z "$(printf '%s' "$CARTS" | tr -d '[:space:]')" ]; then
echo "::notice::No cartridges changed in this PR — skipping per-cartridge .so build."
exit 0
fi
while IFS= read -r cart; do
[ -z "$cart" ] && continue
echo "Building $cart .so..."
cd "cartridges/$cart/ffi" && zig build
cd "$GITHUB_WORKSPACE"
done
done <<< "$CARTS"

- name: Build static library
run: cd ffi/zig && zig build lib
Expand Down
Loading