Files
OmniRoute/.github/workflows/nightly-schemathesis.yml
Diego Rodrigues de Sa e Souza 751710616a fix(ci): run the build-bearing nightly jobs on the box's light pool (#11965) (#11967)
Four nightly jobs run a backend-only `next build` on ubuntu-latest (7 GB):
Schemathesis, promptfoo injection guard, garak probes and the axe a11y suite
(self-building webServer). On release/v3.8.51 three of them died with the hosted
VM shutdown signature and nobody saw it — nightlies have no audience — and the
fourth passes by a margin of minutes. They now target [self-hosted, omni-light]
(hosted fallback when USE_VPS_RUNNER is off), a new two-listener label on the .113
box for jobs that need ~6 GB, not the 14-16 GB of a full build; they run once a day
in the 04:00-06:00 UTC window, when the box is idle.

Fleet reshaped the same day and documented in docs/ops/RUNNER_BOX.md: 4 active
OmniRoute listeners (omniroute-113-5/-6 omni-build, omniroute-113/-2 omni-light),
omniroute-113-3/-4/-7/-8 disabled (systemctl enable --now brings one back), janitor
ceiling MAX_ACTIVE_RUNNERS=4. The remaining headroom limit is the VM's 31 GB of RAM
(2 heavy + 2 light ≈ 42 GB peak, inside the 16 GB swap); more RAM on the Proxmox VM
is the lever that turns the label ceilings into 3 heavy + 2 light.

check:workflows --ratchet unchanged (194/194); check-workflows and
backend-only-smoke-workflows suites pass; docs-sync PASS.
2026-08-28 23:26:52 -03:00

78 lines
2.9 KiB
YAML

name: Nightly Schemathesis
on:
schedule:
- cron: "23 4 * * *"
workflow_dispatch:
permissions:
contents: read
jobs:
schemathesis:
name: Schemathesis — OpenAPI contract fuzz (advisory)
# #11965: this job runs a backend-only `next build`; the hosted 7 GB runner cannot build
# release/v3.8.51 (VM shutdown ~7 min in), so it targets the box's light pool (`omni-light`:
# two listeners, jobs ≤ ~6 GB). Falls back to hosted when USE_VPS_RUNNER is off.
runs-on: ${{ (vars.USE_VPS_RUNNER == 'true' && fromJSON('["self-hosted","omni-light"]')) || 'ubuntu-latest' }}
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-node@v7
with: { node-version: "24", cache: npm }
- run: npm ci
- name: Build CLI bundle
env:
JWT_SECRET: ci-build-secret-with-sufficient-length-for-validation
OMNIROUTE_BUILD_BACKEND_ONLY: "1"
run: npm run build:cli
- name: Start OmniRoute (background)
env:
JWT_SECRET: ci-build-secret-with-sufficient-length-for-validation
PORT: "20128"
run: |
node dist/server.js > server.log 2>&1 &
echo $! > server.pid
for i in $(seq 1 30); do
if curl -sf http://localhost:20128/api/monitoring/health >/dev/null; then echo "server up"; break; fi
sleep 2
done
- uses: actions/setup-python@v7
with: { python-version: "3.12" }
- name: Install schemathesis
run: pip install schemathesis
- name: Schemathesis contract fuzz (advisory)
# Advisory gate: never fails the job. `continue-on-error` covers a crash of the
# step itself; `|| true` covers schemathesis exiting non-zero when it finds spec
# violations / upstream 500s — both are expected here (most /v1 endpoints proxy an
# upstream that has no provider configured in CI). The point of the nightly is to
# PROVE the contract is fuzzable and surface regressions, not to gate the build.
continue-on-error: true
run: |
schemathesis run docs/openapi.yaml \
--url http://localhost:20128 \
--max-examples 20 \
--workers 4 \
--checks all \
--max-response-time 30 \
--request-timeout 30 \
--suppress-health-check all \
--report junit \
--report-junit-path schemathesis-report/junit.xml \
--no-color \
|| true
- name: Stop server
if: always()
run: kill "$(cat server.pid)" || true
- name: Upload schemathesis report
if: always()
uses: actions/upload-artifact@v7
with:
name: schemathesis-report
path: |
schemathesis-report/
server.log
if-no-files-found: warn
retention-days: 14