diff --git a/.github/workflows/behave.yml b/.github/workflows/behave.yml index 30d08b27..34fb68f0 100644 --- a/.github/workflows/behave.yml +++ b/.github/workflows/behave.yml @@ -4,7 +4,7 @@ name: Run behave on: push: branches: - - '**' + - "**" pull_request: branches: - main @@ -17,22 +17,10 @@ jobs: behave: name: Run Behave runs-on: ubuntu-latest - - services: - postgres: - image: postgres:latest - env: - POSTGRES_USER: scram - POSTGRES_PASSWORD: '' - POSTGRES_DB: test_scram - POSTGRES_HOST_AUTH_METHOD: trust - ports: - - 5432:5432 - options: >- - --health-cmd "pg_isready -U scram" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + strategy: + max-parallel: 4 + matrix: + python-version: ["3.11", "3.12"] steps: - name: Check out the code @@ -40,6 +28,7 @@ jobs: - name: Set up Docker uses: docker/setup-buildx-action@v3 + - name: Install Docker Compose run: | sudo apt-get update @@ -50,6 +39,8 @@ jobs: - name: Build Docker images run: make build + env: + PYTHON_IMAGE_VER: "${{ matrix.python-version }}" - name: Migrate Database run: make migrate @@ -71,19 +62,21 @@ jobs: uses: jwalton/gh-docker-logs@v2 - name: Upload Coverage to Coveralls + if: matrix.python-version == '3.12' uses: coverallsapp/github-action@v2 - name: Upload Coverage to GitHub + if: matrix.python-version == '3.12' uses: actions/upload-artifact@v4 with: name: coverage-report path: coverage.xml - name: Display Coverage Metrics + if: matrix.python-version == '3.12' uses: 5monkeys/cobertura-action@v14 with: - minimum_coverage: '50' - + minimum_coverage: "50" - name: Check Docker state (post-test) if: always() diff --git a/.github/workflows/behave_next_python.yml b/.github/workflows/behave_next_python.yml new file mode 100644 index 00000000..1c4b1a3c --- /dev/null +++ b/.github/workflows/behave_next_python.yml @@ -0,0 +1,77 @@ +--- +name: Run behave with unsupported Python versions + +on: + push: + branches: + - '**' + pull_request: + branches: + - main + - develop + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + behave_next_python: + name: Run Behave + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: ['3.13'] + + steps: + - name: Check out the code + uses: actions/checkout@v4 + + - name: Set up Docker + uses: docker/setup-buildx-action@v3 + + - name: Install Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose make + + - name: Check Docker state (pre-build) + run: docker ps + + - name: Build Docker images + run: make build + env: + PYTHON_IMAGE_VER: "${{ matrix.python-version }}" + + - name: Migrate Database + run: | + make migrate || echo "::warning:: migrate failed on future Python version ${{ matrix.python-version }}." + + - name: Run Application + run: | + make run || echo "::warning:: run failed on future Python version ${{ matrix.python-version }}." + + - name: Check Docker state (pre-test) + run: docker ps + + - name: Run pytest + behave with Coverage + env: + POSTGRES_USER: scram + POSTGRES_DB: test_scram + run: | + make coverage.xml || echo "::warning:: pytest + behave failed on future Python version ${{ matrix.python-version }}." + + - name: Dump docker logs on failure + if: failure() + uses: jwalton/gh-docker-logs@v2 + + - name: Check Docker state (post-test) + if: always() + run: docker ps + + - name: Stop Services + if: always() + run: make stop + + - name: Clean Up + if: always() + run: make clean diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 5f8ca68f..5d4004d2 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -20,7 +20,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.12'] + python-version: ['3.11', '3.12'] services: postgres: @@ -28,7 +28,7 @@ jobs: env: POSTGRES_USER: scram POSTGRES_PASSWORD: '' - POSTGRES_DB: test_scram + POSTGRES_DB: test_scram_${{ matrix.python-version }} POSTGRES_HOST_AUTH_METHOD: trust ports: - 5432:5432 @@ -58,30 +58,25 @@ jobs: # https://github.com/pytest-dev/pytest-github-actions-annotate-failures/pull/68 isn't yet in a release pip install git+https://github.com/pytest-dev/pytest-github-actions-annotate-failures.git@6e66cd895fe05cd09be8bad58f5d79110a20385f - - name: Apply unapplied migrations + - name: Apply migrations env: - DATABASE_URL: "postgres://scram:@localhost:5432/test_scram" + DATABASE_URL: "postgres://scram:@localhost:5432/test_scram_${{ matrix.python-version }}" run: | - python manage.py makemigrations --noinput || true - UNAPPLIED_MIGRATIONS=$(python manage.py showmigrations --plan | grep '\[ \]' | awk '{print $2}') - if [ -n "$UNAPPLIED_MIGRATIONS" ]; then - for migration in $UNAPPLIED_MIGRATIONS; do - python manage.py migrate $migration --fake-initial --noinput - done - else - echo "No unapplied migrations." - fi + python manage.py makemigrations --noinput + python manage.py migrate --noinput - name: Check for duplicate migrations + env: + DATABASE_URL: "postgres://scram:@localhost:5432/test_scram_${{ matrix.python-version }}" run: | if python manage.py makemigrations --dry-run | grep "No changes detected"; then echo "No duplicate migrations detected." else - echo "Warning: Potential duplicate migrations detected. Please review." + echo "::warning:: Potential duplicate migrations detected. Please review." fi - name: Run Pytest env: - DATABASE_URL: "postgres://scram:@localhost:5432/test_scram" + DATABASE_URL: "postgres://scram:@localhost:5432/test_scram_${{ matrix.python-version }}" REDIS_HOST: "localhost" run: pytest diff --git a/.github/workflows/future_pytest.yml b/.github/workflows/pytest_next_python.yml similarity index 99% rename from .github/workflows/future_pytest.yml rename to .github/workflows/pytest_next_python.yml index c20d365c..dbc9d4e1 100644 --- a/.github/workflows/future_pytest.yml +++ b/.github/workflows/pytest_next_python.yml @@ -14,7 +14,7 @@ on: workflow_dispatch: jobs: - pytest: + pytest_next_python: name: Run Pytest runs-on: ubuntu-latest strategy: diff --git a/Makefile b/Makefile index 8c3fac1f..347eb58c 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,7 @@ +# It'd be nice to keep these in sync with the defaults of the Dockerfiles +PYTHON_IMAGE_VER ?= 3.12 +POSTGRES_IMAGE_VER ?= 12.3 + .DEFAULT_GOAL := help ## toggle-prod: configure make to use the production stack @@ -37,7 +41,8 @@ behave-translator: compose.override.yml ## build: rebuilds all your containers or a single one if CONTAINER is specified .Phony: build build: compose.override.yml - @docker compose up -d --no-deps --build $(CONTAINER) + @docker compose build --build-arg PYTHON_IMAGE_VER=$(PYTHON_IMAGE_VER) --build-arg POSTGRES_IMAGE_VER=$(POSTGRES_IMAGE_VER) $(CONTAINER) + @docker compose up -d --no-deps $(CONTAINER) @docker compose restart $(CONTAINER) ## coverage.xml: generate coverage from test runs diff --git a/compose/local/django/Dockerfile b/compose/local/django/Dockerfile index 12ea411b..aaba2ef9 100644 --- a/compose/local/django/Dockerfile +++ b/compose/local/django/Dockerfile @@ -1,4 +1,6 @@ -FROM python:3.12-slim-bookworm +ARG PYTHON_IMAGE_VER=3.12 + +FROM python:${PYTHON_IMAGE_VER}-slim-bookworm ENV PIP_ROOT_USER_ACTION ignore ENV PYTHONUNBUFFERED 1 diff --git a/compose/local/docs/Dockerfile b/compose/local/docs/Dockerfile index 274d4829..49965c75 100644 --- a/compose/local/docs/Dockerfile +++ b/compose/local/docs/Dockerfile @@ -1,4 +1,6 @@ -FROM python:3.12-slim-bookworm +ARG PYTHON_IMAGE_VER=3.12 + +FROM python:${PYTHON_IMAGE_VER}-slim-bookworm ENV PIP_ROOT_USER_ACTION ignore ENV PYTHONUNBUFFERED 1 diff --git a/compose/production/django/Dockerfile b/compose/production/django/Dockerfile index cbb5aeb5..84748126 100644 --- a/compose/production/django/Dockerfile +++ b/compose/production/django/Dockerfile @@ -1,5 +1,6 @@ +ARG PYTHON_IMAGE_VER=3.12 -FROM python:3.12-slim-bookwork +FROM python:${PYTHON_IMAGE_VER}-slim-bookworm ENV PYTHONUNBUFFERED 1 diff --git a/compose/production/postgres/Dockerfile b/compose/production/postgres/Dockerfile index c4160f1e..88f86a97 100644 --- a/compose/production/postgres/Dockerfile +++ b/compose/production/postgres/Dockerfile @@ -1,4 +1,6 @@ -FROM postgres:12.3 +ARG POSTGRES_IMAGE_VER=12.3 + +FROM postgres:${POSTGRES_IMAGE_VER} COPY ./compose/production/postgres/maintenance /usr/local/bin/maintenance RUN chmod +x /usr/local/bin/maintenance/* diff --git a/config/settings/local.py b/config/settings/local.py index de20d800..56029930 100644 --- a/config/settings/local.py +++ b/config/settings/local.py @@ -51,7 +51,7 @@ } # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"] -if env("USE_DOCKER") == "yes": +if env("USE_DOCKER", default="no") == "yes": import socket hostname, _, ips = socket.gethostbyname_ex(socket.gethostname()) diff --git a/requirements/local.txt b/requirements/local.txt index 2712cf7e..134a2213 100644 --- a/requirements/local.txt +++ b/requirements/local.txt @@ -2,7 +2,7 @@ Werkzeug[watchdog]==2.0.3 # https://github.com/pallets/werkzeug ipdb==0.13.9 # https://github.com/gotcha/ipdb -psycopg2-binary==2.9.3 # https://github.com/psycopg/psycopg2 +psycopg2-binary==2.9.10 # https://github.com/psycopg/psycopg2 watchgod==0.8.2 # https://github.com/samuelcolvin/watchgod # Testing