From 0ef7eb508ced53ec57fe16e32c9edf7c5ae919aa Mon Sep 17 00:00:00 2001 From: Harald Roessler Date: Fri, 22 May 2026 09:58:51 +0700 Subject: [PATCH 1/3] ci(fork): add pytest-run job with Postgres service container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the fork CI only ran pytest --collect-only, never executing any tests. This meant regressions like the PR#17 credit-middleware 402-block loss were invisible to CI — the concurrency test (test_concurrent_deducts_respect_balance) would have caught it immediately, but it never ran. New job: - pytest-run: spins up a Postgres 16 service container, runs init_db.sql for the schema, executes tests/test_credit_middleware.py with proper env vars (CREDITS_ENABLED=true, MOLTSTACK_DB_PW, etc.) This is intentionally scoped to credit middleware tests only — the test_caep.py and protocol compliance tests need additional infrastructure (sandbox, admin keys) and can be added separately. Also adds httpx to the collect job's pip install (needed for import to succeed). --- .github/workflows/fork-ci.yml | 58 ++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fork-ci.yml b/.github/workflows/fork-ci.yml index ccc5bc8..227324e 100644 --- a/.github/workflows/fork-ci.yml +++ b/.github/workflows/fork-ci.yml @@ -94,7 +94,7 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt - pip install pytest pytest-asyncio + pip install pytest pytest-asyncio httpx - name: collect tests # Collection imports test modules without running them. Catches # ImportError / SyntaxError / fixture-parse errors without @@ -106,6 +106,62 @@ jobs: run: | pytest --collect-only -q tests/ test_*.py 2>&1 | tail -40 + pytest-run: + name: pytest (credit middleware) + runs-on: ubuntu-latest + services: + postgres: + image: postgres:16 + env: + POSTGRES_DB: moltstack + POSTGRES_USER: moltstack + POSTGRES_PASSWORD: ci-pw + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: pip + cache-dependency-path: requirements.txt + - name: install requirements + pytest + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pytest pytest-asyncio httpx + - name: init test DB schema + # init_db.sql uses IF NOT EXISTS — idempotent, safe to run + # repeatedly. Uses plain text password via PGPASSWORD — safe + # because this runs in an ephemeral CI container. + env: + PGPASSWORD: ci-pw + run: | + psql -h localhost -U moltstack -d moltstack -f init_db.sql + - name: run credit middleware tests + # These tests require a live Postgres because credit_middleware + # connects via db_pool (asyncpg). The service container provides + # a fresh Postgres on localhost:5432. + # MOLTRUST_ADMIN_USERS needs a valid bcrypt hash for the format + # check — the placeholder below passes the regex but won't match + # any real password. + env: + MOLTRUST_API_KEYS: 'mt_ci_placeholder_key' + NONCE_SECRET: 'ci-placeholder-nonce-secret' + MOLTSTACK_DB_PW: 'ci-pw' + DB_NAME: moltstack + DB_HOST: localhost + MOLTRUST_ADMIN_USERS: 'ci-admin:admin:$2b$12$ciplaceholderhashforadminusersformatcheck' + MOLTRUST_ENV: 'ci' + CREDITS_ENABLED: 'true' + run: | + python -m pytest tests/test_credit_middleware.py -v --tb=short 2>&1 + ruff: name: ruff (informational) runs-on: ubuntu-latest From d823d780ace2349413526685b7fbc2db665c147e Mon Sep 17 00:00:00 2001 From: Harald Roessler Date: Fri, 22 May 2026 10:12:11 +0700 Subject: [PATCH 2/3] ci(fork): fix api_keys.email column missing from init_db.sql --- .github/workflows/fork-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/fork-ci.yml b/.github/workflows/fork-ci.yml index 227324e..9d48685 100644 --- a/.github/workflows/fork-ci.yml +++ b/.github/workflows/fork-ci.yml @@ -143,6 +143,8 @@ jobs: PGPASSWORD: ci-pw run: | psql -h localhost -U moltstack -d moltstack -f init_db.sql + # CI schema alignment: columns present on live DB but missing from init_db.sql + psql -h localhost -U moltstack -d moltstack -c "ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS email TEXT;" - name: run credit middleware tests # These tests require a live Postgres because credit_middleware # connects via db_pool (asyncpg). The service container provides From 1f697fa75860320bb1b30a837c4cf7df644ec420 Mon Sep 17 00:00:00 2001 From: Harald Roessler Date: Fri, 22 May 2026 10:15:21 +0700 Subject: [PATCH 3/3] ci(fork): add request_log table to CI schema setup --- .github/workflows/fork-ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fork-ci.yml b/.github/workflows/fork-ci.yml index 9d48685..9fe1bce 100644 --- a/.github/workflows/fork-ci.yml +++ b/.github/workflows/fork-ci.yml @@ -141,10 +141,14 @@ jobs: # because this runs in an ephemeral CI container. env: PGPASSWORD: ci-pw + PGUSER: moltstack run: | psql -h localhost -U moltstack -d moltstack -f init_db.sql - # CI schema alignment: columns present on live DB but missing from init_db.sql + # CI schema alignment: columns/tables present on live DB but missing from init_db.sql psql -h localhost -U moltstack -d moltstack -c "ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS email TEXT;" + # request_log is referenced by middleware during test runs. Table not in + # init_db.sql — add minimal schema so INSERTs don't flood the log. + psql -h localhost -U moltstack -d moltstack -c "CREATE TABLE IF NOT EXISTS request_log (id BIGSERIAL PRIMARY KEY, endpoint TEXT, method TEXT, status_code INT, ip TEXT, user_agent TEXT, response_ms FLOAT, source TEXT, ip_org TEXT, ip_country TEXT, created_at TIMESTAMPTZ DEFAULT NOW());" - name: run credit middleware tests # These tests require a live Postgres because credit_middleware # connects via db_pool (asyncpg). The service container provides