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
45 changes: 37 additions & 8 deletions .github/workflows/abi-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@

name: ABI Drift Gate

# Was workflow-level path-filtered: a required check that never ran on PRs
# touching none of its paths, leaving the check "Expected" and the PR blocked.
# Now always runs; the `changes` job gates the heavy `verify` job, which when
# skipped reports SUCCESS to required checks. (verify also does its own
# per-cartridge scoping for the relevant case.)
on:
push:
branches: [main]
paths:
- 'cartridges/**/abi/**'
- 'cartridges/**/ffi/**'
- '.github/workflows/abi-drift.yml'
pull_request:
branches: [main]
paths:
- 'cartridges/**/abi/**'
- 'cartridges/**/ffi/**'
- '.github/workflows/abi-drift.yml'
workflow_dispatch:

concurrency:
group: abi-drift-${{ github.workflow }}-${{ github.ref }}
Expand All @@ -38,8 +36,39 @@ 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: |
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 '^cartridges/.*/abi/|^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 '^cartridges/.*/abi/|^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>}"

verify:
name: Emit manifest + verify FFI
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down
50 changes: 36 additions & 14 deletions .github/workflows/backend-assurance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,16 @@

name: Backend-Assurance Harness

# Was workflow-level path-filtered: a required check that never ran on PRs
# touching none of its paths, leaving the check "Expected" and the PR blocked.
# Now always runs; the `changes` job gates the heavy job, which when skipped
# reports SUCCESS to required checks.
on:
push:
branches: [main]
paths:
- 'src/abi/Boj/SafetyLemmas.idr'
- 'elixir/test/backend_assurance/**'
- 'elixir/mix.exs'
- 'elixir/mix.lock'
- 'docs/backend-assurance/**'
- '.github/workflows/backend-assurance.yml'
pull_request:
branches: [main]
paths:
- 'src/abi/Boj/SafetyLemmas.idr'
- 'elixir/test/backend_assurance/**'
- 'elixir/mix.exs'
- 'elixir/mix.lock'
- 'docs/backend-assurance/**'
- '.github/workflows/backend-assurance.yml'
workflow_dispatch:

concurrency:
group: backend-assurance-${{ github.workflow }}-${{ github.ref }}
Expand All @@ -46,8 +37,39 @@ 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: |
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 '^src/abi/Boj/SafetyLemmas\.idr$|^elixir/test/backend_assurance/|^elixir/mix\.(exs|lock)$|^docs/backend-assurance/' && 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 '^src/abi/Boj/SafetyLemmas\.idr$|^elixir/test/backend_assurance/|^elixir/mix\.(exs|lock)$|^docs/backend-assurance/' && run=true || run=false; }
fi
printf 'run=%s\n' "$run" >> "$GITHUB_OUTPUT"
echo "relevant=$run; changed files:"; printf '%s\n' "${changed:-<none computed>}"

property-test:
name: BEAM property tests
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
Expand Down
59 changes: 43 additions & 16 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,15 @@

name: E2E + Aspect + Bench

# Was workflow-level path-filtered: required checks that never ran on PRs
# touching none of its paths, leaving them "Expected" and the PR blocked.
# Now always runs; the `changes` job gates the heavy jobs, which when skipped
# report SUCCESS to required checks.
on:
push:
branches: [main, master, develop]
paths:
- 'adapter/**'
- 'cartridges/**'
- 'ffi/**'
- 'mcp-bridge/**'
- 'tests/**'
- 'src/**'
- '.github/workflows/e2e.yml'
pull_request:
branches: [main, master]
paths:
- 'adapter/**'
- 'cartridges/**'
- 'ffi/**'
- 'mcp-bridge/**'
- 'tests/**'
- 'src/**'
- '.github/workflows/e2e.yml'
workflow_dispatch:

permissions: read-all
Expand All @@ -37,9 +25,40 @@ concurrency:
cancel-in-progress: true

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: |
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 '^adapter/|^cartridges/|^ffi/|^mcp-bridge/|^tests/|^src/' && 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 '^adapter/|^cartridges/|^ffi/|^mcp-bridge/|^tests/|^src/' && run=true || run=false; }
fi
printf 'run=%s\n' "$run" >> "$GITHUB_OUTPUT"
echo "relevant=$run; changed files:"; printf '%s\n' "${changed:-<none computed>}"

# ─── End-to-End: Full REST + MCP Bridge ────────────────────────────
e2e-full:
name: E2E — Full REST + MCP Bridge
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15

Expand Down Expand Up @@ -104,6 +123,8 @@ jobs:
# ─── End-to-End: Order Ticket (FFI layer) ──────────────────────────
e2e-order-ticket:
name: E2E — Order Ticket (FFI layer)
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10

Expand All @@ -125,6 +146,8 @@ jobs:
# ─── Aspect Tests: Cross-Cutting Concerns ──────────────────────────
aspect-tests:
name: Aspect — Thread Safety + ABI Contract + SPDX
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10

Expand All @@ -138,6 +161,8 @@ jobs:
# ─── Benchmarks: Performance Regression Detection ──────────────────
benchmarks:
name: Bench — FFI Catalogue + Mount/Unmount + Hash
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15

Expand Down Expand Up @@ -231,6 +256,8 @@ jobs:
# deltas across pushes are visible inline.
bench-bridge:
name: Bench — mcp-bridge (path-claims)
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
Expand Down
55 changes: 44 additions & 11 deletions .github/workflows/lsp-dap-bsp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@

name: LSP/DAP/BSP CI

# Was workflow-level path-filtered: required checks that never ran on PRs
# touching none of its paths, leaving them "Expected" and the PR blocked.
# Now always runs; the `changes` job gates the heavy jobs, which when skipped
# report SUCCESS to required checks.
on:
push:
paths:
- 'cartridges/lsp-mcp/**'
- 'cartridges/dap-mcp/**'
- 'cartridges/bsp-mcp/**'
- 'src/abi/Boj/Protocol.idr'
- '.github/workflows/lsp-dap-bsp.yml'
branches: [main]
pull_request:
paths:
- 'cartridges/lsp-mcp/**'
- 'cartridges/dap-mcp/**'
- 'cartridges/bsp-mcp/**'
branches: [main]
workflow_dispatch:

permissions: read-all

Expand All @@ -26,8 +23,39 @@ concurrency:
cancel-in-progress: true

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: |
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 '^cartridges/(lsp|dap|bsp)-mcp/|^src/abi/Boj/Protocol\.idr$' && 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 '^cartridges/(lsp|dap|bsp)-mcp/|^src/abi/Boj/Protocol\.idr$' && run=true || run=false; }
fi
printf 'run=%s\n' "$run" >> "$GITHUB_OUTPUT"
echo "relevant=$run; changed files:"; printf '%s\n' "${changed:-<none computed>}"

abi-check:
name: ABI Specification Check (Idris2)
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
Expand Down Expand Up @@ -62,6 +90,8 @@ jobs:

ffi-build:
name: FFI Build & Test (Zig)
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
Expand Down Expand Up @@ -107,6 +137,8 @@ jobs:

panel-validation:
name: Panel Manifest Validation
needs: changes
if: needs.changes.outputs.run == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
Expand Down Expand Up @@ -141,7 +173,8 @@ jobs:
name: Cartridge Completeness Check
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [abi-check, ffi-build, panel-validation]
needs: [changes, abi-check, ffi-build, panel-validation]
if: needs.changes.outputs.run == 'true'
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Verify triadic structure
Expand Down
Loading
Loading