name: CI on: pull_request: schedule: - cron: "0 2 * * *" concurrency: group: ci-pr-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: ci: if: github.event_name == 'pull_request' runs-on: ubuntu-latest env: CI_IMAGE: nohype-ci:${{ github.run_id }} steps: - uses: actions/checkout@v4 - name: Build run: docker build -t "$CI_IMAGE" . - name: Start PostgreSQL run: | docker network create ci-net docker run -d --name ci-postgres --network ci-net \ -e POSTGRES_DB=nohype \ -e POSTGRES_USER=nohype \ -e POSTGRES_PASSWORD=nohype \ postgres:16-alpine for i in $(seq 1 30); do if docker exec ci-postgres pg_isready -U nohype -d nohype >/dev/null; then exit 0 fi sleep 2 done docker logs ci-postgres || true exit 1 - name: Ruff run: docker run --rm --network ci-net -e SECRET_KEY=ci-secret-key -e DATABASE_URL=postgres://nohype:nohype@ci-postgres:5432/nohype "$CI_IMAGE" ruff check . - name: Mypy run: docker run --rm --network ci-net -e SECRET_KEY=ci-secret-key -e DATABASE_URL=postgres://nohype:nohype@ci-postgres:5432/nohype "$CI_IMAGE" mypy apps config - name: Pytest run: docker run --rm --network ci-net -e SECRET_KEY=ci-secret-key -e DATABASE_URL=postgres://nohype:nohype@ci-postgres:5432/nohype "$CI_IMAGE" pytest - name: Tailwind build (assert generated diff is clean) run: | docker run --rm \ --network ci-net \ -v "$PWD:/app" \ -w /app \ -e SECRET_KEY=ci-secret-key \ -e DATABASE_URL=postgres://nohype:nohype@ci-postgres:5432/nohype \ "$CI_IMAGE" \ sh -lc "python manage.py tailwind install --no-input && python manage.py tailwind build" git diff --exit-code -- theme/static/css/styles.css - name: Remove PostgreSQL if: always() run: | docker rm -f ci-postgres || true docker network rm ci-net || true - name: Remove CI image if: always() run: docker image rm -f "$CI_IMAGE" || true nightly-e2e: if: github.event_name == 'schedule' runs-on: ubuntu-latest env: CI_IMAGE: nohype-ci-nightly:${{ github.run_id }} steps: - uses: actions/checkout@v4 - name: Build run: docker build -t "$CI_IMAGE" . - name: Start PostgreSQL run: | docker network create nightly-net docker run -d --name nightly-postgres --network nightly-net \ -e POSTGRES_DB=nohype \ -e POSTGRES_USER=nohype \ -e POSTGRES_PASSWORD=nohype \ postgres:16-alpine for i in $(seq 1 30); do if docker exec nightly-postgres pg_isready -U nohype -d nohype >/dev/null; then exit 0 fi sleep 2 done docker logs nightly-postgres || true exit 1 - name: Start dev server with seeded content run: | docker run -d --name nightly-e2e --network nightly-net \ -e SECRET_KEY=ci-secret-key \ -e DATABASE_URL=postgres://nohype:nohype@nightly-postgres:5432/nohype \ "$CI_IMAGE" \ sh -lc "python manage.py migrate --noinput && python manage.py seed_e2e_content && python manage.py runserver 0.0.0.0:8000" for i in $(seq 1 40); do if docker exec nightly-e2e curl -fsS http://127.0.0.1:8000/ >/dev/null; then exit 0 fi sleep 2 done docker logs nightly-e2e || true exit 1 - name: Run nightly Playwright journey run: | docker exec nightly-e2e playwright install chromium docker exec -e E2E_BASE_URL=http://127.0.0.1:8000 nightly-e2e \ pytest -o addopts='' apps/core/tests/test_nightly_e2e_playwright.py -q - name: Remove nightly container if: always() run: | docker rm -f nightly-e2e || true docker rm -f nightly-postgres || true docker network rm nightly-net || true - name: Remove CI image if: always() run: docker image rm -f "$CI_IMAGE" || true