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
44 changes: 44 additions & 0 deletions .github/workflows/security-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Security audit

# Runs on every pull request (no paths-ignore) so dependency scans are not
# skipped when the main CI workflow is skipped for docs-only changes.

on:
pull_request:
workflow_dispatch:

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

jobs:
pip-audit:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
Comment thread
leostar0412 marked this conversation as resolved.
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
with:
python-version: "3.13"

- name: Cache uv
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ~/.cache/uv
key: ${{ runner.os }}-uv-pip-audit-${{ hashFiles('requirements.lock', 'requirements-dev.lock') }}
restore-keys: |
${{ runner.os }}-uv-pip-audit-
${{ runner.os }}-uv-

- name: Dependency audit (pip-audit)
run: |
uv venv
uv pip install "pip-audit>=2.10,<3"
uv run pip-audit --desc on -r requirements.lock -r requirements-dev.lock
28 changes: 27 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,36 @@ uv run python benchmarks/compare_to_baseline.py bench.json benchmarks/baselines.

**CI:** The [`.github/workflows/benchmarks.yml`](.github/workflows/benchmarks.yml) workflow runs on **`workflow_dispatch`** only, uploads `bench.json` as an artifact, and runs the compare step on success.

## Dependency security audit

Every pull request runs **[`.github/workflows/security-audit.yml`](.github/workflows/security-audit.yml)** (`pip-audit` against the pinned dependency trees). Unlike the main [CI workflow](.github/workflows/actions.yml), this workflow has **no `paths-ignore`**, so doc-only PRs still get a dependency scan.

**What is scanned**

- [`requirements.lock`](requirements.lock) — production / Docker image
- [`requirements-dev.lock`](requirements-dev.lock) — dev and CI (includes `-r requirements.in`)

**Run locally** (same command as CI, from the repo root):

```bash
uv venv
uv pip install "pip-audit>=2.10,<3"
uv run pip-audit --desc on -r requirements.lock -r requirements-dev.lock
```

If the audit reports a vulnerable package, bump the constraint in [`requirements.in`](requirements.in) or [`requirements-dev.in`](requirements-dev.in), then regenerate locks:

```bash
uv pip compile requirements.in -o requirements.lock --python-version 3.13 --python-platform linux
uv pip compile requirements-dev.in -o requirements-dev.lock --python-version 3.13 --python-platform linux
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Commit the updated `.in` and `.lock` files. Prefer fixing versions over long-lived `--ignore-vuln` entries.

## Other guidelines

- **Branching:** Create feature branches from `develop`. Open pull requests against `develop`. See [docs/Development_guideline.md](docs/Development_guideline.md).
- **Code style:** Use Python 3.13 and follow Django and project conventions. Use the project’s logging (`logging.getLogger(__name__)`). Before pushing, run **`uv run pyright`** (with dev deps) for the paths covered by **`pyrightconfig.json`**, and ensure CI’s **lint** / **pyright** / **test** jobs would pass.
- **Code style:** Use Python 3.13 and follow Django and project conventions. Use the project’s logging (`logging.getLogger(__name__)`). Before pushing, run **`uv run pyright`** (with dev deps) for the paths covered by **`pyrightconfig.json`**, and ensure CI’s **lint** / **pyright** / **test** / **Security audit** jobs would pass.
- **Database:** Use the Django ORM and migrations. Writes only through the service layer as above.
- **Docs:** Update this file (and app `services.py` docstrings) when adding new apps or changing the write rules. After changing `services.py` or `core/protocols.py`, run `python scripts/generate_service_docs.py` and commit the updated `docs/service_api/` files.

Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

-r requirements.in

pytest>=7.4,<9
pytest>=9.0.3,<10
pytest-benchmark>=4.0,<6
pytest-django>=4.5,<5
django-stubs>=4.2.7,<5
Expand Down
5 changes: 3 additions & 2 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ httplib2==0.31.2
# google-auth-httplib2
identify==2.6.19
# via pre-commit
idna==3.14
idna==3.16
# via
# -r requirements.in
# requests
# yarl
import-linter==2.11
Expand Down Expand Up @@ -209,7 +210,7 @@ pyparsing==3.3.2
# via httplib2
pyright==1.1.409
# via -r requirements-dev.in
pytest==8.4.2
pytest==9.0.3
# via
# -r requirements-dev.in
# pytest-benchmark
Expand Down
2 changes: 2 additions & 0 deletions requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ psycopg[binary]>=3.1,<4
django-environ>=0.11,<1
requests>=2.31,<3
urllib3>=2.0,<3
# CVE-2026-45409: ensure patched idna (transitive via requests, etc.).
idna>=3.15,<4
discord.py>=2.3.0,<3
python-dateutil>=2.8.0,<3
celery[redis]>=5.3,<6
Expand Down
3 changes: 2 additions & 1 deletion requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ httplib2==0.31.2
# via
# google-api-python-client
# google-auth-httplib2
idna==3.14
idna==3.16
# via
# -r requirements.in
# requests
# yarl
jeepney==0.9.0
Expand Down
Loading