Skip to content

Commit

Permalink
feat: simplify config options
Browse files Browse the repository at this point in the history
  • Loading branch information
rochecompaan authored Jul 27, 2024
1 parent 7e96a98 commit 4b2f31e
Show file tree
Hide file tree
Showing 81 changed files with 139 additions and 22,880 deletions.
19 changes: 8 additions & 11 deletions cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,35 @@
"description": "Behold My Awesome Project!",
"author_name": "Joe Sixie",
"domain_name": "sixfeetup.com",
"repo_name": "{{ cookiecutter.project_name }}",
"repo_url": "[email protected]:sixfeetup/{{ cookiecutter.project_slug }}.git",
"email": "{{ cookiecutter.author_name.lower()|replace(' ', '-') }}@example.com",
"email": "{{ cookiecutter.author_name.lower()|replace(' ', '-') }}@{{ cookiecutter.domain_name }}",
"version": "0.1.0",
"timezone": "US/Eastern",
"aws_region": "us-east-1",
"aws_account_id": "000000000000",
"create_nextjs_frontend": "y",
"create_react_frontend": "n",
"mail_service": [
"Mailgun",
"Amazon SES",
"Other SMTP"
],
"use_drf": "n",
"use_graphql": "y",
"custom_bootstrap_compilation": "n",
"use_compressor": "n",
"use_celery": "n",
"use_sentry": "n",
"debug": "n",
"source_control_provider": [
"bitbucket",
"github",
"github.com",
"bitbucket.org",
"none"
],
"source_control_organization_slug": "sixfeetup",
"__prompts__": {
"source_control_organization_slug": "What is the organization slug for the source control provider?",
"source_control_provider": {
"__prompt__": "Which source control provider do you want to use?",
"bitbucket": "Bitbucket",
"github": "Github",
"none": "No source control provider"
}
}
},
"repo_name": "{{ cookiecutter.project_slug }}",
"repo_url": "git@{{ cookiecutter.source_control_provider }}:{{ cookiecutter.source_control_organization_slug }}/{{ cookiecutter.project_slug }}.git"
}
77 changes: 22 additions & 55 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import os
import random
import shlex
import shutil
import string
import zipfile
import subprocess
import shlex
import zipfile

try:
# Inspired by
Expand All @@ -25,14 +25,13 @@
create_nextjs_frontend = "{{ cookiecutter.create_nextjs_frontend }}" == "y"
if not create_nextjs_frontend:
shutil.rmtree("frontend")
file_names = [
os.path.join("k8s", "base", "frontend.yaml"),
os.path.join("k8s", "prod", "patch-react.yaml"),
]
for file_name in file_names:
os.remove(file_name)

create_react_frontend = "{{ cookiecutter.create_react_frontend }}" == "y"
if not create_react_frontend:
shutil.rmtree("frontend_react")

# by default we have frontend folder for nextjs. If we want react then we rename react folder to be the frontend folder
if create_react_frontend:
shutil.move("frontend_react", "frontend")

def remove_celery_files():
file_names = [
Expand Down Expand Up @@ -120,7 +119,7 @@ def set_flag(file_path, flag, value=None, formatted=None, *args, **kwargs):
def set_django_secret_key(file_path):
django_secret_key = set_flag(
file_path,
"!!!SET DJANGO_SECRET_KEY!!!",
"__DJANGO_SECRET_KEY__",
length=64,
using_digits=True,
using_ascii_letters=True,
Expand Down Expand Up @@ -156,7 +155,7 @@ def set_postgres_user(file_path, value):
def set_postgres_password(file_path, value=None):
postgres_password = set_flag(
file_path,
"!!!SET POSTGRES_PASSWORD!!!",
"__POSTGRES_PASSWORD__",
value=value,
length=64,
using_digits=True,
Expand Down Expand Up @@ -190,44 +189,16 @@ def append_to_gitignore_file(s):
gitignore_file.write(os.linesep)


def set_flags_in_envs(postgres_user, celery_flower_user, debug=False):
local_env_path = os.path.join("backend", "local", "environment")

set_postgres_user(local_env_path, value=postgres_user)
set_postgres_password(local_env_path, value=DEBUG_VALUE if debug else None)
def set_flags_in_secrets(postgres_user, celery_flower_user, debug=False):
local_secrets_path = os.path.join("k8s", "local", "secrets.yaml")

set_celery_flower_user(local_env_path, value=celery_flower_user)
set_celery_flower_password(local_env_path, value=DEBUG_VALUE if debug else None)
set_django_secret_key(os.path.join("k8s", "local", "secrets.yaml"))

set_postgres_user(local_secrets_path, value=postgres_user)
set_postgres_password(local_secrets_path, value=DEBUG_VALUE if debug else None)

def set_flags_in_settings_files():
set_django_secret_key(os.path.join("backend", "config", "settings", "local.py"))
set_django_secret_key(os.path.join("backend", "config", "settings", "test.py"))


def remove_drf_starter_files():
os.remove(os.path.join("backend", "config", "api_router.py"))
shutil.rmtree(
os.path.join("backend", "{{ cookiecutter.project_slug }}", "users", "api")
)
os.remove(
os.path.join(
"backend",
"{{ cookiecutter.project_slug }}",
"users",
"tests",
"test_drf_urls.py",
)
)
os.remove(
os.path.join(
"backend",
"{{ cookiecutter.project_slug }}",
"users",
"tests",
"test_drf_views.py",
)
)
set_celery_flower_user(local_secrets_path, value=celery_flower_user)
set_celery_flower_password(local_secrets_path, value=DEBUG_VALUE if debug else None)


def remove_sentry_files():
Expand Down Expand Up @@ -274,29 +245,25 @@ def remove_graphql_files():
def main():
debug = "{{ cookiecutter.debug }}".lower() == "y"

set_flags_in_envs(
set_flags_in_secrets(
DEBUG_VALUE if debug else generate_random_user(),
DEBUG_VALUE if debug else generate_random_user(),
debug=debug,
)
set_flags_in_settings_files()

if "{{ cookiecutter.use_celery }}".lower() == "n":
remove_celery_files()

if "{{ cookiecutter.source_control_provider }}" != "bitbucket":
if "{{ cookiecutter.source_control_provider }}" != "bitbucket.org":
remove_bitbucket_files()

if "{{ cookiecutter.source_control_provider }}" != "github":
if "{{ cookiecutter.source_control_provider }}" != "github.com":
remove_github_files()

if "{{ cookiecutter.use_drf }}".lower() == "n":
remove_drf_starter_files()

if "{{ cookiecutter.use_sentry }}".lower() == "n":
remove_sentry_files()
if "{{ cookiecutter.use_graphql }}".lower() == "n":

if "{{ cookiecutter.create_nextjs_frontend }}".lower() == "n":
remove_graphql_files()

subprocess.run(shlex.split("black ./backend"))
Expand Down
5 changes: 5 additions & 0 deletions scaf
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ docker run --rm $DOCKER_RUN_OPTIONS -v "$(pwd):/home/scaf/out" \
# Check if cookiecutter was successful
if [ $? -eq 0 ]; then
kind create cluster --name $PROJECT_SLUG
cd $PROJECT_SLUG
git init .
git add .
git commit -m "Initial commit"
make compile
else
echo "Failed to create project."
exit 1
Expand Down
16 changes: 8 additions & 8 deletions {{cookiecutter.project_slug}}/.envrc
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# read the secrets from 1Password
# strip whitespace from the value
export AWS_S3_ACCESS_KEY_ID=$(op read "op://{{ cookiecutter.project_name }}/AWS_S3_ACCESS_KEY_ID/token")
export AWS_S3_SECRET_ACCESS_KEY=$(op read "op://{{ cookiecutter.project_name }}/AWS_S3_SECRET_ACCESS_KEY/token")
export AWS_SES_ACCESS_KEY_ID=$(op read "op://{{ cookiecutter.project_name }}/AWS_SES_ACCESS_KEY_ID/token")
export AWS_SES_SECRET_ACCESS_KEY=$(op read "op://{{ cookiecutter.project_name }}/AWS_SES_SECRET_ACCESS_KEY/token")
export POSTGRES_PASSWORD=$(op read "op://{{ cookiecutter.project_name }}/POSTGRES_DB/password")
export POSTGRES_USER=$(op read "op://{{ cookiecutter.project_name }}/POSTGRES_DB/username")
export AWS_S3_ACCESS_KEY_ID="op://{{ cookiecutter.project_name }}/AWS_S3_ACCESS_KEY_ID/token"
export AWS_S3_SECRET_ACCESS_KEY="op://{{ cookiecutter.project_name }}/AWS_S3_SECRET_ACCESS_KEY/token"
export AWS_SES_ACCESS_KEY_ID="op://{{ cookiecutter.project_name }}/AWS_SES_ACCESS_KEY_ID/token"
export AWS_SES_SECRET_ACCESS_KEY="op://{{ cookiecutter.project_name }}/AWS_SES_SECRET_ACCESS_KEY/token"
export POSTGRES_PASSWORD="op://{{ cookiecutter.project_name }}/POSTGRES_DB/password"
export POSTGRES_USER="op://{{ cookiecutter.project_name }}/POSTGRES_DB/username"
# use sandbox host for secrets generation
export POSTGRES_HOST=postgres
export DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}/{{ cookiecutter.project_slug }}
export DJANGO_SECRET_KEY=$(op read "op://{{ cookiecutter.project_name }}/DJANGO_SECRET_KEY/token")
export DJANGO_SECRET_KEY="op://{{ cookiecutter.project_name }}/DJANGO_SECRET_KEY/token"
{%- if cookiecutter.mail_service == 'Mailgun' %}
# Mailgun api key
export MAILGUN_API_KEY=$(op read "op://{{ cookiecutter.project_name }}/MAILGUN_API_KEY/token"){%- endif %}
export MAILGUN_API_KEY="op://{{ cookiecutter.project_name }}/MAILGUN_API_KEY/token"{%- endif %}
8 changes: 4 additions & 4 deletions {{cookiecutter.project_slug}}/.github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ jobs:
python-version: "3.10"
- name: Check lint and formatting
run: make check-lint-and-formatting
{% if cookiecutter.create_react_frontend == 'y' %}
{% if cookiecutter.create_nextjs_frontend == 'y' %}
check-lint-and-test-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: '16'
node-version: '20'
- name: Frontend Lint & Typecheck & Test
run: make check-lint-and-test-frontend
test-frontend:
Expand All @@ -28,7 +28,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: '16'
node-version: '20'
- name: Frontend Unit Tests
run: CI=true make frontend-test
{% endif %}
Expand All @@ -37,7 +37,7 @@ jobs:

services:
postgres:
image: postgres
image: postgres:16
env:
POSTGRES_DB: {{ cookiecutter.project_slug }}
POSTGRES_USER: {{ cookiecutter.project_slug }}
Expand Down
13 changes: 8 additions & 5 deletions {{cookiecutter.project_slug}}/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
KUBECTL_EXEC_BACKEND = kubectl exec -it $$(kubectl get pods -l app=backend -o jsonpath="{.items[0].metadata.name}") -- bash
{% if cookiecutter.create_nextjs_frontend == "y" %}
KUBECTL_EXEC_FRONTEND = kubectl exec -it $$(kubectl get pods -l app=frontend -o jsonpath="{.items[0].metadata.name}") -- bash
{% endif %}

## Release/Deployment Targets

Expand All @@ -12,7 +14,7 @@ check-lint-and-formatting: ## Execute check of lint and formatting using existi
pre-commit install; \
pre-commit run -a

{% if cookiecutter.create_react_frontend == 'y' %}
{% if cookiecutter.create_nextjs_frontend == 'y' %}
check-lint-and-test-frontend: ## Frontend Lint & Typecheck & Test
cd frontend/; \
npm install --legacy-peer-deps; \
Expand All @@ -26,15 +28,14 @@ ifeq ($(CI),true)
cd backend; \
pip install \
-r requirements/production.txt \
-r requirements/base.txt \
-r requirements/tests.txt; \
cd {{ cookiecutter.project_slug }}; \
pytest --cov=./ --cov-report html --ds=config.settings.test
else
$(KUBECTL_EXEC_BACKEND) -c "cd {{ cookiecutter.project_slug }} && pytest --cov=./ --cov-report html --ds=config.settings.test"
endif

{% if cookiecutter.create_react_frontend == 'y' %}
{% if cookiecutter.create_nextjs_frontend == 'y' %}
frontend-test: ## Execute frontend tests
ifeq ($(CI),true)
cd frontend/; \
Expand Down Expand Up @@ -62,9 +63,9 @@ pipdeptree: ## Show the dependencies of installed packages as a tree structure
$(KUBECTL_EXEC_BACKEND) -c "pipdeptree"

compile: backend/requirements/base.in backend/requirements/tests.in ## compile latest requirements to be built into the docker image
@docker run --rm -v $(shell pwd)/backend/requirements:/local python:3.12-slim-bullseye /bin/bash -c \
@docker run --rm -v $(shell pwd)/backend/requirements:/local python:3.12-slim /bin/bash -c \
"apt-get update; apt-get install -y libpq-dev; \
pip install pip-tools; \
PIP_ROOT_USER_ACTION=ignore pip install --disable-pip-version-check pip-tools; \
touch /local/base.txt; touch /local/production.txt; touch /local/tests.txt; touch /local/local.txt; \
python -m piptools compile --upgrade --allow-unsafe --generate-hashes --output-file /local/base.txt /local/base.in; \
python -m piptools compile --upgrade --allow-unsafe --generate-hashes --output-file /local/production.txt /local/production.in; \
Expand All @@ -74,8 +75,10 @@ compile: backend/requirements/base.in backend/requirements/tests.in ## compile l
shell-backend: ## Shell into the running Django container
$(KUBECTL_EXEC_BACKEND)

{% if cookiecutter.create_nextjs_frontend == "y" %}
shell-frontend:
$(KUBECTL_EXEC_FRONTEND)
{% endif %}

.PHONY: secure
secure: ## Analyze dependencies for security issues
Expand Down
4 changes: 2 additions & 2 deletions {{cookiecutter.project_slug}}/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ To create a superuser use the following commands:

$ make shell-backend
$ ./manage.py createsuperuser
{% if cookiecutter.create_react_frontend == 'y' %}
This project has a React frontend configured. You can access it at [http://localhost:3000/](http://localhost:3000/).
{% if cookiecutter.create_nextjs_frontend == 'y' %}
This project has a NextJS frontend configured. You can access it at [http://localhost:3000/](http://localhost:3000/).
{% endif %}
## Infrastructure provisioning

Expand Down
6 changes: 6 additions & 0 deletions {{cookiecutter.project_slug}}/Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ docker_build(
],
)

{% if cookiecutter.create_nextjs_frontend == "y" %}
docker_build(
"frontend",
context="frontend",
live_update=[
sync("./frontend", "/app"),
],
)
{% endif %}

k8s_yaml(
kustomize("./k8s/local/")
Expand All @@ -39,15 +41,19 @@ syncback(
rsync_path='/app/bin/rsync.tilt',
)

{% if cookiecutter.create_nextjs_frontend == "y" %}
syncback(
"frontend-sync",
"deploy/frontend",
"/app/",
target_dir="./frontend",
rsync_path='/app/rsync.tilt',
)
{% endif %}

{% if cookiecutter.create_nextjs_frontend == "y" %}
k8s_resource(workload='frontend', port_forwards=3000)
{% endif %}
k8s_resource(workload='backend', port_forwards=8000)
k8s_resource(workload='mailhog', port_forwards=8025)
k8s_resource(workload='postgres', port_forwards=5432)
Loading

0 comments on commit 4b2f31e

Please sign in to comment.