Skip to content

Commit

Permalink
Merge branch 'dev' into chore/urlconf
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe-Heffer-Shef authored Jan 20, 2025
2 parents 4f3c821 + a42d779 commit 9713e2c
Show file tree
Hide file tree
Showing 93 changed files with 3,293 additions and 1,778 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/lint-nginx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# GitHub Actions workflow for validating NGINX configuration files
# https://github.com/jhinch/nginx-linter
name: Lint NGINX config files
on:
pull_request:
push:
branches:
- main
jobs:
lint:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install nginx-linter
run: npm install -g nginx-linter
- name: Run nginx linter
run: nginx-linter --include config/nginx/* --no-follow-includes
6 changes: 3 additions & 3 deletions .github/workflows/lint-python.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ jobs:
- name: Lint Python code
run: |
dirs="SORT home survey invites"
isort $dirs
black $dirs
flake8 $dirs
isort $dirs --skip-glob '*/migrations/*'
black $dirs --exclude '/migrations/'
flake8 $dirs --exclude '*/migrations/*'
# Suggest merging any changes
- name: Create Pull Request
# https://github.com/marketplace/actions/create-pull-request
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/lint-shell-scripts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Lint shell scripts
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions
# https://github.com/marketplace/actions/shell-linter
name: Lint shell scripts
on:
pull_request:
push:
branches:
- main
jobs:
lint_shell:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: azohra/shell-linter@v0.6.0
with:
severity: 'warning'
exclude-paths: 'LICENSE'
18 changes: 18 additions & 0 deletions .github/workflows/lint-systemd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# GitHub Actions workflow for linting the systemd unit files
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions
name: Lint systemd units
on:
pull_request:
push:
branches:
- main
jobs:
lint:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install systemdlint
run: pip install systemdlint==1.*
- name: Lint systemd units
run: systemdlint ./config/systemd/*
65 changes: 65 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Contribution guide

We welcome contributions to SORT! This document outlines the guidelines for contributing to the project.

# Getting Started

## Organising work

Please use the [Kanban board](https://github.com/orgs/RSE-Sheffield/projects/19) to assign tasks.

# Making changes

## Proposing changes

1. [Raise an issue](https://github.com/RSE-Sheffield/SORT/issues/new?template=Blank+issue) clearly describing the problem or user requirements;
2. [Create a branch](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/creating-a-branch-for-an-issue) that is associated with that issue. It can be helpful to prefix the branch name to match the type of changes e.g. `feat/123-my-feature` for features or `docs/my-guide` for documentation, etc. See [Semantic branch names](https://damiandabrowski.medium.com/semantic-branch-names-and-commit-messages-3ac38a6fcbb6).
3. In that branch, make changes that aim to resolve that issue;
4. Create a [draft pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests) (PR) while the changes are being designed;
5. When ready, mark the PR "Ready for review" and request for reviewers to look at the proposed changes;

## Environments

There are two main environments:

- Development (the `dev` branch and the `sort-web-dev` virtual machine)
- Production (the `main` branch and the `sort-web-app` virtual machine)

## Change process

Any proposed changes should be proposed in pull requests that would be merged into the `dev` branch.

```mermaid
graph LR
subgraph Development environment
A(Feature branch)
B{Approve?}
C[Merge feature branch into dev]
D{Approve?}
end
subgraph Production environment
E[Main branch]
end
A --> B
B -- Yes --> C
C --> D
D -- Yes --> E
```

so the commit history would look something like this:

```mermaid
gitGraph
commit id: "Initial commit"
branch dev
branch feat/my-feature
commit id: "Work on feature branch"
checkout dev
merge feat/my-feature id: "Merge into dev"
checkout main
merge dev id: "Merge dev into main"
```

# Code of Conduct

We expect all contributors to follow the SORT [Code of Conduct](CODE_OF_CONDUCT.md).
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Follow these steps to set up and run the app locally:

Prerequisites

- Python 3.10
- Python 3.12
- pip
---

Expand Down Expand Up @@ -61,8 +61,9 @@ python manage.py createsuperuser

6. Create a `.env` file in the project root directory and add the following environment variables:

```
```bash
DJANGO_SECRET_KEY=your_secret_key
DJANGO_DEBUG=True
```

---
Expand All @@ -81,3 +82,7 @@ The app will be available at http://127.0.0.1:8000.
```bash
python manage.py loaddata data\questionnaires.json data\questionnaires.json
```

# Deployment

Please read [`docs/deployment.md`](docs/deployment.md).
69 changes: 46 additions & 23 deletions SORT/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,34 @@

import os
from pathlib import Path
from typing import Any

from dotenv import load_dotenv

load_dotenv() # Load environment variables from .env file

def cast_to_boolean(obj: Any) -> bool:
"""
Check if the string value is 1, yes, or true.
Empty values are interpreted as False.
"""
# Cast to lower case string
obj = str(obj).casefold()
# False / off
if obj in {"", "off", "none"}:
return False
# True / on
return obj[0] in {"1", "y", "t", "o"}


# Load environment variables from .env file
load_dotenv(os.getenv("DJANGO_ENV_PATH"))

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Path when redirecting to login
LOGIN_URL = "/login/"

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
Expand All @@ -28,10 +48,9 @@
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []
DEBUG = cast_to_boolean(os.getenv("DJANGO_DEBUG", "False"))

ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "sort-web-app.shef.ac.uk").split()

# Application definition

Expand All @@ -48,11 +67,12 @@
# apps created by FA:
"home",
"survey",
"invites",
]

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
# Implement security in the web server, not in Django.
# https://docs.djangoproject.com/en/5.1/ref/middleware/#module-django.middleware.security
# "django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
Expand Down Expand Up @@ -80,21 +100,19 @@
},
]

WSGI_APPLICATION = "SORT.wsgi.application"

WSGI_APPLICATION = os.getenv("DJANGO_WSGI_APPLICATION", "SORT.wsgi.application")

# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases

DATABASES = {
# Set the database settings using environment variables, or default to a local SQLite database file.
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
# "NAME": os.getenv("DB_NAME"),
# "USER": os.getenv("DB_USER"),
# "PASSWORD": os.getenv("DB_PASSWORD"),
# "HOST": os.getenv("DB_HOST"),
# "PORT": os.getenv("DB_PORT"),
"ENGINE": os.getenv("DJANGO_DATABASE_ENGINE", "django.db.backends.sqlite3"),
"NAME": os.getenv("DJANGO_DATABASE_NAME", BASE_DIR / "db.sqlite3"),
"USER": os.getenv("DJANGO_DATABASE_USER"),
"PASSWORD": os.getenv("DJANGO_DATABASE_PASSWORD"),
"HOST": os.getenv("DJANGO_DATABASE_HOST"),
"PORT": os.getenv("DJANGO_DATABASE_PORT"),
}
}

Expand All @@ -116,27 +134,25 @@
},
]


# Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/

LANGUAGE_CODE = "en-us"
LANGUAGE_CODE = "en-gb"

TIME_ZONE = "UTC"
TIME_ZONE = "Europe/London"

USE_I18N = True
# Disable translation features
USE_I18N = False

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/

STATIC_URL = "static/"

STATICFILES_DIRS = [BASE_DIR / "static"]


# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field

Expand All @@ -145,7 +161,6 @@
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"


# FA: End session when the browser is closed
SESSION_EXPIRE_AT_BROWSER_CLOSE = True

Expand All @@ -171,3 +186,11 @@
# FA: for production:

# EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"

STATIC_ROOT = os.getenv("DJANGO_STATIC_ROOT")

# Security settings
SESSION_COOKIE_SECURE = cast_to_boolean(
os.getenv("DJANGO_SESSION_COOKIE_SECURE", not DEBUG)
)
CSRF_COOKIE_SECURE = cast_to_boolean(os.getenv("DJANGO_CSRF_COOKIE_SECURE", not DEBUG))
2 changes: 2 additions & 0 deletions SORT/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "SORT.settings")

# Create WSGI application object
application = get_wsgi_application()
"https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/#the-application-object"
3 changes: 3 additions & 0 deletions config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Server configuration

This directory contains configuration files for the production web server.
61 changes: 61 additions & 0 deletions config/nginx/gunicorn.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# nginx configuration file

# HTTP and SSL certificates
# https://nginx.org/en/docs/http/configuring_https_servers.html
# https://ssl-config.mozilla.org/#server=nginx&version=1.27.3&config=modern&openssl=3.4.0&ocsp=false&guideline=5.7

# Gunicorn proxy configuration
# https://docs.gunicorn.org/en/stable/deploy.html#nginx-configuration

upstream app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
# for UNIX domain socket setups
server unix:/run/gunicorn.sock fail_timeout=0;
}

server {
# https://nginx.org/en/docs/http/ngx_http_core_module.html
listen 443 ssl;
listen [::]:443 ssl;
# Unavailable on nginx versions before 1.25.1
# https://nginx.org/en/docs/http/ngx_http_v2_module.html
#http2 on;
# SSL options
ssl_certificate /etc/ssl/certs/sort.crt;
ssl_certificate_key /etc/ssl/private/sort.key;
ssl_protocols TLSv1.3;
ssl_ecdh_curve X25519:prime256v1:secp384r1;
ssl_prefer_server_ciphers off;
client_max_body_size 1m;
server_name sort-web-app.shef.ac.uk;
keepalive_timeout 5;

# /server-status endpoint
# This is used by IT Services to monitor servers using collectd
# https://nginx.org/en/docs/http/ngx_http_stub_status_module.html
# https://www.collectd.org/documentation/manpages/collectd.conf.html
# It's based on Apache mod_status https://httpd.apache.org/docs/2.4/mod/mod_status.html
location = /server-status {
stub_status;
}

# Serve static files without invoking Python WSGI
location /static/ {
# https://nginx.org/en/docs/http/ngx_http_core_module.html#root
root /var/www/sort;
}

# Proxy forward to the WSGI Python app
location / {
# Set HTTP headers for the proxied service
# https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://app_server;
}
}
Loading

0 comments on commit 9713e2c

Please sign in to comment.