Fix case-arm shadowing UB, tail-loop preemption, and OOM diagnostics #87
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
| name: Linux quickstart | |
| # Runs the exact README quickstart on a fresh Ubuntu image. If this | |
| # job is red, the README is lying — fix the README (or the build) before | |
| # pushing. Surfaced after a Linux user filed a review where every README | |
| # step failed; this guards against that regression coming back. | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| quickstart: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install README-listed system dependencies | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y --no-install-recommends \ | |
| build-essential libsqlite3-dev libssl-dev zlib1g-dev | |
| - name: Build swc + libswarmrt | |
| run: make swc libswarmrt | |
| - name: Compile-check every documented sw snippet + example | |
| # Tripwire against doc/example drift: every complete ```sw block | |
| # in the docs (those with a `module` + `fun main`) and every | |
| # runnable examples/*.sw must still compile with this swc. A red | |
| # here means a copy-paste-able snippet has rotted out of sync | |
| # with the language — fix the snippet (or the compiler). | |
| run: bash scripts/check_sw_docs.sh | |
| - name: Doctest — documented sw examples must RUN + match their output | |
| # One step beyond compile-checking: every complete ```sw block in | |
| # the docs that carries `# =>` expected-output markers is compiled, | |
| # RUN, and its stdout asserted line-for-line. A red here means a | |
| # doc example claims output the language no longer produces — the | |
| # "docs lie" tripwire. Fix the example, the marker, or the compiler. | |
| run: bash scripts/doctest.sh | |
| - name: Run the README quickstart verbatim | |
| run: | | |
| ./bin/swc build examples/counter.sw -o counter | |
| # `counter` is a long-running actor demo — give it a few seconds | |
| # then check it produced the documented output. | |
| timeout 5s ./counter > counter.out || true | |
| grep -q "Count:" counter.out | |
| - name: Run a few more examples | |
| run: | | |
| set -e | |
| ./bin/swc build examples/hello.sw -o /tmp/hello | |
| /tmp/hello | grep -q "Hello" | |
| ./bin/swc build examples/lambda.sw -o /tmp/lambda | |
| /tmp/lambda > /tmp/lambda.out | |
| test -s /tmp/lambda.out | |
| - name: Run the sw test suite | |
| run: make test-sw | |
| - name: Phase test suite (C-side runtime tests) | |
| # Was not in CI before round 7 — codex review caught that | |
| # multiple phase tests were failing locally while CI stayed | |
| # green. Now we gate on phase 2/3/4/5/6/7/8/9. Phase 4 | |
| # (Agent/App/DynSup), phase 5 (StateMachine/PG), and phase 7 | |
| # (hot reload multi-process/dead-cleanup) all used to fail | |
| # because sw_spawn_link's "non-parent scheduler" hint was | |
| # silently dropped by sw_spawn_opts; fixed in round 7 by | |
| # adding tls_spawn_override. | |
| run: | | |
| set -e | |
| for p in 2 3 4 5 6 7 8 9 10; do | |
| make test-phase$p | |
| done | |
| - name: GC copy-on-escape gate (ASAN + arena poison) | |
| # Compiles the copy-on-escape stress harness under -fsanitize=address + | |
| # -DSW_ARENA_POISON; a missed deep-copy on any send/spawn/ETS boundary | |
| # surfaces as a use-after-free or a 0xDE-garbage content assert. | |
| run: make gc-stress | |
| - name: GC memory-slope gate (Ownership v2 — bounded escaped memory) | |
| # Proves RECLAMATION, not just safety: peak-RSS growth must stay under | |
| # budget across a 10x scale-up of fixed-concurrency spawns, fixed-depth | |
| # messages, and a long-lived tail-recursive loop. Runs under default and | |
| # single-scheduler so adopt/reset/destroy ordering bugs surface too. | |
| run: | | |
| set -e | |
| make gc-slope | |
| SW_SCHEDULERS=1 make gc-slope | |
| - name: LeakSanitizer lifecycle gate (Phase 2.1 — Linux-only LSan) | |
| # The slope gates catch UNBOUNDED growth; this catches BOUNDED leaks | |
| # under their RSS noise floor. macOS Apple-clang ASAN has no LSan, so | |
| # every other ASAN run uses detect_leaks=0 and is leak-blind — this | |
| # Linux leg is the only real leak assertion in CI. Churns every | |
| # lifecycle owner (timers fired+cancelled, supervisors killed, ETS | |
| # replace/delete, spawns, compound messages), exits cleanly, and LSan | |
| # asserts zero definitely-lost blocks at exit. Proven bidirectional | |
| # (an injected unreachable block fails it). Advisory while it bakes; | |
| # promote to blocking once green across a week of pushes. | |
| continue-on-error: true | |
| run: make lsan-gate | |
| - name: Scheduler-count matrix (Phase 2.2 — suite under S=1 and oversubscribed) | |
| # The default-scheduler run above covers nproc; these legs cover the | |
| # edges. S=1 found a real architecture issue (blocking curl client + | |
| # in-process server deadlocks — the affected tests SKIP below 3 | |
| # schedulers, see KNOWN_ISSUES); S=8 oversubscribes the runner's | |
| # cores so cross-scheduler interleavings get exercised. The per-test | |
| # 180s timeout in run_tests.sh turns any future hang into a loud FAIL. | |
| run: | | |
| set -e | |
| SW_SCHEDULERS=1 ./tests/sw/run_tests.sh | |
| SW_SCHEDULERS=1 ./tests/sw/run_conform.sh | |
| SW_SCHEDULERS=8 ./tests/sw/run_tests.sh | |
| SW_SCHEDULERS=8 ./tests/sw/run_conform.sh | |
| - name: Stress test (high-process-count race guard) | |
| # Catches regressions in the high-spawn scheduler/mailbox path. | |
| # The historical ctx-tear race is closed by per-slot generation | |
| # counters + ctx_lock; the later spawn-storm crash cleared on | |
| # native Linux x86_64 May 29, so any miss here is a regression. | |
| run: make stress |