Skip to content

feat(watches): concurrent drain + fix(engine): clearer temperature-rejection message #938

feat(watches): concurrent drain + fix(engine): clearer temperature-rejection message

feat(watches): concurrent drain + fix(engine): clearer temperature-rejection message #938

Workflow file for this run

name: CI
on:
pull_request:
push:
branches: [main]
# Shared by every job. POSTGRES_PASSWORD is required at settings import
# (no default), so even the non-DB jobs need the block to load Django.
env:
DJANGO_ENV: local
DJANGO_SECRET_KEY: ci-not-a-secret
BASE_URL: http://localhost:8000
APP_BASE_URL: http://localhost:3001
MARKETING_BASE_URL: http://localhost:3000
# No LLM in CI ; the test suite mocks the engine, this just satisfies config.
ENGINE_BASE_URL: http://localhost:11434/v1
ENGINE_MODEL: qwen2.5:7b
POSTGRES_DB: openmagpie
POSTGRES_USER: openmagpie
POSTGRES_PASSWORD: openmagpie
POSTGRES_HOST: localhost # the service is published on the runner's localhost
POSTGRES_PORT: "5432"
jobs:
# PR-only: validate the source branch name. On push to main there's no
# feature branch to check (main is exempt), so this job skips.
branch-name:
name: branch-name
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check branch name
run: ./scripts/check-branch-name.sh "${{ github.head_ref }}"
lint:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
# --frozen: fail if uv.lock drifts. --all-packages: every workspace
# member (core + cli + schema) incl. dev tools (ruff, ty).
- name: Sync workspace
run: uv sync --all-packages --frozen
- name: ruff
run: |
uv run ruff check .
uv run ruff format --check .
- name: ty
run: uv run --package openmagpie-core ty check apps/core packages/openmagpie-schema tools/schema_sync
- name: whitespace + file length
run: |
./scripts/check-whitespace.sh
./scripts/check-file-length.sh
# Everything in scripts/ is POSIX sh; -s sh fails on any bashism so the
# curl|sh installer (and the dev tooling) stays portable. shellcheck ships
# on GitHub's ubuntu runners today; install it if a future image drops it.
- name: shellcheck (scripts are POSIX sh)
run: |
command -v shellcheck >/dev/null || { sudo apt-get update && sudo apt-get install -y shellcheck; }
find scripts -name '*.sh' -print0 | xargs -0 -r shellcheck -s sh
# Fail if a model change has no committed migration — compares models.py
# against the migration files (the autodetector), no DB involved.
# --check implies no-write on Django >=4.2, so no --dry-run needed.
- name: migrations match models
run: uv run --package openmagpie-core python apps/core/manage.py makemigrations --check
# The committed schema.json is generated from the Pydantic models (the
# web client generates its validators from it). Mirror the local
# pre-commit `schema-sync` hook so a stale artifact, a forgotten model,
# or an input mode divergence can't reach main via a contributor who
# skipped `make hooks` or used `git commit --no-verify`. --no-sync uses
# the workspace env synced above (the generator needs pydantic + the
# openmagpie-schema package, both installed by that sync).
- name: schema.json is fresh
run: uv run --no-sync python -m tools.schema_sync.generate --check
# Smoke-test the CLI wheel build (the PyPI publish path in release-cli.yml).
# A packaging break - name drift, a missing schema force-include - fails
# here instead of at the first real release. Build only; not published.
- name: CLI wheel builds
run: uv build --package openmagpie --wheel
test:
name: test
runs-on: ubuntu-latest
# The app is a multi-writer pipeline on Postgres (not SQLite), so the
# test DB needs a real Postgres ; mirror the compose dev creds.
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_DB: openmagpie
POSTGRES_USER: openmagpie
POSTGRES_PASSWORD: openmagpie
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U openmagpie -d openmagpie"
--health-interval 5s --health-timeout 3s --health-retries 10
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: Sync workspace
run: uv sync --all-packages --frozen
# Run from apps/core so Django's test discovery finds every app (they are
# importable as top-level there); no hardcoded app list to drift out of date.
- name: Tests
working-directory: apps/core
run: uv run --package openmagpie-core python manage.py test --noinput
# Backstop for hop 2 of the schema contract (schema.json -> web zod). The `lint`
# job's "schema.json is fresh" step guards hop 1 (Pydantic -> schema.json); this
# guards that the committed web validators (packages/schema/src/generated.ts)
# aren't stale relative to schema.json + the generator. Mirrors the local
# `web-schema` pre-commit hook, unconditionally, for anyone without pnpm.
web-schema:
name: web-schema
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml
- name: Install web deps
working-directory: web
run: pnpm install --frozen-lockfile
- name: generated.ts is fresh
working-directory: web
run: pnpm --filter @magpie/schema check
# Freshness is a string diff; typecheck the WHOLE workspace (not just
# @magpie/schema) so a contract change that type-breaks a CONSUMER
# (@magpie/api-utils, the apps) or a zod-4 usage issue fails on the PR here,
# not later on push-to-main (images.yml). Deps are already installed above.
- name: web packages typecheck
working-directory: web
run: pnpm -r typecheck
# typecheck never EXECUTES the module, so also run the generated schemas: a
# fresh but throw-on-import generated.ts (a zod runtime bump) fails here too.
- name: generated.ts runtime smoke
working-directory: web
run: pnpm --filter @magpie/schema smoke