From be57ef07acf7491ad1e262150e3bbd5c4e203107 Mon Sep 17 00:00:00 2001 From: "Samuel T." Date: Thu, 3 Oct 2024 14:02:57 -0400 Subject: [PATCH] Check for missing migration (#256) --- ...yml => canopeum_backend_pr_validation.yml} | 19 +++++++++++-- ...ml => canopeum_frontend_pr_validation.yml} | 6 ++-- canopeum_backend/canopeum_backend/settings.py | 28 ++++++++++++------- canopeum_backend/test.py | 21 ++++++++++++++ 4 files changed, 58 insertions(+), 16 deletions(-) rename .github/workflows/{canopeum_backend.yml => canopeum_backend_pr_validation.yml} (69%) rename .github/workflows/{canopeum_frontend.yml => canopeum_frontend_pr_validation.yml} (80%) create mode 100644 canopeum_backend/test.py diff --git a/.github/workflows/canopeum_backend.yml b/.github/workflows/canopeum_backend_pr_validation.yml similarity index 69% rename from .github/workflows/canopeum_backend.yml rename to .github/workflows/canopeum_backend_pr_validation.yml index 998dcd612..10fe0e073 100644 --- a/.github/workflows/canopeum_backend.yml +++ b/.github/workflows/canopeum_backend_pr_validation.yml @@ -1,4 +1,4 @@ -name: canopeum_backend +name: Backend PR validation on: push: @@ -6,14 +6,14 @@ on: - main paths: - "canopeum_backend/**" - - ".github/workflows/canopeum_backend.yml" + - ".github/workflows/canopeum_backend_pr_validation.yml" pull_request: branches: - main - production paths: - "canopeum_backend/**" - - ".github/workflows/canopeum_backend.yml" + - ".github/workflows/canopeum_backend_pr_validation.yml" env: # Since the Django mypy extention RUNS the config file, we need a non-empty secret to avoid @@ -21,6 +21,19 @@ env: SECRET_KEY_DJANGO_CANOPEUM: mypy-ext jobs: + django-test: + runs-on: ubuntu-latest + defaults: + run: + working-directory: canopeum_backend + steps: + - uses: actions/checkout@v4 + - name: Install uv using the standalone installer + run: curl -LsSf https://astral.sh/uv/install.sh | sh + - run: uv sync --locked --extra dev + - run: echo "$PWD/.venv/bin" >> $GITHUB_PATH + - name: Run Django Tests + run: python manage.py test mypy: runs-on: ubuntu-latest defaults: diff --git a/.github/workflows/canopeum_frontend.yml b/.github/workflows/canopeum_frontend_pr_validation.yml similarity index 80% rename from .github/workflows/canopeum_frontend.yml rename to .github/workflows/canopeum_frontend_pr_validation.yml index d76ffa34f..e3563610e 100644 --- a/.github/workflows/canopeum_frontend.yml +++ b/.github/workflows/canopeum_frontend_pr_validation.yml @@ -1,4 +1,4 @@ -name: canopeum_frontend +name: Frontend PR validation on: push: @@ -6,14 +6,14 @@ on: - main paths: - "canopeum_frontend/**" - - ".github/workflows/canopeum_frontend.yml" + - ".github/workflows/canopeum_frontend_pr_validation.yml" pull_request: branches: - main - production paths: - "canopeum_frontend/**" - - ".github/workflows/canopeum_frontend.yml" + - ".github/workflows/canopeum_frontend_pr_validation.yml" jobs: Lint: diff --git a/canopeum_backend/canopeum_backend/settings.py b/canopeum_backend/canopeum_backend/settings.py index 51b55f053..346616b36 100644 --- a/canopeum_backend/canopeum_backend/settings.py +++ b/canopeum_backend/canopeum_backend/settings.py @@ -11,6 +11,7 @@ """ import os +import sys from datetime import timedelta from pathlib import Path @@ -170,17 +171,24 @@ def get_secret(key: str, default: str): # Database # https://docs.djangoproject.com/en/5.0/ref/settings/#databases - DATABASES = { - "default": dj_database_url.parse( - "mysql://canopeum_user:{}@{}:{}/canopeum_db".format( - get_secret("MYSQL_PASSWORD_CANOPEUM", ""), - get_secret("MYSQL_HOST_CANOPEUM", "localhost"), - get_secret("MYSQL_PORT_CANOPEUM", "3308"), - ), - conn_max_age=600, - conn_health_checks=True, - ) + "default": ( + # If running Django tests, use an in-memory database, + # which is faster and requires less setup + # Using conditional instead of TEST dictionary because USER can't be overriden + # https://docs.djangoproject.com/en/5.1/topics/testing/overview/#the-test-database + {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"} + if sys.argv[1] == "test" + else dj_database_url.parse( + "mysql://canopeum_user:{}@{}:{}/canopeum_db".format( + get_secret("MYSQL_PASSWORD_CANOPEUM", ""), + get_secret("MYSQL_HOST_CANOPEUM", "localhost"), + get_secret("MYSQL_PORT_CANOPEUM", "3308"), + ), + conn_max_age=600, + conn_health_checks=True, + ) + ), } # Password validation diff --git a/canopeum_backend/test.py b/canopeum_backend/test.py new file mode 100644 index 000000000..ff81fdd16 --- /dev/null +++ b/canopeum_backend/test.py @@ -0,0 +1,21 @@ +# This should preferably go in a test folder. But we only have a single test for now +# Tests are auto-discovered as long as they're named test*.py +from io import StringIO + +from django.core.management import call_command +from django.test import TestCase as DBTestCase + + +class PendingMigrationsTests(DBTestCase): + def test_no_pending_migrations(self): + out = StringIO() + try: + # https://docs.djangoproject.com/en/5.1/ref/django-admin/#cmdoption-makemigrations-check + call_command( + "makemigrations", + "--check", + stdout=out, + stderr=StringIO(), + ) + except SystemExit: + raise AssertionError("Pending migrations:\n" + out.getvalue()) from None