ci: add the delta-gate workflow for the capped functional lane
workflow_dispatch, runs-on gate-functional — a host-mode, Bun-only lane with no Node.js runtime, so every step is plain git + bun in shell rather than a JS-based action. Clones candidate and control, runs the full vitest suite on each, enforces a >=3,000-collected guard per side, and diffs the two fail lists for genuinely new reds. The lane's own tripwire marker (host pressure — never our own red or green) is checked before the verdict is printed, and the job cleans up its own checkouts so repeat runs don't feed the lane's disk-budget trip.
This commit is contained in:
parent
2633e8d5e1
commit
9922631d1f
1 changed files with 127 additions and 0 deletions
127
.forgejo/workflows/delta-gate.yml
Normal file
127
.forgejo/workflows/delta-gate.yml
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
name: Delta Gate
|
||||||
|
|
||||||
|
# On-demand candidate-vs-control gate on the capped functional CI lane
|
||||||
|
# (label: gate-functional). That lane is Bun-only host-mode — there is no
|
||||||
|
# Node.js runtime available to it, so this workflow deliberately avoids every
|
||||||
|
# JS-based action (checkout/setup-node/setup-bun/upload-artifact all require
|
||||||
|
# one) and does everything with plain git + bun in shell steps instead.
|
||||||
|
#
|
||||||
|
# Verdict lines a caller should grep for in the run log:
|
||||||
|
# COLLECTED patch=<n> control=<n> — collection-truncation guard inputs
|
||||||
|
# NEW-RED-COUNT:<n> — failures on candidate absent from control
|
||||||
|
# DELTA-GATE: CLEAN | NEW REDS | INVALID | STOPPED-BY-REGISTRY-TRIPWIRE
|
||||||
|
#
|
||||||
|
# The lane's own housekeeping stops the runner and drops a marker file when
|
||||||
|
# host pressure (I/O, registry latency, disk budget) trips — never ours to
|
||||||
|
# interpret as a red or a green. The final step checks for that marker before
|
||||||
|
# it says anything about pass/fail.
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
candidate:
|
||||||
|
description: 'Candidate ref (branch or sha) to gate'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
control:
|
||||||
|
description: 'Control sha to diff against'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: delta-gate
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
delta-gate:
|
||||||
|
name: Delta gate — candidate vs control
|
||||||
|
runs-on: gate-functional
|
||||||
|
timeout-minutes: 120
|
||||||
|
steps:
|
||||||
|
- name: Clean any residue from a prior run
|
||||||
|
run: rm -rf "ob-cand-${{ github.run_id }}" "ob-ctrl-${{ github.run_id }}" "/tmp/ob-${{ github.run_id }}-"*
|
||||||
|
|
||||||
|
- name: Clone + test — candidate
|
||||||
|
id: patch
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
git clone --quiet "https://source.soulcraft.com/soulcraftlabs/open-brainy.git" "ob-cand-${{ github.run_id }}"
|
||||||
|
cd "ob-cand-${{ github.run_id }}"
|
||||||
|
git checkout --quiet "${{ github.event.inputs.candidate }}"
|
||||||
|
git log --oneline -1
|
||||||
|
bun install
|
||||||
|
rc=0
|
||||||
|
bun x vitest run > "/tmp/ob-${{ github.run_id }}-patch.log" 2>&1 || rc=$?
|
||||||
|
echo "PATCH-RC:$rc"
|
||||||
|
grep -aE "Tests .*(passed|failed)" "/tmp/ob-${{ github.run_id }}-patch.log" | tail -1
|
||||||
|
grep -aE "^ FAIL |^\s+×" "/tmp/ob-${{ github.run_id }}-patch.log" | sed -E "s/ [0-9]+ms$//" | sed -E "s/^\s+//" | sort -u > "/tmp/ob-${{ github.run_id }}-patch.fail"
|
||||||
|
echo "PATCH-FAILING:$(wc -l < "/tmp/ob-${{ github.run_id }}-patch.fail")"
|
||||||
|
|
||||||
|
- name: Clone + test — control
|
||||||
|
id: control
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
git clone --quiet "https://source.soulcraft.com/soulcraftlabs/open-brainy.git" "ob-ctrl-${{ github.run_id }}"
|
||||||
|
cd "ob-ctrl-${{ github.run_id }}"
|
||||||
|
git checkout --quiet "${{ github.event.inputs.control }}"
|
||||||
|
git log --oneline -1
|
||||||
|
bun install
|
||||||
|
rc=0
|
||||||
|
bun x vitest run > "/tmp/ob-${{ github.run_id }}-control.log" 2>&1 || rc=$?
|
||||||
|
echo "CONTROL-RC:$rc"
|
||||||
|
grep -aE "Tests .*(passed|failed)" "/tmp/ob-${{ github.run_id }}-control.log" | tail -1
|
||||||
|
grep -aE "^ FAIL |^\s+×" "/tmp/ob-${{ github.run_id }}-control.log" | sed -E "s/ [0-9]+ms$//" | sed -E "s/^\s+//" | sort -u > "/tmp/ob-${{ github.run_id }}-control.fail"
|
||||||
|
echo "CONTROL-FAILING:$(wc -l < "/tmp/ob-${{ github.run_id }}-control.fail")"
|
||||||
|
|
||||||
|
- name: Delta gate verdict
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# The lane's own tripwire wins over anything we would otherwise say:
|
||||||
|
# a bare failure/timeout above with this marker present is host
|
||||||
|
# pressure, never a real red and never a real green.
|
||||||
|
if [ -f /srv/gate-lane/TRIPWIRE-STOPPED ]; then
|
||||||
|
echo "DELTA-GATE: STOPPED-BY-REGISTRY-TRIPWIRE"
|
||||||
|
head -1 /srv/gate-lane/TRIPWIRE-STOPPED
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
patch_log="/tmp/ob-${{ github.run_id }}-patch.log"
|
||||||
|
control_log="/tmp/ob-${{ github.run_id }}-control.log"
|
||||||
|
patch_fail="/tmp/ob-${{ github.run_id }}-patch.fail"
|
||||||
|
control_fail="/tmp/ob-${{ github.run_id }}-control.fail"
|
||||||
|
|
||||||
|
if [ ! -s "$patch_log" ] || [ ! -s "$control_log" ]; then
|
||||||
|
echo "DELTA-GATE: INVALID — a leg produced no log (see the two steps above for the real cause)"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
pt=$(grep -aoE "\(([0-9]+)\)$" "$patch_log" | tail -1 | tr -d "()")
|
||||||
|
ct=$(grep -aoE "\(([0-9]+)\)$" "$control_log" | tail -1 | tr -d "()")
|
||||||
|
echo "COLLECTED patch=${pt:-0} control=${ct:-0}"
|
||||||
|
if [ "${pt:-0}" -lt 3000 ] || [ "${ct:-0}" -lt 3000 ]; then
|
||||||
|
echo "DELTA-GATE: INVALID — truncated collection"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== NEW REDS ==="
|
||||||
|
comm -23 "$patch_fail" "$control_fail"
|
||||||
|
new=$(comm -23 "$patch_fail" "$control_fail" | wc -l)
|
||||||
|
echo "NEW-RED-COUNT:$new"
|
||||||
|
|
||||||
|
echo "=== full candidate fail list ==="
|
||||||
|
cat "$patch_fail"
|
||||||
|
echo "=== full control fail list ==="
|
||||||
|
cat "$control_fail"
|
||||||
|
|
||||||
|
if [ "$new" -eq 0 ]; then
|
||||||
|
echo "DELTA-GATE: CLEAN"
|
||||||
|
else
|
||||||
|
echo "DELTA-GATE: NEW REDS"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Clean up (mind the lane's disk budget)
|
||||||
|
if: always()
|
||||||
|
run: rm -rf "ob-cand-${{ github.run_id }}" "ob-ctrl-${{ github.run_id }}" "/tmp/ob-${{ github.run_id }}-"*
|
||||||
Reference in a new issue