Add Cloudflare Pages Direct Upload fallback deploy Action (#245) #240
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-License-Identifier: MPL-2.0 | |
| # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> | |
| # | |
| # BoJ Server — Zig FFI test & build pipeline | |
| name: Zig FFI Tests | |
| # NOTE: this workflow used to be workflow-level path-filtered (on.*.paths). | |
| # That made it a REQUIRED check that simply never ran on PRs touching none of | |
| # its paths — GitHub then left the check "Expected" forever and the PR sat at | |
| # mergeable_state=blocked. It now always runs; a lightweight `changes` job | |
| # decides whether the heavy `test` job is needed. A job skipped via `if:` | |
| # reports SUCCESS to required status checks, so the required context is always | |
| # satisfied without running heavy work on unrelated PRs. | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| changes: | |
| name: Detect relevant changes | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| run: ${{ steps.detect.outputs.run }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| - id: detect | |
| env: | |
| EVENT: ${{ github.event_name }} | |
| BASE: ${{ github.base_ref }} | |
| BEFORE: ${{ github.event.before }} | |
| run: | | |
| # Fail-safe: default to running; only set run=false when a successful | |
| # diff shows NOTHING in this gate's path set changed. | |
| set -uo pipefail | |
| run=true | |
| if [ "$EVENT" = pull_request ]; then | |
| git fetch --no-tags --depth=200 origin "$BASE" 2>/dev/null \ | |
| && changed=$(git diff --name-only "origin/${BASE}...HEAD" 2>/dev/null) \ | |
| && { printf '%s\n' "$changed" | grep -qE '^ffi/|^cartridges/.*/ffi/' && run=true || run=false; } | |
| elif [ "$EVENT" = push ] && [ -n "$BEFORE" ] && [ "$BEFORE" != 0000000000000000000000000000000000000000 ]; then | |
| changed=$(git diff --name-only "${BEFORE}...${GITHUB_SHA}" 2>/dev/null) \ | |
| && { printf '%s\n' "$changed" | grep -qE '^ffi/|^cartridges/.*/ffi/' && run=true || run=false; } | |
| fi | |
| printf 'run=%s\n' "$run" >> "$GITHUB_OUTPUT" | |
| echo "relevant=$run; changed files:"; printf '%s\n' "${changed:-<none computed>}" | |
| test: | |
| name: Zig FFI Tests | |
| needs: changes | |
| if: needs.changes.outputs.run == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| 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 | |
| # Only scope cartridges whose `ffi/` actually changed — | |
| # `cartridge.json` edits (e.g. adding a status field) and | |
| # `abi/` edits should not pull a cart into this FFI test | |
| # job, which exists to validate Zig builds. Using | |
| # `cartridges/*/ffi/**` as the pathspec ensures only | |
| # ffi-relevant diffs count (also matches the workflow's | |
| # own `on.paths` filter — they were inconsistent before). | |
| changed="$(git diff --name-only "origin/${BASE_REF}...HEAD" -- 'cartridges/*/ffi/**' \ | |
| | 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 | |
| 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="" | |
| 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" | |
| else | |
| echo " ✗ $cart FAILED" | |
| failed="$failed $cart" | |
| fi | |
| cd "$GITHUB_WORKSPACE" | |
| echo "::endgroup::" | |
| done <<< "$CARTS" | |
| if [ -n "$failed" ]; then | |
| echo "::error::Failed cartridges:$failed" | |
| exit 1 | |
| fi | |
| - name: Build cartridge shared libraries | |
| 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 .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 <<< "$CARTS" | |
| - name: Build static library | |
| run: cd ffi/zig && zig build lib | |
| - name: Run benchmarks | |
| run: cd ffi/zig && zig build bench |