Skip to content

feat: registered forecast students compete under auto by default #82

feat: registered forecast students compete under auto by default

feat: registered forecast students compete under auto by default #82

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: build + test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Build loadable extension
run: make loadable
- name: Run test suite
run: make test
amalgamation:
name: amalgamation compiles
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# regenerate the single-file amalgamation from the current sources and
# compile it (static + loadable), so it can never drift from the tree.
- name: Generate + compile amalgamation
run: make amalgamation-check
bindings:
name: bindings (node + rust)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# rust crate: compiles the amalgamation via build.rs, register + forecast
- name: Rust crate
run: make rust-src && cargo test --manifest-path bindings/rust/Cargo.toml
- uses: actions/setup-node@v4
with:
node-version: "22"
# node binding: load the extension and run a forecast through node:sqlite
- name: Node binding
run: |
make loadable
cp dist/predict0.so bindings/node/predict0.so
node --experimental-sqlite -e '
const sp = require("./bindings/node/index.cjs");
const { DatabaseSync } = require("node:sqlite");
const db = new DatabaseSync(":memory:", { allowExtension: true });
sp.load(db);
db.exec("CREATE TABLE r(ts TEXT, value REAL)");
const ins = db.prepare("INSERT INTO r VALUES (?,?)");
for (let i = 0; i < 96; i++)
ins.run("2024-01-01T" + String(i % 24).padStart(2, "0") + ":00:00", 50 + 10 * Math.sin(i));
const doc = JSON.parse(db.prepare("SELECT forecast(ts, value, 6) d FROM r").get().d);
if (doc.status !== "ok" || doc.rows.length !== 6) { console.error("bad forecast doc"); process.exit(1); }
const x = db.prepare("SELECT count(*) c FROM forecast_rows(\x27" + JSON.stringify(doc).replaceAll("\x27","") + "\x27)").get().c;
if (x !== 6) { console.error("expected 6 expanded rows, got", x); process.exit(1); }
console.log("node binding OK");
'
# drizzle ORM smoke: the aggregate form composed through a query
# builder end to end (the RFC §4.2.8 ORM path)
- name: Drizzle smoke (aggregate form)
run: |
cd bindings/node
npm install --no-save better-sqlite3 drizzle-orm
node test/drizzle-smoke.mjs
sanitizers:
name: ASan + UBSan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run sanitizer soak
run: make test-asan CC=clang
valgrind:
name: valgrind
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Run valgrind inside a container instead of apt-installing it on the
# runner: the host's apt contends with the runner's background
# unattended-upgrades dpkg lock and can hang. `make test-valgrind` builds
# the soak in a fresh gcc:13 container (glibc + gcc coverage too) and
# runs it under valgrind with --error-exitcode.
- name: Run valgrind (containerized)
run: make test-valgrind
fuzz-smoke:
name: fuzz smoke (60s)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build + run libFuzzer
run: |
make vendor/sqlite3ext.h sqlite-predict.h
clang -std=c99 -g -O1 -fsanitize=fuzzer,address \
-DSQLITE_CORE -DSQLITE_PREDICT_STATIC -DSQLITE_STRICT_SUBTYPE=1 \
-Ivendor/ -I./ \
fuzz/fuzz_predict.c sqlite-predict.c predict-forecast.c \
predict-tabular.c predict-receipts.c predict-distill.c \
predict-student.c \
vendor/sha256.c vendor/sqlite3.c -o fuzz_predict -lm -lpthread -ldl
./fuzz_predict -max_total_time=60 -max_len=512 fuzz/seeds
windows:
name: windows (mingw)
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4
- uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-gcc make curl unzip mingw-w64-x86_64-sqlite3
- name: Build loadable DLL
run: make loadable
- name: Build + run soak (static, portability proof)
run: make soak && ./dist/soak
- name: Load the DLL via the SQLite CLI
run: |
sqlite3 ":memory:" ".load ./dist/predict0" "SELECT predict_version();"
wasm:
name: wasm (emscripten)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install emscripten
run: |
git clone --depth 1 https://github.com/emscripten-core/emsdk.git
./emsdk/emsdk install latest
./emsdk/emsdk activate latest
- name: Compile soak to WebAssembly
run: |
source ./emsdk/emsdk_env.sh
make soak-wasm
- name: Run under node
run: node dist/soak.js
onnx:
name: onnx (cpu)
runs-on: ubuntu-latest
env:
ORT_VERSION: "1.27.1"
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Fetch onnxruntime
run: |
curl -fsSL -o ort.tgz \
"https://github.com/microsoft/onnxruntime/releases/download/v${ORT_VERSION}/onnxruntime-linux-x64-${ORT_VERSION}.tgz"
tar xzf ort.tgz
echo "ONNXRUNTIME_PREFIX=$PWD/onnxruntime-linux-x64-${ORT_VERSION}" \
>> "$GITHUB_ENV"
- name: Build the onnx variant + run its tests
run: make test-onnx
- name: ASan + LSan soak of the onnx backend
run: make test-asan-onnx
- name: Compile-check the GPU build (CUDA/TensorRT wiring)
run: make loadable-onnx-gpu