Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions .github/workflows/changelog-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,25 @@ name: Changelog Check
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

# The gate itself decides per package whether a fragment is required
# (changed_packages / code_touched in internals/checks); these paths only
# decide whether the decision is worth a runner. packages/** covers both the
# code that demands a fragment and the fragment dirs that satisfy it, so the
# near-miss diagnostics (malformed fragment names) still run on
# fragment-only PRs.
#
# plugins/ is deliberately absent: the gate's matchers are hardcoded to
# packages/<pkg>/, so it cannot see plugin fragments -- running it on a
# plugin change is a vacuous pass. Plugin changelog enforcement is a gate
# gap, tracked in its own issue.
on:
pull_request:
branches: [main]
paths:
- 'packages/**'
# Attestations are filtered out of the gate's code_touched, so they
# cannot alter its verdict.
- '!packages/*/e2e-attestations/**'
- '.github/workflows/changelog-check.yml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand All @@ -31,7 +47,7 @@ jobs:
# Logic (packages/<pkg>/ source detection, per-package fragment
# detection, raw-body skip-changelog scanning) lives in internals/checks'
# changelog_gate check, colocated-tested at 100% coverage, per
# AGENTS.md "CI Workflows". Mirrors template-lib's reference gate (#566).
# AGENTS.md "CI Workflows".
- name: Require a per-package changelog fragment for SDK code changes
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
Expand Down
81 changes: 0 additions & 81 deletions .github/workflows/conventions.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
name: Python Test

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
name: dirsql Python CI

# packages/rust/** fans in: the core compiles into the binding, and
# [e2e].extra_scope means a core change stales this package's attestation.
on:
push:
branches: [main]
Expand All @@ -11,20 +10,92 @@ on:
- 'packages/rust/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/python-test.yml'
- 'testing-conventions.toml'
- '.github/workflows/dirsql-python-ci.yml'
pull_request:
paths:
- 'packages/python/**'
- '!packages/python/changelog.d/**'
- '!packages/python/migrations.d/**'
- '!packages/python/README.md'
- 'packages/rust/**'
- '!packages/rust/changelog.d/**'
- '!packages/rust/migrations.d/**'
- '!packages/rust/README.md'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/python-test.yml'
- 'testing-conventions.toml'
- '.github/workflows/dirsql-python-ci.yml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
python-sdk:
uses: thekevinscott/testing-conventions/.github/workflows/testing-conventions.yml@v0
with:
languages: '["python"]'
source: packages/python/dirsql
config: testing-conventions.toml
base: ${{ github.event.pull_request.base.sha || 'origin/main' }}

rust-python-binding:
uses: thekevinscott/testing-conventions/.github/workflows/testing-conventions.yml@v0
with:
languages: '["rust"]'
source: packages/python
config: testing-conventions.toml
base: ${{ github.event.pull_request.base.sha || 'origin/main' }}
gates: '["colocated-test", "unit-lint"]'

lint:
name: lint (python)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v7

- name: Install just
uses: extractions/setup-just@v2

# ruff never executes the compiled extension, so skip the maturin
# project install -- a plain `uv run` would pay a full Rust build.
- name: Install dependencies
run: uv sync --no-install-project
working-directory: packages/python

- name: Lint
run: uv run --no-sync ruff check .
working-directory: packages/python

- name: Format check
run: uv run --no-sync ruff format --check .
working-directory: packages/python

ty:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v7

# `ty` checks statically and never imports the compiled extension, so
# skip the maturin project install -- `uv run` would pay a Rust build.
- name: Install dependencies
run: uv sync --no-install-project
working-directory: packages/python

- name: Type check (all rules promoted to error)
run: uv run --no-sync ty check --error all --error-on-warning dirsql/
working-directory: packages/python

unit:
name: Unit tests
runs-on: ubuntu-latest
Expand Down Expand Up @@ -74,9 +145,8 @@ jobs:
working-directory: packages/python

integration:
# Hermetic tier (#289): SDK public API with the Rust core and the
# filesystem mocked. The PyO3 extension is still built because
# `dirsql/__init__.py` imports `dirsql._dirsql` at module load.
# Hermetic tier: core and filesystem mocked. The PyO3 extension is still
# built because `dirsql/__init__.py` imports `dirsql._dirsql` at load.
name: Integration tests
runs-on: ubuntu-latest
strategy:
Expand Down Expand Up @@ -118,9 +188,8 @@ jobs:
working-directory: packages/python

binding:
# Binding tier (#289): the SDK public API against the real PyO3 core and
# a real filesystem — proves the SDK↔core marshaling that the hermetic
# integration tier mocks out.
# Binding tier: real PyO3 core and real filesystem -- proves the
# SDK↔core marshaling the hermetic tier mocks out.
name: Binding tests
runs-on: ubuntu-latest
strategy:
Expand Down Expand Up @@ -161,24 +230,10 @@ jobs:
run: uv run python -m pytest tests/integration/binding/ -x -q --tb=short
working-directory: packages/python

# Unit coverage now runs in the reusable testing-conventions workflow
# (conventions.yml, `python-sdk` gates: unit-coverage) after upstream #284
# taught the coverage suite job to install/build from the derived package
# root (python_env=uv -> `uv sync` builds maturin; provision_rust). The
# bespoke coverage job that lived here is retired (#412).

distcheck:
# Functional publishability gate (#344, mirroring ts-test.yml's distcheck
# job): build the real `dirsql` CLI binary via cargo, stage it under
# `dirsql/_binary/` the way the release pipeline's bundle_cli step
# would, build the wheel with `maturin build`, `pip install` it into a
# fresh venv, and run the installed `dirsql --version` console script
# plus `import dirsql`. Red here means the PyPI release is broken and
# must not go out. This is the install-and-run check the `packaging`
# gate does NOT do (that gate only asserts no test files ship in the
# artifact). No mocks. The flow lives in the internals/distcheck package
# (#520); this job invokes its `dirsql-distcheck python` entry point.
name: Packaging distcheck (install + run)
# Installs and runs the built wheel, which the `packaging` gate does not
# do -- that gate only asserts no test files ship in the artifact.
name: Packaging distcheck (python)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
name: Rust Test

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
name: dirsql Rust CI

# The binding crates fan in (packages/ts/napi, packages/python/src): they are
# cargo workspace members, so the workspace-wide unit/lint jobs compile them.
# The root testing-conventions.toml carries this lane's config and the
# [rust.coverage] floors the coverage job reads.
on:
push:
branches: [main]
Expand All @@ -12,21 +13,38 @@ on:
- 'packages/python/src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/rust-test.yml'
- 'testing-conventions.toml'
- '.github/workflows/dirsql-rust-ci.yml'
pull_request:
paths:
- 'packages/rust/**'
- '!packages/rust/changelog.d/**'
- '!packages/rust/migrations.d/**'
- '!packages/rust/README.md'
- 'packages/ts/napi/**'
- 'packages/python/src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/rust-test.yml'
- 'testing-conventions.toml'
- '.github/workflows/dirsql-rust-ci.yml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
rust:
uses: thekevinscott/testing-conventions/.github/workflows/testing-conventions.yml@v0
with:
languages: '["rust"]'
source: packages/rust
config: testing-conventions.toml
base: ${{ github.event.pull_request.base.sha || 'origin/main' }}
gates: '["colocated-test", "unit-lint", "integration-lint", "mutation", "packaging"]'

unit:
name: Unit tests
runs-on: ubuntu-latest
Expand Down Expand Up @@ -115,17 +133,9 @@ jobs:
with:
node-version: "24"

# Unit-only coverage floor (#295). Replaces the bespoke `cargo llvm-cov
# --fail-under-*` gate. The CLI scopes to `--lib` (so the integration
# tier under packages/rust/tests/ no longer pads the number --
# testing-conventions #269), reads `[rust].features` (= cli) so the
# `#[cfg(feature = "cli")]` module is measured (#270), and enforces the
# `[rust.coverage]` lines/functions/regions/branch floors from
# testing-conventions.toml (#271).
#
# Whole-tree only: unlike the Python/TS jobs there is no `--base`
# changed-lines check. Rust's effectful paths (filesystem / subprocess /
# HTTP / `notify`) are unit-uncovered by design (#233); a per-PR
# HTTP / `notify`) are unit-uncovered by design, so a per-PR
# changed-lines floor would fail legitimate integration-tier edits.
- name: Unit coverage floor (testing-conventions)
run: npx -y testing-conventions unit coverage --language rust packages/rust/src
Expand Down
Loading
Loading