Skip to content

Commit

Permalink
Make the template project compatible with startproject (#20)
Browse files Browse the repository at this point in the history
Adds the necessary place holders for ensuring the `template` project can
be used with the Django `startproject` command.

- Placeholders added to template file (mostly `{{ project_name }}`)
- Really basic usage example in README
- Github action workflow to ensure that the repository is capable of
creating a valid project


The Github action workflow `startproject` performs the following to
ensure that we can create a valid project from this repositoiry:

1. Checkout code
2. Install Django. Poetry and Invoke
3. Run the `startproject` Django command specifying the `template`
directory as the source
4. Poetry install the project created in the previous step
5. Run `invoke check` on the project - which runs all the static
analysis, linting and tests

Closes #19
  • Loading branch information
a-musing-moose authored Dec 6, 2023
2 parents f1ae04c + f00bdcc commit b5603f5
Show file tree
Hide file tree
Showing 17 changed files with 142 additions and 23 deletions.
90 changes: 90 additions & 0 deletions .github/workflows/startproject.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Start Project

on:
pull_request:
push:
branches: [main]

# Restrict jobs in this workflow to have no permissions by default; permissions
# should be granted per job as needed using a dedicated `permissions` block
permissions: {}

jobs:
creates-valid-project:
permissions:
contents: read
runs-on: ubuntu-latest

services:
postgres:
image: postgres:14
env:
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev_password
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Allows us to use the same env config used locally by mapping to port to
# the test runner container.
- 5432:5432

steps:
- uses: actions/checkout@v4
with:
persist-credentials: false

- uses: actions/setup-python@v4
with:
python-version: "3.12"

- name: Install Dependencies
run: |
sudo apt-get update
# Project System Dependencies
sudo apt-get install -y \
build-essential \
libffi-dev \
libpq-dev
# Playwright System Dependencies
sudo apt-get install -y \
libnss3\
libnspr4\
libatk1.0-0\
libatk-bridge2.0-0\
libcups2\
libdrm2\
libxkbcommon0\
libatspi2.0-0\
libxcomposite1\
libxdamage1\
libxfixes3\
libxrandr2\
libgbm1\
libasound2
# Base Python tooling
pip install poetry django
- name: Create test project
run: |
django-admin startproject \
--template template/ \
--extension py,Dockerfile,env,toml,yml \
test_project
- name: Install test project
run: |
cd test_project
poetry install
poetry run playwright install
- name: Check test project is valid
run: |
cd test_project
cp example.env .env
poetry run invoke check
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,36 @@ This project is intended as:
- a place where we can document decisions that have been made about practices
- e.g.: why X was picked, why Y was avoided (+ pros & cons)

## Usage

To create a new project from this template, you must have the most recent stable version
of Django installed in order to run the `startproject` command. The simplest way to do
this is with [pipx][pipx]:

```shell
pipx install django
```

This will ensure that the `django-admin` command is available in your shell. From there
you can create a new project with the following command:

```shell
django-admin startproject --template path/to/django-template/template/ --extension py,env,toml,yml <project_name>
```

!!! warn
The name of your project _must_ be a valid Python package name - that means
underscores (`_`) not hyphens (`-`) for name separators please.

Running the Django admin command will create a new project in the folder specified in
with `<project_name>`.

## Contributing

If you have ideas for improvements, open a PR with your idea or propose it in the guild channel
If you have ideas for improvements, open a PR with your idea or propose it in the guild
channel

Feature branches are encouraged, and merging should on consensus from guild

<!-- Links -->
[pipx]: https://pypa.github.io/pipx/
8 changes: 4 additions & 4 deletions template/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Packaging Stage
# ===============

FROM python:3.11.2-slim-bullseye as packager
FROM python:3.12.0-slim-bullseye as packager
ENV PYTHONUNBUFFERED=1
RUN pip install -U pip && pip install poetry
COPY README.md pyproject.toml poetry.lock /source/
Expand All @@ -13,7 +13,7 @@ RUN rm -rf dist && poetry build
# Building Stage
# ==============

FROM python:3.11.2-slim-bullseye as builder
FROM python:3.12.0-bullseye as builder
ENV PYTHONUNBUFFERED=1

RUN apt-get update && apt-get install -y \
Expand All @@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

COPY --from=packager /source/dist/django_template*.whl /
COPY --from=packager /source/dist/*.whl /
RUN python -m venv /venv/

# _activate_ the virtual environment
Expand All @@ -34,7 +34,7 @@ RUN pip install -U pip && pip install *.whl
# Final Runtime
# =============

FROM python:3.11.2-slim-bullseye as runtime
FROM python:3.12.0-slim-bullseye as runtime
ENV PYTHONUNBUFFERED=1

ARG GIT_COMMIT_HASH
Expand Down
2 changes: 1 addition & 1 deletion template/example.env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SECRET_KEY="00c#jblr9b+s-^ulqj&8r8u1(-av#^!+e6czoz&(k4b3q1pacx"
SECRET_KEY={{ secret_key }}
ALLOWED_HOSTS=*
DEBUG=True

Expand Down
4 changes: 2 additions & 2 deletions template/mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
site_name: django_template
site_name: "{{ project_name }}"
watch:
- src/
- docs/
Expand Down Expand Up @@ -37,6 +37,6 @@ plugins:
setup_commands:
- import os, sys
- sys.path.append("src")
- os.environ["DJANGO_SETTINGS_MODULE"] = "{package_name}.main.settings"
- os.environ["DJANGO_SETTINGS_MODULE"] = "{{ project_name }}.main.settings"
- tags:
tags_file: tags.md
10 changes: 5 additions & 5 deletions template/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[tool.poetry]
authors = ["Jonathan Moss <[email protected]>"]
description = ""
name = "django-template"
packages = [{include = "django_template", from = "src"}]
name = "{{ project_name }}"
packages = [{include = "{{ project_name }}", from = "src"}]
readme = "README.md"
version = "0.1.0"

[tool.poetry.scripts]
manage = "django_template.manage:main"
manage = "{{ project_name }}.manage:main"

[tool.poetry.dependencies]
django = "^4.2.7"
Expand Down Expand Up @@ -67,13 +67,13 @@ ignore_missing_imports = true
module = "environ"

[tool.django-stubs]
django_settings_module = "django_template.main.settings"
django_settings_module = "{{ project_name }}.main.settings"

[tool.isort]
profile = "black"

[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "django_template.main.settings"
DJANGO_SETTINGS_MODULE = "{{ project_name }}.main.settings"
addopts = "--rootdir src --spec"
norecursedirs = ".git .venv docs data"
spec_header_format = "{test_case} [{module_path}]:"
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
ASGI config for django_template project.
ASGI config for {{ project_name }} project.
It exposes the ASGI callable as a module-level variable named ``application``.
Expand All @@ -11,6 +11,6 @@

from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_template.main.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.main.settings")

application = get_asgi_application()
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "django_template.main.urls"
ROOT_URLCONF = "{{ project_name }}.main.urls"

TEMPLATES = [
{
Expand All @@ -63,7 +63,7 @@
},
]

WSGI_APPLICATION = "django_template.main.wsgi.application"
WSGI_APPLICATION = "{{ project_name }}.main.wsgi.application"


# Database
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
WSGI config for django_template project.
WSGI config for {{ project_name }} project.
It exposes the WSGI callable as a module-level variable named ``application``.
Expand All @@ -11,6 +11,6 @@

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_template.main.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.main.settings")

application = get_wsgi_application()
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

def main() -> None:
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_template.main.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.main.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
Expand Down
2 changes: 1 addition & 1 deletion template/src/tests/system/main/test_views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json

from django_template.main import views
from {{ project_name }}.main import views


def test_releases_view_includes_revision_details(settings, rf):
Expand Down
5 changes: 3 additions & 2 deletions template/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# CONSTANTS #
#############

PACKAGE = "django_template"
PACKAGE = "{{ project_name }}"


@invoke.task
Expand Down Expand Up @@ -39,7 +39,8 @@ def typing(ctx):
Check type annotations
"""
_title("Type checking")
# PYTHONPATH must include the `src` folder for django-stubs to find the settings module
# PYTHONPATH must include the `src` folder for django-stubs to find the settings
# module
src_path = str((pathlib.Path() / "src").absolute())
with ctx.prefix(f"export PYTHONPATH=${{PYTHONPATH}}:{src_path}"):
try:
Expand Down

0 comments on commit b5603f5

Please sign in to comment.