name: ci # Deliberately not triggered by pull_request. # # The forge this runs on is public and takes pull requests from strangers, and a # runner executes whatever the workflow checks out. Triggering on pull_request # would mean a stranger's first contribution runs code on the runner host before # anyone has read it. Triggering only on push means the runner only ever executes # code that someone with push rights put there. # # The cost is that a pull request gets no automatic check. Run it by pushing the # branch yourself once you have read the diff. on: push: branches: ['**'] tags-ignore: ['**'] jobs: test: runs-on: docker container: image: rust:1.98-bookworm steps: - uses: actions/checkout@v4 - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} restore-keys: cargo-${{ runner.os }}- # No `cargo fmt --check`. The tables in this crate are aligned by hand — # MONTHS, JURISDICTIONS — and rustfmt wants one entry per line, which loses # the shape that makes them readable. A gate that fights the house style is # a gate that gets ignored. - name: Lint run: | rustup component add clippy cargo clippy --all-targets -- -D warnings # The binding code only exists under the feature, so a bare clippy # run never looks at src/python.rs. cargo clippy --features python --all-targets -- -D warnings - name: Rust tests run: cargo test # The CLI and the bindings are the same engine, so they have to agree. This # is the check that caught the bindings resolving their own default # jurisdiction while the CLI read the configured one. - name: Python bindings run: | apt-get update && apt-get install -y --no-install-recommends python3 python3-venv python3-dev python3 -m venv /tmp/venv /tmp/venv/bin/pip install --quiet maturin pytest mypy cargo build --release /tmp/venv/bin/maturin build --release --out dist /tmp/venv/bin/pip install --quiet --no-index --find-links dist typikon /tmp/venv/bin/python -m pytest tests/python -q - name: Type stubs run: | cat > /tmp/typecheck.py <<'EOF' import datetime, typikon d: typikon.Day = typikon.describe(datetime.date(2026, 4, 12)) day: datetime.date = d.date feast: str | None = d.feast n: int = d.days_to_pascha EOF /tmp/venv/bin/python -m mypy --strict /tmp/typecheck.py