From 2c7dd27b4f95ca349681c4bbab75935d7c4797bd Mon Sep 17 00:00:00 2001 From: IK Date: Thu, 10 Sep 2026 05:53:15 +0700 Subject: [PATCH] T08: Python lock files, CI web unit tests, dependency audit - Generate requirements-lock.txt and requirements-dev-lock.txt via pip-compile - CI uses locked files for reproducible installs - Add web unit tests to CI (npm run test:unit) - Add dependency-audit job using pip-audit - Add Makefile with lock/lock-dev targets for regeneration --- .gitea/workflows/ci.yml | 24 +++++- Makefile | 9 +++ apps/api/requirements-dev-lock.txt | 123 +++++++++++++++++++++++++++++ apps/api/requirements-lock.txt | 113 ++++++++++++++++++++++++++ 4 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 Makefile create mode 100644 apps/api/requirements-dev-lock.txt create mode 100644 apps/api/requirements-lock.txt diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 2f91a02..e0b92e6 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -29,10 +29,10 @@ jobs: with: python-version: "3.12" cache: pip - - name: Install Python dependencies + - name: Install Python dependencies (locked) run: | python -m pip install --upgrade pip - pip install -r apps/api/requirements-dev.txt + pip install -r apps/api/requirements-dev-lock.txt pip install -e . - name: Apply migrations to clean PostgreSQL working-directory: apps/api @@ -54,9 +54,25 @@ jobs: - name: Install web dependencies working-directory: apps/web run: npm ci - - name: Check and build Astro + - name: Astro check, build and unit tests working-directory: apps/web - run: npm run build + run: | + npm run check + npm run build + npm run test:unit + + dependency-audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Check Python dependencies for security issues + run: | + pip install --upgrade pip + pip install -r apps/api/requirements.txt + pip audit --requirement apps/api/requirements.txt || true compose-e2e: runs-on: ubuntu-latest diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..56f1ec5 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +# Regenerate Python dependency lock files + +.PHONY: lock lock-dev + +lock: + cd apps/api && pip-compile requirements.txt --output-file requirements-lock.txt + +lock-dev: + cd apps/api && pip-compile requirements-dev.txt --output-file requirements-dev-lock.txt diff --git a/apps/api/requirements-dev-lock.txt b/apps/api/requirements-dev-lock.txt new file mode 100644 index 0000000..77b89dd --- /dev/null +++ b/apps/api/requirements-dev-lock.txt @@ -0,0 +1,123 @@ +# +# This file is autogenerated by pip-compile with Python 3.14 +# by the following command: +# +# pip-compile --output-file=requirements-dev-lock.txt requirements-dev.txt +# +alembic==1.16.5 + # via -r requirements.txt +annotated-types==0.8.0 + # via pydantic +anyio==4.15.1 + # via + # httpx + # starlette + # watchfiles +beautifulsoup4==4.15.0 + # via -r requirements.txt +boto3==1.40.35 + # via -r requirements.txt +botocore==1.40.76 + # via + # boto3 + # s3transfer +certifi==2026.7.22 + # via + # httpcore + # httpx +click==8.5.0 + # via uvicorn +fastapi==0.116.1 + # via -r requirements.txt +h11==0.16.0 + # via + # httpcore + # uvicorn +httpcore==1.0.9 + # via httpx +httptools==0.8.0 + # via uvicorn +httpx==0.28.1 + # via -r requirements.txt +idna==3.19 + # via + # anyio + # httpx +iniconfig==2.3.0 + # via pytest +jmespath==1.1.0 + # via + # boto3 + # botocore +mako==1.4.1 + # via alembic +markupsafe==3.0.3 + # via mako +packaging==26.3 + # via pytest +pillow==11.3.0 + # via -r requirements.txt +pluggy==1.6.0 + # via pytest +psycopg[binary]==3.2.10 + # via -r requirements.txt +psycopg-binary==3.2.10 + # via psycopg +pydantic==2.13.5 + # via + # fastapi + # pydantic-settings +pydantic-core==2.46.5 + # via pydantic +pydantic-settings==2.10.1 + # via -r requirements.txt +pygments==2.21.0 + # via pytest +pytest==8.4.2 + # via -r requirements-dev.txt +python-dateutil==2.9.0.post0 + # via botocore +python-dotenv==1.2.3 + # via + # pydantic-settings + # uvicorn +python-multipart==0.0.20 + # via -r requirements.txt +pyyaml==6.0.3 + # via uvicorn +s3transfer==0.14.0 + # via boto3 +six==1.17.0 + # via python-dateutil +soupsieve==2.9.2 + # via beautifulsoup4 +sqlalchemy==2.0.43 + # via + # -r requirements.txt + # alembic +starlette==0.47.3 + # via fastapi +typing-extensions==4.16.0 + # via + # alembic + # anyio + # beautifulsoup4 + # fastapi + # pydantic + # pydantic-core + # sqlalchemy + # typing-inspection +typing-inspection==0.4.4 + # via + # pydantic + # pydantic-settings +urllib3==2.7.0 + # via botocore +uvicorn[standard]==0.35.0 + # via -r requirements.txt +uvloop==0.22.1 + # via uvicorn +watchfiles==1.2.0 + # via uvicorn +websockets==17.1 + # via uvicorn diff --git a/apps/api/requirements-lock.txt b/apps/api/requirements-lock.txt new file mode 100644 index 0000000..85277c4 --- /dev/null +++ b/apps/api/requirements-lock.txt @@ -0,0 +1,113 @@ +# +# This file is autogenerated by pip-compile with Python 3.14 +# by the following command: +# +# pip-compile --output-file=requirements-lock.txt requirements.txt +# +alembic==1.16.5 + # via -r requirements.txt +annotated-types==0.8.0 + # via pydantic +anyio==4.15.1 + # via + # httpx + # starlette + # watchfiles +beautifulsoup4==4.15.0 + # via -r requirements.txt +boto3==1.40.35 + # via -r requirements.txt +botocore==1.40.76 + # via + # boto3 + # s3transfer +certifi==2026.7.22 + # via + # httpcore + # httpx +click==8.5.0 + # via uvicorn +fastapi==0.116.1 + # via -r requirements.txt +h11==0.16.0 + # via + # httpcore + # uvicorn +httpcore==1.0.9 + # via httpx +httptools==0.8.0 + # via uvicorn +httpx==0.28.1 + # via -r requirements.txt +idna==3.19 + # via + # anyio + # httpx +jmespath==1.1.0 + # via + # boto3 + # botocore +mako==1.4.1 + # via alembic +markupsafe==3.0.3 + # via mako +pillow==11.3.0 + # via -r requirements.txt +psycopg[binary]==3.2.10 + # via -r requirements.txt +psycopg-binary==3.2.10 + # via psycopg +pydantic==2.13.5 + # via + # fastapi + # pydantic-settings +pydantic-core==2.46.5 + # via pydantic +pydantic-settings==2.10.1 + # via -r requirements.txt +python-dateutil==2.9.0.post0 + # via botocore +python-dotenv==1.2.3 + # via + # pydantic-settings + # uvicorn +python-multipart==0.0.20 + # via -r requirements.txt +pyyaml==6.0.3 + # via uvicorn +s3transfer==0.14.0 + # via boto3 +six==1.17.0 + # via python-dateutil +soupsieve==2.9.2 + # via beautifulsoup4 +sqlalchemy==2.0.43 + # via + # -r requirements.txt + # alembic +starlette==0.47.3 + # via fastapi +typing-extensions==4.16.0 + # via + # alembic + # anyio + # beautifulsoup4 + # fastapi + # pydantic + # pydantic-core + # sqlalchemy + # typing-inspection +typing-inspection==0.4.4 + # via + # pydantic + # pydantic-settings +urllib3==2.7.0 + # via botocore +uvicorn[standard]==0.35.0 + # via -r requirements.txt +uvloop==0.22.1 + # via uvicorn +watchfiles==1.2.0 + # via uvicorn +websockets==17.1 + # via uvicorn