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
32 changes: 15 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
fetch-depth: 0
- id: filter
Expand Down Expand Up @@ -60,8 +60,8 @@ jobs:
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- run: pip install -e '.[dev]'
Expand All @@ -71,18 +71,16 @@ jobs:
types:
needs: changes
if: needs.changes.outputs.code == 'true'
# ADVISORY type-checking (R36): pyright `basic` on passiveworkers/net only. Non-blocking
# (continue-on-error) — it surfaces type signal without gating merges; promote to a required
# check once the scoped surface is clean and the include list has widened. See [tool.pyright].
# BLOCKING type-checking (R36): pyright `basic` on passiveworkers/net only. A pyright error
# fails this job and therefore `ci-ok`. Widen the include list module-by-module. See [tool.pyright].
runs-on: ubuntu-24.04
continue-on-error: true
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- run: pip install -e . pyright # -e . gives pyright the real fastapi/pydantic types
- name: Pyright (basic, passiveworkers/net — advisory)
- name: Pyright (basic, passiveworkers/net)
run: pyright

test:
Expand All @@ -95,8 +93,8 @@ jobs:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
- name: Install (all extras + dev tools)
Expand All @@ -120,11 +118,11 @@ jobs:
# the served inline JS is Python-version-independent, so run the guards once
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- uses: actions/setup-node@v5
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: "24"
- run: pip install -e .
Expand All @@ -141,8 +139,8 @@ jobs:
# never CI-checked — every extra import must stay lazy/optional, or this job fails.
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- name: Install core only (no extras)
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CodeQL

on:
push:
branches: [main]
paths-ignore: ['docs/**', '**.md']
pull_request:
schedule:
- cron: "27 4 * * 1" # weekly (Monday 04:27 UTC): picks up new queries on unchanged code
workflow_dispatch:

# Read-only token by default; only the analyze job gets the one write scope it needs.
permissions:
contents: read

concurrency:
group: codeql-${{ github.ref }}
# Same rule as ci.yml: never cancel a main run, only superseded feature-branch pushes.
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
# Not a required check (only ci.yml's `ci-ok` is); results land in the Security tab.
analyze:
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write # upload SARIF results to code scanning
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
with:
languages: python
build-mode: none # interpreted language: no build step
- uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
with:
category: "/language:python"
20 changes: 10 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ jobs:
# green `main`, but a tag is a one-shot action, so re-verify rather than trust that.
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- name: Install (all extras + dev tools)
Expand All @@ -30,16 +30,16 @@ jobs:
needs: test
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- run: python -m pip install --upgrade pip build twine
- name: Build sdist + wheel
run: python -m build
- name: twine check
run: twine check dist/*
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist
path: dist/
Expand All @@ -53,12 +53,12 @@ jobs:
permissions:
id-token: write # OIDC — no stored PyPI token
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dist
path: dist/
- name: Publish to PyPI (Trusted Publishing, OIDC)
uses: pypa/gh-action-pypi-publish@release/v1
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
with:
# A retried run after a partial success (e.g. sdist uploaded, wheel upload dropped)
# would otherwise have PyPI reject the already-accepted file, fail this job again,
Expand All @@ -71,13 +71,13 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v5
- uses: actions/download-artifact@v4
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dist
path: dist/
- name: Create GitHub Release with build provenance
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
with:
files: dist/*
generate_release_notes: true
12 changes: 6 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ CI gate is scoped to `select = ["E9", "F"]` (pyflakes + syntax errors only — s
```bash
python -m py_compile $(git ls-files '*.py')
```
This is a syntax-compile check, not a real type checker. CI separately runs an
**advisory** `pyright` pass scoped to `passiveworkers/net` only
(`continue-on-error: true`, non-blocking — see `[tool.pyright]` in `pyproject.toml`
and the `types` job in `.github/workflows/ci.yml`); it surfaces signal but doesn't
gate merges yet.
This is a syntax-compile check, not a real type checker. CI separately runs a
**blocking** `pyright` pass scoped to `passiveworkers/net` only (the `types` job in
`.github/workflows/ci.yml`, configured by `[tool.pyright]` in `pyproject.toml`): a
pyright error fails `types` and so the required `ci-ok`. Run `pyright` locally
before pushing a change under `passiveworkers/net`.

**Test**

Expand Down Expand Up @@ -163,7 +163,7 @@ entry in `billed_repos.json`.
force-pushing your own branch here is fine. Its `required_checks` is `[ci-ok]`: the
aggregate job in `ci.yml` that needs `changes`, `lint`, `types`, `test` (Python 3.10-3.14),
`frontend` and `core-install`, always runs, and fails if any needed job failed or was
cancelled (skipped is fine; `types` is advisory). GitHub enforces `ci-ok` through a
cancelled (skipped is fine). GitHub enforces `ci-ok` through a
`required_status_checks` rule on the "fleet: protect default branch" ruleset (alongside
deletion and non-fast-forward). `ci.yml` has no `paths-ignore` on `pull_request`: a
`changes` job skips the heavy jobs for docs-only PRs (every file under `docs/` or `*.md`),
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ filterwarnings = [
]

[tool.pyright]
# Scoped, ADVISORY type-checking (R36/D52). Starts on the federation layer only — the highest-value,
# Scoped, BLOCKING type-checking (R36/D52). Starts on the federation layer only — the highest-value,
# most-tested surface, where the pydantic request/response models already carry real types. `basic` mode
# is Any-tolerant, so the dynamic `sqlite3.Row["col"]` / `json.loads(...)` patterns don't explode. The CI
# `types` job runs this but does NOT gate the build (continue-on-error) — signal now, enforcement later.
# `types` job runs this and gates the build: a pyright error fails `types` and so the required `ci-ok`.
# Widen `include` module-by-module as the surface is annotated; NOT strict, NOT repo-wide by design.
include = ["passiveworkers/net"]
typeCheckingMode = "basic"
Expand Down