From 4cb149f279b9a052270efabd17a99f7782b7edff Mon Sep 17 00:00:00 2001 From: C4 Patino Date: Fri, 16 Feb 2024 22:28:41 -0600 Subject: [PATCH] Update Docker build and push workflow and Dockerfile --- .dockerignore | 3 +- .github/workflows/build-deploy.yml | 54 ++++++ .github/workflows/build-docker.yml | 40 ---- .github/workflows/draft-release.yml | 17 -- .github/workflows/test-build.yml | 24 --- .vscode/settings.json | 6 +- CollegiateHouseWars/settings/__init__.py | 2 +- CollegiateHouseWars/settings/defaults.py | 17 +- CollegiateHouseWars/settings/dev.py | 25 --- CollegiateHouseWars/settings/docker.py | 2 +- CollegiateHouseWars/settings/local.py | 17 ++ CollegiateHouseWars/settings/prod.py | 15 +- CollegiateHouseWars/wsgi.py | 3 +- Dockerfile | 21 ++- Dockerfile.dev | 17 ++ docker-compose.prod.yml | 27 +++ docker-compose.yml | 8 +- .../templates/housewars/activity_form.html | 55 +++--- housewars/templates/housewars/entry_form.html | 58 +++--- templates/admin/base_site.html | 8 +- templates/base.html | 171 +++++++++--------- tests/test_points_entry_create.py | 4 - 22 files changed, 301 insertions(+), 293 deletions(-) create mode 100644 .github/workflows/build-deploy.yml delete mode 100644 .github/workflows/build-docker.yml delete mode 100644 .github/workflows/draft-release.yml delete mode 100644 .github/workflows/test-build.yml delete mode 100644 CollegiateHouseWars/settings/dev.py create mode 100644 CollegiateHouseWars/settings/local.py create mode 100644 Dockerfile.dev create mode 100644 docker-compose.prod.yml diff --git a/.dockerignore b/.dockerignore index f5e96db..2d19ec7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,2 @@ -venv \ No newline at end of file +venv +.env \ No newline at end of file diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml new file mode 100644 index 0000000..e3c8001 --- /dev/null +++ b/.github/workflows/build-deploy.yml @@ -0,0 +1,54 @@ +name: Docker Build and Push + +on: + push: + branches: + - main + tags: + - v* + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Setup Chrome + uses: nanasess/setup-chromedriver@v2 + - name: Install dependencies + run: python -m pip install -r requirements.txt + - name: Test build + run: python manage.py test + + build-and-push: + runs-on: ubuntu-latest + needs: test + + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Build & push Docker image + uses: mr-smithers-excellent/docker-build-push@v6 + with: + image: c4thebomb/csmb-housewars + registry: docker.io + addLatest: true + multiPlatform: true + platform: linux/amd64,linux/arm64/v8 + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + draft: + runs-on: ubuntu-latest + needs: test + + steps: + - uses: actions/checkout@v3 + - name: Draft release + uses: release-drafter/release-drafter@v5 + id: release-draft + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml deleted file mode 100644 index 3d4aa46..0000000 --- a/.github/workflows/build-docker.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Commit docker image - -on: - release: - types: [published] - -jobs: - build: - environment: production - runs-on: ubuntu-latest - - steps: - - name: Cache Docker layers - uses: actions/cache@v2 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - name: Checkout - uses: actions/checkout@v2 - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Build and push - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - builder: ${{ steps.buildx.outputs.name }} - push: true - tags: ${{ secrets.DOCKER_HUB_USERNAME }}/collegiate-housewars:latest - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml deleted file mode 100644 index 320533f..0000000 --- a/.github/workflows/draft-release.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Create release draft - -on: - push: - branches: [main] - -jobs: - draft: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Draft release - uses: release-drafter/release-drafter@v5 - id: release-draft - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml deleted file mode 100644 index 2a7d3cf..0000000 --- a/.github/workflows/test-build.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Test build - -on: - push: - branches: [main] - pull_request: - workflow_dispatch: - -jobs: - test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - name: Setup Chrome - uses: nanasess/setup-chromedriver@v1.0.8 - - name: Install dependencies - run: python -m pip install -r requirements.txt - - name: Test build - run: python manage.py test diff --git a/.vscode/settings.json b/.vscode/settings.json index c9eead1..aaadf14 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,9 @@ "editor.defaultFormatter": null, "[dockercompose]": { "editor.defaultFormatter": "ms-azuretools.vscode-docker" - } + }, + "lldb.displayFormat": "auto", + "lldb.showDisassembly": "auto", + "lldb.dereferencePointers": true, + "lldb.consoleMode": "commands" } diff --git a/CollegiateHouseWars/settings/__init__.py b/CollegiateHouseWars/settings/__init__.py index c787328..8f607e4 100644 --- a/CollegiateHouseWars/settings/__init__.py +++ b/CollegiateHouseWars/settings/__init__.py @@ -1 +1 @@ -from .dev import * +from .local import * diff --git a/CollegiateHouseWars/settings/defaults.py b/CollegiateHouseWars/settings/defaults.py index cfde6f3..055f083 100644 --- a/CollegiateHouseWars/settings/defaults.py +++ b/CollegiateHouseWars/settings/defaults.py @@ -1,15 +1,12 @@ from pathlib import Path from django.contrib.messages import constants -# Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent.parent SECURE_SSL_REDIRECT = False SESSION_COOKIE_SECURE = False CSRF_COOKIE_SECURE = False -# Application definition - INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', @@ -21,7 +18,7 @@ INSTALLED_APPS = [ 'smart_selects', 'formtools', - 'housewars.apps.HousewarsConfig' + 'housewars', ] MIDDLEWARE = [ @@ -55,9 +52,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'CollegiateHouseWars.wsgi.application' -# Password validation -# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators - AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', @@ -73,9 +67,6 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] -# Internationalization -# https://docs.djangoproject.com/en/4.0/topics/i18n/ - LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' @@ -84,9 +75,6 @@ USE_I18N = True USE_TZ = True -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/4.0/howto/static-files/ - STATIC_URL = 'static/' STATIC_ROOT = BASE_DIR / "staticfiles" @@ -108,9 +96,6 @@ LOGGING = { }, } -# Default primary key field type -# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field - DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/CollegiateHouseWars/settings/dev.py b/CollegiateHouseWars/settings/dev.py deleted file mode 100644 index e68a966..0000000 --- a/CollegiateHouseWars/settings/dev.py +++ /dev/null @@ -1,25 +0,0 @@ -from .defaults import * - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '*9r50c74r58p#*tnfpadsw*cp&$(^sj585w1u@!y9*eowmwl1*' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [ - 'localhost', - '127.0.0.1', -] - -# Database -# https://docs.djangoproject.com/en/4.0/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', - } -} diff --git a/CollegiateHouseWars/settings/docker.py b/CollegiateHouseWars/settings/docker.py index 451563f..e6c3a0e 100644 --- a/CollegiateHouseWars/settings/docker.py +++ b/CollegiateHouseWars/settings/docker.py @@ -1,4 +1,4 @@ -from .dev import * +from .local import * DATABASES = { 'default': { diff --git a/CollegiateHouseWars/settings/local.py b/CollegiateHouseWars/settings/local.py new file mode 100644 index 0000000..6722443 --- /dev/null +++ b/CollegiateHouseWars/settings/local.py @@ -0,0 +1,17 @@ +from .defaults import * + +SECRET_KEY = '*9r50c74r58p#*tnfpadsw*cp&$(^sj585w1u@!y9*eowmwl1*' + +DEBUG = True + +ALLOWED_HOSTS = [ + 'localhost', + '127.0.0.1', +] + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} diff --git a/CollegiateHouseWars/settings/prod.py b/CollegiateHouseWars/settings/prod.py index 5867a27..9de3904 100644 --- a/CollegiateHouseWars/settings/prod.py +++ b/CollegiateHouseWars/settings/prod.py @@ -2,29 +2,22 @@ import os from .defaults import * -# SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.environ.get('SECRET_KEY') -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = False ALLOWED_HOSTS = [ - 'housewars.c4thebomb101.com', - 'csmb-housewars.herokuapp.com', + 'csmb-housewars.c4patino.com', ] CSRF_TRUSTED_ORIGINS = [ - 'https://housewars.c4thebomb101.com', - 'https://csmb-housewars.herokuapp.com' + 'https://csmb-housewars.c4patino.com/' ] -# Database -# https://docs.djangoproject.com/en/4.0/ref/settings/#databases - DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'housewars', + 'NAME': os.environ.get('DATABASE_NAME'), 'USER': os.environ.get('DATABASE_USERNAME'), 'PASSWORD': os.environ.get('DATABASE_PASSWORD'), 'HOST': os.environ.get('DATABASE_HOST'), diff --git a/CollegiateHouseWars/wsgi.py b/CollegiateHouseWars/wsgi.py index 43bd583..6985fc8 100644 --- a/CollegiateHouseWars/wsgi.py +++ b/CollegiateHouseWars/wsgi.py @@ -12,8 +12,7 @@ import os from django.core.wsgi import get_wsgi_application from whitenoise import WhiteNoise -os.environ.setdefault('DJANGO_SETTINGS_MODULE', - 'CollegiateHouseWars.settings.prod') +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CollegiateHouseWars.settings.prod') application = get_wsgi_application() application = WhiteNoise(application) diff --git a/Dockerfile b/Dockerfile index 6523189..f042053 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,20 @@ -# syntax=docker/dockerfile:1 -FROM python:3.10.6-slim-buster -RUN apt update && apt install build-essential default-libmysqlclient-dev -y +FROM python:3.10 + +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 + WORKDIR /app + COPY requirements.txt requirements.txt -RUN python -m pip install -r requirements.txt + +RUN pip install --upgrade pip && \ + pip install -r requirements.txt && \ + pip install gunicorn + COPY . . + +RUN python manage.py collectstatic --noinput + EXPOSE 8000/tcp -CMD python manage.py runserver 0.0.0.0:8000 \ No newline at end of file + +CMD ["gunicorn", "--bind", "0.0.0.0:8000", "CollegiateHouseWars.wsgi:application"] \ No newline at end of file diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..42d8fca --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,17 @@ +FROM python:3.10 + +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 + +WORKDIR /app + +COPY requirements.txt requirements.txt + +RUN pip install --upgrade pip && \ + pip install -r requirements.txt + +COPY . . + +EXPOSE 8000/tcp + +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..1cb8e52 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,27 @@ +version: '3.8' + +services: + app: + restart: unless-stopped + build: + context: . + dockerfile: Dockerfile + platforms: + - linux/amd64 + - linux/arm64/v8 + image: c4thebomb/csmb-housewars:${TAG:-latest} + env_file: + - path: .env + required: true + ports: + - 127.0.0.1:8000:8000 + networks: + - housewars + - common-network + external_links: + - mysqldb + +networks: + common-network: + external: true + housewars: {} diff --git a/docker-compose.yml b/docker-compose.yml index 4dd4664..2d0b8c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,10 +5,12 @@ services: restart: unless-stopped build: context: . + dockerfile: Dockerfile.dev ports: - 8000:8000 volumes: - ./:/app + networks: - housewars environment: @@ -20,11 +22,12 @@ services: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000" mysqldb: restart: unless-stopped - image: mysql:5.7 + image: mysql:8.3 ports: - 3306:3306 volumes: - housewars-mysql:/var/lib/mysql + networks: - housewars environment: @@ -34,7 +37,10 @@ services: test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ] timeout: 5s retries: 10 + volumes: housewars-mysql: + + networks: housewars: {} diff --git a/housewars/templates/housewars/activity_form.html b/housewars/templates/housewars/activity_form.html index 0ca21ee..d4c69f2 100644 --- a/housewars/templates/housewars/activity_form.html +++ b/housewars/templates/housewars/activity_form.html @@ -2,38 +2,39 @@ {% load i18n %} {% block step-counter %} -
-
-
- -

Info

-
-
- -

Activities

-
+
+
+
+ +

Info

+
+
+ +

Activities

+
{% endblock %} {% block content %} -
- {% csrf_token %} - {{ wizard.management_form }} + + {% csrf_token %} + {{ wizard.management_form }} -
- - {{ form.activity1 }} -
-
- - {{ form.activity2 }} -
+
+ + {{ form.activity1 }} +
+
+ + {{ form.activity2 }} +
-
- - -
-
+
+ + +
+ {% endblock %} \ No newline at end of file diff --git a/housewars/templates/housewars/entry_form.html b/housewars/templates/housewars/entry_form.html index e4101f9..3f829a5 100644 --- a/housewars/templates/housewars/entry_form.html +++ b/housewars/templates/housewars/entry_form.html @@ -18,34 +18,34 @@ {% endblock %} {% block content %} -
- {% csrf_token %} - {{ wizard.management_form }} - - -
-
- {{ form.first_name }} -
-
- {{ form.last_name }} -
+ + {% csrf_token %} + {{ wizard.management_form }} + + +
+
+ {{ form.first_name }}
-
- - {{ form.email }} +
+ {{ form.last_name }}
-
- - {{ form.grade }} -
-
- - {{ form.house }} -
- -
- -
- -{% endblock %} +
+
+ + {{ form.email }} +
+
+ + {{ form.grade }} +
+
+ + {{ form.house }} +
+ +
+ +
+ +{% endblock %} \ No newline at end of file diff --git a/templates/admin/base_site.html b/templates/admin/base_site.html index 8c03c15..c13e823 100644 --- a/templates/admin/base_site.html +++ b/templates/admin/base_site.html @@ -1,10 +1,10 @@ {% extends "admin/base_site.html" %} {% block title %} - {% if subtitle %} - {{ subtitle }} | - {% endif %} - {{ title }} | House Wars Admin +{% if subtitle %} +{{ subtitle }} | +{% endif %} +{{ title }} | House Wars Admin {% endblock %} {% block branding %} diff --git a/templates/base.html b/templates/base.html index c33a85b..54e7cdb 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,95 +1,98 @@ {% load static %} - - - - - - - - - - + + + + - - + + + - {% block title %} - - {% if title %}{{ title }}{% endif %} | House Wars - - {% endblock %} - - -
-
-
-
- {% block step-counter %}{% endblock %} -
- - - - - {% block content %}{% endblock %} - - -
- {% if messages %} - {% for message in messages %} -
{{ message }}
- {% endfor %} - {% endif %} - - {% if form.errors %} - {% for field in form %} - {% for error in field.errors %} -
{{ error }}
- {% endfor %} - {% endfor %} - - {% for error in form.non_field_errors %} -
{{ error }}
- {% endfor %} - {% endif %} -
+ + + + + + + {% block title %} + + {% if title %}{{ title }}{% endif %} | House Wars + + {% endblock %} + + + +
+
+
+
+ {% block step-counter %}{% endblock %}
-
- - +
+
+ + + \ No newline at end of file diff --git a/tests/test_points_entry_create.py b/tests/test_points_entry_create.py index 1350719..a39576b 100644 --- a/tests/test_points_entry_create.py +++ b/tests/test_points_entry_create.py @@ -42,10 +42,6 @@ class PointsEntryCreatePageTest(StaticLiveServerTestCase): Select(self.browser.find_element(By.ID, 'id_activity')).select_by_visible_text('Dodgeball - 30 min') Select(self.browser.find_element(By.ID, 'house')).select_by_visible_text('Hawk') - # Wait until the Select button with '1st' shows up - WebDriverWait(self.browser, timeout=5).until(visibility_of( - self.browser.find_element(By.XPATH, "//option[text()='1st']"))) - time.sleep(0.25) Select(self.browser.find_element(By.ID, 'id_award')).select_by_visible_text('1st')