diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index b3aaa06..fcb64a6 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -23,5 +23,8 @@ jobs: env: DJANGO_ENV: dev DJANGO_SECRET_KEY: test-secret-key + # Explicitly clear DB vars so host/prod DATABASE_URL cannot leak in. + DATABASE_URL: "" + DB_HOST: "" run: | uv run python manage.py test diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index e4afa2f..9a1c3d0 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -20,15 +20,27 @@ jobs: - name: Build Docker image run: docker compose build + # Ephemeral local Postgres only — never inherit host DATABASE_URL (prod). - name: Run containerized tests run: | - docker compose up -d db - docker compose run --rm --entrypoint "" \ + set -euo pipefail + # Drop host/prod DB secrets so compose cannot interpolate them. + unset DATABASE_URL DB_HOST DB_NAME DB_USER DB_PASSWORD DB_PORT \ + COMPOSE_DATABASE_URL DJANGO_ENV DJANGO_SECRET_KEY DJANGO_DEBUG \ + DJANGO_ALLOWED_HOSTS || true + + PROJECT="scha-ci-${{ gitea.event.workflow_run.head_sha }}" + cleanup() { docker compose -p "$PROJECT" down -v --remove-orphans || true; } + trap cleanup EXIT + + docker compose -p "$PROJECT" up -d --wait db + docker compose -p "$PROJECT" run --rm --no-deps --entrypoint "" \ -e DJANGO_ENV=dev \ -e DJANGO_SECRET_KEY=test-secret-key \ + -e DJANGO_DEBUG=true \ + -e DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,testserver \ -e DATABASE_URL=postgres://scha:scha@db:5432/scha \ web uv run python manage.py test - docker compose down deploy: if: gitea.event.workflow_run.conclusion == 'success' && gitea.event.workflow_run.event == 'push' diff --git a/.gitea/workflows/unittests.yml b/.gitea/workflows/unittests.yml index 74a8437..7edcf73 100644 --- a/.gitea/workflows/unittests.yml +++ b/.gitea/workflows/unittests.yml @@ -25,5 +25,8 @@ jobs: env: DJANGO_ENV: dev DJANGO_SECRET_KEY: test-secret-key + # Explicitly clear DB vars so host/prod DATABASE_URL cannot leak in. + DATABASE_URL: "" + DB_HOST: "" run: | uv run python manage.py test diff --git a/README.md b/README.md index 60ec80a..d4a9cc9 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,8 @@ Without `DATABASE_URL` / `DB_HOST`, settings fall back to SQLite (`db.sqlite3`). docker compose up --build ``` -App: http://localhost:8000 — Postgres via `DATABASE_URL=postgres://scha:scha@db:5432/scha`. +App: http://localhost:8000 — Postgres via bundled `db` (`postgres://scha:scha@db:5432/scha`). +Compose does **not** read host `DATABASE_URL` (avoids CI/prod leaks); override with `COMPOSE_DATABASE_URL` if needed. ## Environment variables @@ -69,7 +70,7 @@ Validate with: |----------|---------|--------| | `unittests.yml` | push + PR → `master` | `uv sync` + `manage.py test` | | `ci.yml` | PR → `master` | same unit tests | -| `deploy.yml` | after Unit Tests succeeds on `master` **push** | docker build/test → `deploy.sh` | +| `deploy.yml` | after Unit Tests succeeds on `master` **push** | docker build + tests on **ephemeral compose Postgres** → `deploy.sh` | Deploy never runs on PRs. diff --git a/docker-compose.yml b/docker-compose.yml index 96621be..34612f2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,12 +20,16 @@ services: - "8000:8000" # No required env_file — CI has no .env. Defaults below; for local secrets: # docker compose --env-file .env up + # + # Do NOT interpolate ${DATABASE_URL} here. On the Act runner / control node that + # var often points at shared prod/beta Postgres; compose would bake it into + # containerized tests. Use COMPOSE_DATABASE_URL only if you need to override. environment: DJANGO_ENV: ${DJANGO_ENV:-dev} DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-dev-only-change-me} DJANGO_DEBUG: ${DJANGO_DEBUG:-true} DJANGO_ALLOWED_HOSTS: ${DJANGO_ALLOWED_HOSTS:-localhost,127.0.0.1,0.0.0.0} - DATABASE_URL: ${DATABASE_URL:-postgres://scha:scha@db:5432/scha} + DATABASE_URL: ${COMPOSE_DATABASE_URL:-postgres://scha:scha@db:5432/scha} depends_on: db: condition: service_healthy