From 6712f4aea83e65380e86ad379fdf0f02bacfa8ec Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Sun, 29 Sep 2024 22:50:58 -0400
Subject: [PATCH 1/9] chore: Rename cove_project to core, like in handbook
---
.github/workflows/ci.yml | 2 +-
{cove_project => core}/__init__.py | 0
{cove_project => core}/context_processors.py | 0
{cove_project => core}/settings.py | 0
{cove_project => core}/templates/terms.html | 0
{cove_project => core}/urls.py | 0
{cove_project => core}/wsgi.py | 4 ++--
manage.py | 2 +-
pyproject.toml | 2 +-
9 files changed, 5 insertions(+), 5 deletions(-)
rename {cove_project => core}/__init__.py (100%)
rename {cove_project => core}/context_processors.py (100%)
rename {cove_project => core}/settings.py (100%)
rename {cove_project => core}/templates/terms.html (100%)
rename {cove_project => core}/urls.py (100%)
rename {cove_project => core}/wsgi.py (72%)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 713d465..7132bdf 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -23,5 +23,5 @@ jobs:
./manage.py migrate
./manage.py makemigrations --check --dry-run
./manage.py check --fail-level WARNING
- coverage run --source=cove_oc4ids,cove_project -m pytest -W error
+ coverage run --source=core,cove_oc4ids -m pytest -W error
- uses: coverallsapp/github-action@v2
diff --git a/cove_project/__init__.py b/core/__init__.py
similarity index 100%
rename from cove_project/__init__.py
rename to core/__init__.py
diff --git a/cove_project/context_processors.py b/core/context_processors.py
similarity index 100%
rename from cove_project/context_processors.py
rename to core/context_processors.py
diff --git a/cove_project/settings.py b/core/settings.py
similarity index 100%
rename from cove_project/settings.py
rename to core/settings.py
diff --git a/cove_project/templates/terms.html b/core/templates/terms.html
similarity index 100%
rename from cove_project/templates/terms.html
rename to core/templates/terms.html
diff --git a/cove_project/urls.py b/core/urls.py
similarity index 100%
rename from cove_project/urls.py
rename to core/urls.py
diff --git a/cove_project/wsgi.py b/core/wsgi.py
similarity index 72%
rename from cove_project/wsgi.py
rename to core/wsgi.py
index bc339f7..a08c895 100644
--- a/cove_project/wsgi.py
+++ b/core/wsgi.py
@@ -1,5 +1,5 @@
"""
-WSGI config for cove_project project.
+WSGI config for core project.
It exposes the WSGI callable as a module-level variable named ``application``.
@@ -11,6 +11,6 @@
from django.core.wsgi import get_wsgi_application
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cove_project.settings")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
application = get_wsgi_application()
diff --git a/manage.py b/manage.py
index 0c1fd3e..d68553b 100755
--- a/manage.py
+++ b/manage.py
@@ -3,7 +3,7 @@
import sys
if __name__ == "__main__":
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cove_project.settings")
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
from django.core.management import execute_from_command_line
diff --git a/pyproject.toml b/pyproject.toml
index 13707c2..a368b7e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -28,4 +28,4 @@ ignore-variadic-names = true
]
[tool.pytest.ini_options]
-DJANGO_SETTINGS_MODULE = 'cove_project.settings'
+DJANGO_SETTINGS_MODULE = 'core.settings'
From fec3c52f1a40a6ec987fdc0f93c1fdfc454b0d15 Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Mon, 30 Sep 2024 00:15:55 -0400
Subject: [PATCH 2/9] chore: Align with Django 4.2
---
core/asgi.py | 16 ++++++++++++++++
manage.py | 10 +++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 core/asgi.py
diff --git a/core/asgi.py b/core/asgi.py
new file mode 100644
index 0000000..66c1231
--- /dev/null
+++ b/core/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for core project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
+
+application = get_asgi_application()
diff --git a/manage.py b/manage.py
index d68553b..bd9928d 100755
--- a/manage.py
+++ b/manage.py
@@ -1,10 +1,18 @@
#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+
import os
import sys
-if __name__ == "__main__":
+
+def main():
+ """Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
+
+
+if __name__ == "__main__":
+ main()
From 9ff2d42e978c92e86b022bbe0d24f20a49e2bf37 Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Mon, 30 Sep 2024 00:17:15 -0400
Subject: [PATCH 3/9] chore: Upgrade to Python 3.11
---
.github/workflows/ci.yml | 2 +-
.github/workflows/i18n.yml | 2 +-
.github/workflows/lint.yml | 2 +-
.pre-commit-config.yaml | 2 +-
.python-version | 2 +-
pyproject.toml | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7132bdf..e31d612 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -8,7 +8,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
- python-version: '3.10'
+ python-version: '3.11'
cache: pip
cache-dependency-path: '**/requirements*.txt'
- run: pip install -r requirements.txt
diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml
index b6b6040..a8d4f53 100644
--- a/.github/workflows/i18n.yml
+++ b/.github/workflows/i18n.yml
@@ -10,7 +10,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
- python-version: '3.10'
+ python-version: '3.11'
cache: pip
cache-dependency-path: '**/requirements*.txt'
- name: Install translate-toolkit
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 2fc37d9..6a60c4c 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -14,7 +14,7 @@ jobs:
token: ${{ secrets.PAT || github.token }}
- uses: actions/setup-python@v5
with:
- python-version: '3.10'
+ python-version: '3.11'
cache: pip
cache-dependency-path: '**/requirements*.txt'
- id: changed-files
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8d828bc..54e08b8 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,7 +2,7 @@ ci:
autoupdate_schedule: quarterly
skip: [pip-compile]
default_language_version:
- python: python3.10
+ python: python3.11
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.3
diff --git a/.python-version b/.python-version
index c8cfe39..2c07333 100644
--- a/.python-version
+++ b/.python-version
@@ -1 +1 @@
-3.10
+3.11
diff --git a/pyproject.toml b/pyproject.toml
index a368b7e..9a37b3e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
[tool.ruff]
line-length = 119
-target-version = "py310"
+target-version = "py311"
[tool.ruff.lint]
select = ["ALL"]
From ec8c00745eda654d3cf328113eb60b4499cb6153 Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Mon, 30 Sep 2024 00:18:55 -0400
Subject: [PATCH 4/9] feat: Add files for Docker. Rewrite settings.py to match
cookiecutter and use Docker paths for media and db.
---
.dockerignore | 26 +++++
.github/workflows/docker.yml | 38 ++++++
Dockerfile_django | 43 +++++++
Dockerfile_static | 17 +++
core/settings.py | 221 +++++++++++++++++++++++------------
default.conf | 56 +++++++++
6 files changed, 329 insertions(+), 72 deletions(-)
create mode 100644 .dockerignore
create mode 100644 .github/workflows/docker.yml
create mode 100644 Dockerfile_django
create mode 100644 Dockerfile_static
create mode 100644 default.conf
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..b8f6dd2
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,26 @@
+# Dotfiles
+**/.*
+
+# Docker
+**/Dockerfile*
+
+# Requirements
+**/requirements.in
+**/requirements_dev.in
+**/requirements_dev.txt
+
+# Documentation
+docs
+LICENSE
+README.md
+README.rst
+
+# Configuration
+pyproject.toml
+
+# Testing
+**/tests
+pytest.ini
+
+# Generated files
+**/node_modules
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
new file mode 100644
index 0000000..508d90d
--- /dev/null
+++ b/.github/workflows/docker.yml
@@ -0,0 +1,38 @@
+name: Deploy
+on:
+ workflow_run:
+ workflows: ["CI"]
+ branches: [main]
+ types:
+ - completed
+jobs:
+ docker:
+ if: ${{ github.event.workflow_run.conclusion == 'success' }}
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ # https://github.com/docker/login-action#github-container-registry
+ - uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ # https://github.com/docker/setup-buildx-action#usage
+ - uses: docker/setup-buildx-action@v3
+ # https://github.com/docker/build-push-action#usage
+ - uses: docker/build-push-action@v6
+ with:
+ push: true
+ file: Dockerfile_django
+ tags: |
+ ghcr.io/${{ github.repository }}-django:latest
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+ - uses: docker/build-push-action@v6
+ with:
+ push: true
+ file: Dockerfile_static
+ tags: |
+ ghcr.io/${{ github.repository }}-static:latest
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
diff --git a/Dockerfile_django b/Dockerfile_django
new file mode 100644
index 0000000..96255db
--- /dev/null
+++ b/Dockerfile_django
@@ -0,0 +1,43 @@
+FROM python:3.11 as build-stage
+
+COPY requirements.txt /tmp/requirements.txt
+RUN pip install --no-cache-dir -r /tmp/requirements.txt
+
+WORKDIR /workdir
+
+COPY . .
+
+ENV DJANGO_ENV=production
+
+RUN python manage.py collectstatic --noinput -v2
+
+FROM python:3.11
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ gettext \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN groupadd -r runner && useradd --no-log-init -r -g runner runner
+
+# Must match the settings.DATABASES default value.
+RUN mkdir -p /data/db && chown -R runner:runner /data/db
+# Must match the settings.MEDIA_ROOT default value.
+RUN mkdir -p /data/media && chown -R runner:runner /data/media
+
+COPY requirements.txt /tmp/requirements.txt
+RUN pip install --no-cache-dir -r /tmp/requirements.txt
+
+WORKDIR /workdir
+USER runner:runner
+COPY --chown=runner:runner . .
+
+# Django needs a copy of the staticfiles.json manifest file.
+COPY --from=build-stage --chown=runner:runner /workdir/static/staticfiles.json /workdir/static/staticfiles.json
+
+ENV DJANGO_ENV=production
+ENV WEB_CONCURRENCY=2
+
+RUN python manage.py compilemessages
+
+EXPOSE 8000
+CMD ["gunicorn", "core.wsgi", "--bind", "0.0.0.0:8000", "--worker-tmp-dir", "/dev/shm", "--threads", "2", "--name", "cove"]
diff --git a/Dockerfile_static b/Dockerfile_static
new file mode 100644
index 0000000..a6360e8
--- /dev/null
+++ b/Dockerfile_static
@@ -0,0 +1,17 @@
+FROM python:{{ cookiecutter.python_version }} as build-stage
+
+COPY requirements.txt /tmp/requirements.txt
+RUN pip install --no-cache-dir -r /tmp/requirements.txt
+
+WORKDIR /workdir
+COPY . .
+
+ENV DJANGO_ENV=production
+
+RUN python manage.py collectstatic --noinput -v2
+
+FROM nginxinc/nginx-unprivileged:latest as production-stage
+USER root
+COPY --from=build-stage --chown=nginx:root /workdir/static /usr/share/nginx/html/static
+COPY --chown=nginx:root default.conf /etc/nginx/conf.d/default.conf
+USER nginx
diff --git a/core/settings.py b/core/settings.py
index d367f9d..c5eb391 100644
--- a/core/settings.py
+++ b/core/settings.py
@@ -1,5 +1,5 @@
"""
-Django settings for cove_project project.
+Django settings for the project.
Generated by 'django-admin startproject'.
@@ -11,42 +11,33 @@
"""
import os
+from glob import glob
from pathlib import Path
-from cove import settings
+import sentry_sdk
+from sentry_sdk.integrations.django import DjangoIntegration
+from sentry_sdk.integrations.logging import ignore_logger
-# Build paths inside the project like this: BASE_DIR / "subdir".
+production = os.getenv("DJANGO_ENV") == "production"
+local_access = "LOCAL_ACCESS" in os.environ or "ALLOWED_HOSTS" not in os.environ
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
-# We use the setting to choose whether to show the section about Sentry in the
-# terms and conditions
-SENTRY_DSN = os.getenv("SENTRY_DSN", "")
-if SENTRY_DSN:
- import sentry_sdk
- from sentry_sdk.integrations.django import DjangoIntegration
- from sentry_sdk.integrations.logging import ignore_logger
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
- ignore_logger("django.security.DisallowedHost")
- sentry_sdk.init(dsn=SENTRY_DSN, integrations=[DjangoIntegration()])
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = os.getenv("SECRET_KEY", "2n5k63x#a(xc@-!tpxisd)bd!3bimfr1prj-*t7tnl(*j+#$0k")
-FATHOM = {
- "domain": os.getenv("FATHOM_ANALYTICS_DOMAIN", "cdn.usefathom.com"),
- "id": os.getenv("FATHOM_ANALYTICS_ID", ""),
-}
-VALIDATION_ERROR_LOCATIONS_LENGTH = settings.VALIDATION_ERROR_LOCATIONS_LENGTH
-VALIDATION_ERROR_LOCATIONS_SAMPLE = settings.VALIDATION_ERROR_LOCATIONS_SAMPLE
-DELETE_FILES_AFTER_DAYS = int(os.getenv("DELETE_FILES_AFTER_DAYS", "90"))
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = not production
-# We can't take MEDIA_ROOT and MEDIA_URL from cove settings,
-# ... otherwise the files appear under the BASE_DIR that is the Cove library install.
-# That could get messy. We want them to appear in our directory.
-MEDIA_ROOT = BASE_DIR / "media"
-MEDIA_URL = "/infrastructure/media/"
+ALLOWED_HOSTS = [".localhost", "127.0.0.1", "[::1]", "0.0.0.0"] # noqa: S104 # Docker
+if "ALLOWED_HOSTS" in os.environ:
+ ALLOWED_HOSTS.extend(os.getenv("ALLOWED_HOSTS").split(","))
-SECRET_KEY = os.getenv("SECRET_KEY", "2n5k63x#a(xc@-!tpxisd)bd!3bimfr1prj-*t7tnl(*j+#$0k")
-DEBUG = settings.DEBUG
-ALLOWED_HOSTS = settings.ALLOWED_HOSTS
# Application definition
@@ -66,6 +57,7 @@
MIDDLEWARE = (
"django.middleware.cache.UpdateCacheMiddleware",
+ "django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
@@ -73,32 +65,45 @@
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
- "django.middleware.security.SecurityMiddleware",
"cove.middleware.CoveConfigCurrentApp",
"django.middleware.cache.FetchFromCacheMiddleware",
)
+ROOT_URLCONF = "core.urls"
+
+TEMPLATES = [
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [BASE_DIR / "core" / "templates"],
+ "APP_DIRS": True,
+ "OPTIONS": {
+ "context_processors": [
+ "django.template.context_processors.debug",
+ "django.template.context_processors.request",
+ "django.template.context_processors.i18n",
+ "django.contrib.auth.context_processors.auth",
+ "django.contrib.messages.context_processors.messages",
+ "cove.context_processors.from_settings",
+ "core.context_processors.from_settings",
+ ],
+ },
+ },
+]
-ROOT_URLCONF = "cove_project.urls"
+WSGI_APPLICATION = "core.wsgi.application"
-TEMPLATES = settings.TEMPLATES
-TEMPLATES[0]["DIRS"] = [BASE_DIR / "cove_project" / "templates"]
-TEMPLATES[0]["OPTIONS"]["context_processors"].append(
- "cove_project.context_processors.from_settings",
-)
-WSGI_APPLICATION = "cove_project.wsgi.application"
+# Database
+# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
-# We can't take DATABASES from cove settings,
-# ... otherwise the files appear under the BASE_DIR that is the Cove library install.
-# That could get messy. We want them to appear in our directory.
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
- "NAME": os.getenv("DB_NAME", str(BASE_DIR / "db.sqlite3")),
+ "NAME": os.getenv("DATABASE_PATH", "/data/db/db.sqlite3" if production else str(BASE_DIR / "db.sqlite3")),
}
}
+
# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
@@ -121,36 +126,117 @@
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
-LANGUAGE_CODE = settings.LANGUAGE_CODE
-TIME_ZONE = settings.TIME_ZONE
-USE_I18N = settings.USE_I18N
-USE_TZ = settings.USE_TZ
+LANGUAGE_CODE = "en-us"
+
+TIME_ZONE = "UTC"
-LANGUAGES = settings.LANGUAGES
+USE_I18N = True
+
+USE_TZ = True
-LOCALE_PATHS = (BASE_DIR / "cove_oc4ids" / "locale",)
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
-# We can't take STATIC_URL and STATIC_ROOT from cove settings,
-# ... otherwise the files appear under the BASE_DIR that is the Cove library install.
-# and that doesn't work with our standard Apache setup.
-STATIC_URL = "infrastructure/static/"
-STATIC_ROOT = BASE_DIR / "static"
+STATIC_URL = "static/"
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
+
-# Misc
+# Project-specific Django configuration
-LOGGING = settings.LOGGING
-LOGGING["handlers"]["null"] = {
- "class": "logging.NullHandler",
+LOCALE_PATHS = glob(str(BASE_DIR / "**" / "locale"))
+
+STATIC_ROOT = BASE_DIR / "static"
+
+STORAGES = {
+ "default": {
+ "BACKEND": "django.core.files.storage.FileSystemStorage",
+ },
+ "staticfiles": {
+ "BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
+ },
}
-LOGGING["loggers"]["django.security.DisallowedHost"] = {
- "handlers": ["null"],
- "propagate": False,
+
+# https://docs.djangoproject.com/en/4.2/topics/logging/#django-security
+LOGGING = {
+ "version": 1,
+ "disable_existing_loggers": False,
+ "formatters": {
+ "console": {
+ "format": "%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(message)s",
+ },
+ },
+ "handlers": {
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "console",
+ },
+ "null": {
+ "class": "logging.NullHandler",
+ },
+ },
+ "loggers": {
+ "": {
+ "handlers": ["console"],
+ "level": "INFO",
+ },
+ "django.security.DisallowedHost": {
+ "handlers": ["null"],
+ "propagate": False,
+ },
+ },
}
-# OC4IDS Config
+# https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
+if production and not local_access:
+ # Run: env DJANGO_ENV=production SECURE_HSTS_SECONDS=1 ./manage.py check --deploy
+ CSRF_COOKIE_SECURE = True
+ SESSION_COOKIE_SECURE = True
+ SECURE_SSL_REDIRECT = True
+ SECURE_REFERRER_POLICY = "same-origin" # default in Django >= 3.1
+
+ # https://docs.djangoproject.com/en/4.2/ref/middleware/#http-strict-transport-security
+ if "SECURE_HSTS_SECONDS" in os.environ:
+ SECURE_HSTS_SECONDS = int(os.getenv("SECURE_HSTS_SECONDS"))
+ SECURE_HSTS_INCLUDE_SUBDOMAINS = True
+ SECURE_HSTS_PRELOAD = True
+
+# https://docs.djangoproject.com/en/4.2/ref/settings/#secure-proxy-ssl-header
+if "DJANGO_PROXY" in os.environ:
+ USE_X_FORWARDED_HOST = True
+ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
+
+LANGUAGES = (
+ ("en", "English"),
+ ("es", "Spanish"),
+)
+
+MEDIA_ROOT = os.getenv("MEDIA_ROOT", "/data/media/" if production else BASE_DIR / "media/")
+MEDIA_URL = "media/"
+
+if production:
+ CACHES = {
+ "default": {
+ "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
+ "LOCATION": "127.0.0.1:11211",
+ }
+ }
+
+
+# Dependency configuration
+
+if "SENTRY_DSN" in os.environ:
+ # https://docs.sentry.io/platforms/python/logging/#ignoring-a-logger
+ ignore_logger("django.security.DisallowedHost")
+ sentry_sdk.init(
+ dsn=os.getenv("SENTRY_DSN"),
+ integrations=[DjangoIntegration()],
+ traces_sample_rate=0, # The Sentry plan does not include Performance.
+ )
COVE_CONFIG = {
# lib-cove-web options
@@ -162,19 +248,10 @@
"support_email": "data@open-contracting.org",
}
-# Because of how the standard site proxies traffic, we want to use this
-USE_X_FORWARDED_HOST = True
-# This Cove is served from the same domain as another Django app.
-# To make sure sessions and CSRF tokens don't clash, use different names.
-# https://github.com/open-contracting/deploy/issues/188
-CSRF_COOKIE_NAME = "oc4idscsrftoken"
-SESSION_COOKIE_NAME = "oc4idssessionid"
+# Project configuration
-if not DEBUG:
- CACHES = {
- "default": {
- "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
- "LOCATION": "127.0.0.1:11211",
- }
- }
+FATHOM = {
+ "domain": os.getenv("FATHOM_ANALYTICS_DOMAIN") or "cdn.usefathom.com",
+ "id": os.getenv("FATHOM_ANALYTICS_ID"),
+}
diff --git a/default.conf b/default.conf
new file mode 100644
index 0000000..d4f4a75
--- /dev/null
+++ b/default.conf
@@ -0,0 +1,56 @@
+server {
+ listen 8080;
+ listen [::]:8080;
+ server_name localhost;
+ server_tokens off;
+
+ #access_log /var/log/nginx/host.access.log main;
+
+ location /media/ {
+ root /data;
+ }
+
+ location / {
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+
+ location /static/ {
+ expires max;
+ }
+ location = /static/staticfiles.json {
+ expires -1;
+ }
+ }
+
+ #error_page 404 /404.html;
+
+ # redirect server error pages to the static page /50x.html
+ #
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
+
+ # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+ #
+ #location ~ \.php$ {
+ # proxy_pass http://127.0.0.1;
+ #}
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # root html;
+ # fastcgi_pass 127.0.0.1:9000;
+ # fastcgi_index index.php;
+ # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
+ # include fastcgi_params;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+}
From b9a61827328383dde1ae83d94c402d5cf2ac4c7b Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Mon, 30 Sep 2024 01:18:27 -0400
Subject: [PATCH 5/9] chore: Ignore ARG001 in pytest fixture
---
pyproject.toml | 1 +
1 file changed, 1 insertion(+)
diff --git a/pyproject.toml b/pyproject.toml
index 9a37b3e..2ab63ea 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -25,6 +25,7 @@ ignore-variadic-names = true
"*/migrations/*" = ["E501"]
"tests/*" = [
"D", "FBT003", "INP001", "PLR2004", "PT", "S", "TRY003",
+ "ARG001", # fixtures
]
[tool.pytest.ini_options]
From 9093623ed49a572d931a4537565cae318e01bc9d Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Wed, 2 Oct 2024 14:25:36 -0400
Subject: [PATCH 6/9] chore: Remove link to favicon that doesn't exist
---
core/settings.py | 2 +-
cove_oc4ids/templates/cove_oc4ids/base.html | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/core/settings.py b/core/settings.py
index c5eb391..8b2b525 100644
--- a/core/settings.py
+++ b/core/settings.py
@@ -235,7 +235,7 @@
sentry_sdk.init(
dsn=os.getenv("SENTRY_DSN"),
integrations=[DjangoIntegration()],
- traces_sample_rate=0, # The Sentry plan does not include Performance.
+ traces_sample_rate=1.0,
)
COVE_CONFIG = {
diff --git a/cove_oc4ids/templates/cove_oc4ids/base.html b/cove_oc4ids/templates/cove_oc4ids/base.html
index 493ba47..f832163 100644
--- a/cove_oc4ids/templates/cove_oc4ids/base.html
+++ b/cove_oc4ids/templates/cove_oc4ids/base.html
@@ -3,7 +3,6 @@
{% load static %}
{% block after_head %}
-
{% include "cove_oc4ids/fathom.html" %}
From 4061ceee0f512d6827db2b235ba222c91814f30b Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Wed, 2 Oct 2024 14:37:01 -0400
Subject: [PATCH 7/9] ci: Run collectstatic to satisfy
ManifestStaticFilesStorage
---
.github/workflows/ci.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e31d612..cca922e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,6 +15,7 @@ jobs:
# Check requirements.txt contains production requirements.
- run: ./manage.py --help
- run: pip install -r requirements_dev.txt
+ - run: ./manage.py collectstatic --noinput -v2
- name: Run checks and tests
env:
PYTHONWARNINGS: error
From 01a93bf056e4a550146630221bdb17bd45c74f96 Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Wed, 2 Oct 2024 14:39:05 -0400
Subject: [PATCH 8/9] feat: Increase DATA_UPLOAD_MAX_MEMORY_SIZE to 5MB (2.5MB
default)
---
core/settings.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/core/settings.py b/core/settings.py
index 8b2b525..cff3cc9 100644
--- a/core/settings.py
+++ b/core/settings.py
@@ -218,6 +218,9 @@
MEDIA_ROOT = os.getenv("MEDIA_ROOT", "/data/media/" if production else BASE_DIR / "media/")
MEDIA_URL = "media/"
+# https://docs.djangoproject.com/en/4.2/ref/settings/#data-upload-max-memory-size
+DATA_UPLOAD_MAX_MEMORY_SIZE = 52428800 # 5 MB
+
if production:
CACHES = {
"default": {
From b4f7a2d3dc09c8158189984e1d9d80fe97f9faae Mon Sep 17 00:00:00 2001
From: James McKinney <26463+jpmckinney@users.noreply.github.com>
Date: Wed, 2 Oct 2024 14:52:29 -0400
Subject: [PATCH 9/9] chore: Ignore /static
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index 97162bf..4b3fbd7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ __pycache__
.coverage
.ve
/media
+/static