diff --git a/.editorconfig b/.editorconfig index 261407067..6a9a5c45d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,7 +12,7 @@ trim_trailing_whitespace = true indent_style = space indent_size = 4 -[*.{html,css,scss,json,yml}] +[*.{html,css,scss,json,yml,xml}] indent_style = space indent_size = 2 diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..84b4b4411 --- /dev/null +++ b/.flake8 @@ -0,0 +1,3 @@ +[flake8] +exclude = docs +max-line-length = 119 diff --git a/.github/CONTRIBUTORS-template.md b/.github/CONTRIBUTORS-template.md new file mode 100644 index 000000000..bc0928478 --- /dev/null +++ b/.github/CONTRIBUTORS-template.md @@ -0,0 +1,56 @@ +# Contributors + +## Core Developers + +These contributors have commit flags for the repository, and are able to +accept and merge pull requests. + + + + + + + + {%- for contributor in core_contributors %} + + + + + + {%- endfor %} +
NameGithubTwitter
{{ contributor.name }} + {{ contributor.github_login }} + {{ contributor.twitter_username }}
+ +_Audrey is also the creator of Cookiecutter. Audrey and Daniel are on +the Cookiecutter core team._ + +## Other Contributors + +Listed in alphabetical order. + + + + + + + + {%- for contributor in other_contributors %} + + + + + + {%- endfor %} +
NameGithubTwitter
{{ contributor.name }} + {{ contributor.github_login }} + {{ contributor.twitter_username }}
+ +### Special Thanks + +The following haven't provided code directly, but have provided +guidance and advice. + +- Jannis Leidel +- Nate Aune +- Barry Morrison diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..23ca7a37f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,5 @@ +# These are supported funding model platforms + +github: [pydanny, browniebroke] +patreon: feldroy +open_collective: cookiecutter-django diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index b232b6e34..000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1 +0,0 @@ -## [Make sure to follow one of the issue templates we've got](https://github.com/pydanny/cookiecutter-django/issues/new/choose), otherwise the issue might be closed immeditely diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 2a48c0c32..0e5ec12c4 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -1,21 +1,64 @@ --- name: Bug Report about: Report a bug +labels: bug --- ## What happened? - - - ## What should've happened instead? +## Additional details + +- Host system configuration: -## Steps to reproduce + - Version of cookiecutter CLI (get it with `cookiecutter --version`): + - OS name and version: -[//]: # (Any or all of the following:) -[//]: # (* Host system configuration: OS, Docker & friends' versions etc.) -[//]: # (* Replay file https://cookiecutter.readthedocs.io/en/latest/advanced/replay.html) -[//]: # (* Logs) + On Linux, run + + ```bash + lsb_release -a 2> /dev/null || cat /etc/redhat-release 2> /dev/null || cat /etc/*-release 2> /dev/null || cat /etc/issue 2> /dev/null + ``` + + On MacOs, run + + ```bash + sw_vers + ``` + + On Windows, via CMD, run + + ``` + systeminfo | findstr /B /C:"OS Name" /C:"OS Version" + ``` + + ```bash + # Insert here the OS name and version + + ``` + + - Python version, run `python3 -V`: + - Docker version (if using Docker), run `docker --version`: + - docker-compose version (if using Docker), run `docker-compose --version`: + - ... + +- Options selected and/or [replay file](https://cookiecutter.readthedocs.io/en/latest/advanced/replay.html): + On Linux and macOS: `cat ${HOME}/.cookiecutter_replay/cookiecutter-django.json` + (Please, take care to remove sensitive information) + +```json + +``` + + +Logs: +
+
+$ cookiecutter https://github.com/cookiecutter/cookiecutter-django
+project_name [Project Name]: ...
+
+
+
diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md index b0d560d81..ab719770c 100644 --- a/.github/ISSUE_TEMPLATE/feature.md +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -1,24 +1,13 @@ --- name: New Feature Proposal about: Propose a new feature +labels: enhancement --- ## Description -[//]: # (What's it you're proposing? How should it be implemented?) - - - +What are you proposing? How should it be implemented? ## Rationale -[//]: # (Why should this feature be implemented?) - - - - -## Use case(s) / visualization(s) - -[//]: # ("Better to see something once than to hear about it a thousand times.") - - +Why should this feature be implemented? diff --git a/.github/ISSUE_TEMPLATE/improvement.md b/.github/ISSUE_TEMPLATE/improvement.md deleted file mode 100644 index 572652373..000000000 --- a/.github/ISSUE_TEMPLATE/improvement.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Improvement Suggestion -about: Let us know how we could improve ---- - -## Description - -[//]: # (What's it you're proposing? How should it be implemented?) - - - - -## Rationale - -[//]: # (Why should this feature be implemented?) - - - - -## Use case(s) / visualization(s) - -[//]: # ("Better to see something once than to hear about it a thousand times.") - - diff --git a/.github/ISSUE_TEMPLATE/paid-support.md b/.github/ISSUE_TEMPLATE/paid-support.md index d565e564f..f4e7578a8 100644 --- a/.github/ISSUE_TEMPLATE/paid-support.md +++ b/.github/ISSUE_TEMPLATE/paid-support.md @@ -3,8 +3,10 @@ name: Paid Support Request about: Ask Core Team members to help you out --- -Provided your question goes beyound [regular support](https://github.com/pydanny/cookiecutter-django/issues/new?template=question.md), and/or the task at hand is of timely/high priority nature use the below information to reach out for contributors directly. +Provided your question goes beyond [regular support](https://github.com/cookiecutter/cookiecutter-django/issues/new?template=question.md), and/or the task at hand is of timely/high priority nature use the below information to reach out for contributors directly. -* Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB. +- Bruno Alla, Core Developer ([GitHub](https://github.com/sponsors/browniebroke)). -* Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience. +- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB. + +- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience. diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 0c0f3d891..61f839cf6 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,6 +1,11 @@ --- name: Question -about: Please, ask your question on StackOverflow or Gitter +about: Please ask your question on StackOverflow, Discord or GitHub Discussions. +labels: question --- -First, make sure to examine [the docs](https://cookiecutter-django.readthedocs.io/en/latest/). If that doesn't help post a question on [StackOverflow](https://stackoverflow.com/questions/tagged/cookiecutter-django) tagged with `cookiecutter-django`. Finally, feel free to join [Gitter](https://gitter.im/pydanny/cookiecutter-django) and ask around. +First, make sure to examine [the docs](https://cookiecutter-django.readthedocs.io/en/latest/). If that doesn't help, we recommend one of these 3 main channels: + +- If your issue is related to Django + something else but was generated with cookiecutter-django, the best is to post a question on [StackOverflow](https://stackoverflow.com/questions/tagged/cookiecutter-django) tagged with `cookiecutter-django`, you would get more visibility from other communities as well. +- Join us on [Discord](https://discord.gg/uFXweDQc5a) and ask around. +- Start [a discussion](https://github.com/cookiecutter/cookiecutter-django/discussions) on our project's GitHub. diff --git a/.github/ISSUE_TEMPLATE/regression.md b/.github/ISSUE_TEMPLATE/regression.md deleted file mode 100644 index 80384004b..000000000 --- a/.github/ISSUE_TEMPLATE/regression.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -name: Regression Report -about: Let us know if something that'd been working has broke ---- - -## What happened before? - - - - -## What happens now? - - - - -## Last stable commit / Since when? - - - - -## Steps to reproduce - -[//]: # (Any or all of the following:) -[//]: # (* Host system configuration: OS, Docker & friends' versions etc.) -[//]: # (* Project generation options) -[//]: # (* Logs) - - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8dbff6c25..2b197873f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,27 +1,17 @@ -[//]: # (Thank you for helping us out: your efforts mean great deal to the project and the community as a whole!) - -[//]: # (Before you proceed:) - -[//]: # (1. Make sure to add yourself to `CONTRIBUTORS.rst` through this PR provided you're contributing here for the first time) -[//]: # (2. Don't forget to update the `docs/` presuming others would benefit from a concise description of whatever that you're proposing) - + ## Description -[//]: # (What's it you're proposing?) - + +Checklist: +- [ ] I've made sure that tests are updated accordingly (especially if adding or updating a template option) +- [ ] I've updated the documentation or confirm that my change doesn't require any updates ## Rationale -[//]: # (Why does the project need that?) - - - - -## Use case(s) / visualization(s) - -[//]: # ("Better to see something once than to hear about it a thousand times.") - - + diff --git a/.github/changelog-template.md b/.github/changelog-template.md new file mode 100644 index 000000000..64bb71790 --- /dev/null +++ b/.github/changelog-template.md @@ -0,0 +1,11 @@ +{%- for change_type, pulls in grouped_pulls.items() %} +{%- if pulls %} + +### {{ change_type }} + +{%- for pull_request in pulls %} + +- {{ pull_request.title }} ([#{{ pull_request.number }}]({{ pull_request.html_url }})) + {%- endfor -%} + {% endif -%} + {% endfor -%} diff --git a/.github/contributors.json b/.github/contributors.json new file mode 100644 index 000000000..f5d7a4df6 --- /dev/null +++ b/.github/contributors.json @@ -0,0 +1,1402 @@ +[ + { + "name": "Daniel Roy Greenfeld", + "github_login": "pydanny", + "twitter_username": "pydanny", + "is_core": true + }, + { + "name": "Audrey Roy Greenfeld", + "github_login": "audreyr", + "twitter_username": "audreyr", + "is_core": true + }, + { + "name": "Fábio C. Barrionuevo da Luz", + "github_login": "luzfcb", + "twitter_username": "luzfcb", + "is_core": true + }, + { + "name": "Saurabh Kumar", + "github_login": "theskumar", + "twitter_username": "_theskumar", + "is_core": true + }, + { + "name": "Jannis Gebauer", + "github_login": "jayfk", + "twitter_username": "", + "is_core": true + }, + { + "name": "Burhan Khalid", + "github_login": "burhan", + "twitter_username": "burhan", + "is_core": true + }, + { + "name": "Shupeyko Nikita", + "github_login": "webyneter", + "twitter_username": "webyneter", + "is_core": true + }, + { + "name": "Bruno Alla", + "github_login": "browniebroke", + "twitter_username": "_BrunoAlla", + "is_core": true + }, + { + "name": "Wan Liuyang", + "github_login": "sfdye", + "twitter_username": "sfdye", + "is_core": true + }, + { + "name": "Jelmer Draaijer", + "github_login": "foarsitter", + "twitter_username": "", + "is_core": true + }, + { + "name": "18", + "github_login": "dezoito", + "twitter_username": "" + }, + { + "name": "2O4", + "github_login": "2O4", + "twitter_username": "" + }, + { + "name": "a7p", + "github_login": "a7p", + "twitter_username": "" + }, + { + "name": "Aadith PM", + "github_login": "aadithpm", + "twitter_username": "" + }, + { + "name": "Aaron Eikenberry", + "github_login": "aeikenberry", + "twitter_username": "" + }, + { + "name": "Adam Bogdał", + "github_login": "bogdal", + "twitter_username": "" + }, + { + "name": "Adam Dobrawy", + "github_login": "ad-m", + "twitter_username": "" + }, + { + "name": "Adam Steele", + "github_login": "adammsteele", + "twitter_username": "" + }, + { + "name": "Agam Dua", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Agustín Scaramuzza", + "github_login": "scaramagus", + "twitter_username": "scaramagus" + }, + { + "name": "Alberto Sanchez", + "github_login": "alb3rto", + "twitter_username": "" + }, + { + "name": "Alex Tsai", + "github_login": "caffodian", + "twitter_username": "" + }, + { + "name": "Alvaro [Andor]", + "github_login": "andor-pierdelacabeza", + "twitter_username": "" + }, + { + "name": "Amjith Ramanujam", + "github_login": "amjith", + "twitter_username": "" + }, + { + "name": "Andreas Meistad", + "github_login": "ameistad", + "twitter_username": "" + }, + { + "name": "Andres Gonzalez", + "github_login": "andresgz", + "twitter_username": "" + }, + { + "name": "Andrew Mikhnevich", + "github_login": "zcho", + "twitter_username": "" + }, + { + "name": "Andrew Chen Wang", + "github_login": "Andrew-Chen-Wang", + "twitter_username": "" + }, + { + "name": "Andy Rose", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Anna Callahan", + "github_login": "jazztpt", + "twitter_username": "" + }, + { + "name": "Anna Sidwell", + "github_login": "takkaria", + "twitter_username": "" + }, + { + "name": "Antonia Blair", + "github_login": "antoniablair", + "twitter_username": "antoniablairart" + }, + { + "name": "Anuj Bansal", + "github_login": "ahhda", + "twitter_username": "" + }, + { + "name": "Arcuri Davide", + "github_login": "dadokkio", + "twitter_username": "" + }, + { + "name": "Areski Belaid", + "github_login": "areski", + "twitter_username": "" + }, + { + "name": "AsheKR", + "github_login": "ashekr", + "twitter_username": "" + }, + { + "name": "Ashley Camba", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Barclay Gauld", + "github_login": "yunti", + "twitter_username": "" + }, + { + "name": "Bartek", + "github_login": "btknu", + "twitter_username": "" + }, + { + "name": "Ben Lopatin", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Ben Warren", + "github_login": "bwarren2", + "twitter_username": "" + }, + { + "name": "Benjamin Abel", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Bert de Miranda", + "github_login": "bertdemiranda", + "twitter_username": "" + }, + { + "name": "Bo Lopker", + "github_login": "blopker", + "twitter_username": "" + }, + { + "name": "Bo Peng", + "github_login": "BoPeng", + "twitter_username": "" + }, + { + "name": "Bouke Haarsma", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Brent Payne", + "github_login": "brentpayne", + "twitter_username": "brentpayne" + }, + { + "name": "Bruce Olivier", + "github_login": "bolivierjr", + "twitter_username": "" + }, + { + "name": "Caio Ariede", + "github_login": "caioariede", + "twitter_username": "caioariede" + }, + { + "name": "Carl Johnson", + "github_login": "carlmjohnson", + "twitter_username": "carlmjohnson" + }, + { + "name": "Catherine Devlin", + "github_login": "catherinedevlin", + "twitter_username": "" + }, + { + "name": "Cédric Gaspoz", + "github_login": "cgaspoz", + "twitter_username": "" + }, + { + "name": "Charlie Smith", + "github_login": "chuckus", + "twitter_username": "" + }, + { + "name": "Chris Curvey", + "github_login": "ccurvey", + "twitter_username": "" + }, + { + "name": "Chris Franklin", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Chris Franklin", + "github_login": "hairychris", + "twitter_username": "" + }, + { + "name": "Chris Pappalardo", + "github_login": "ChrisPappalardo", + "twitter_username": "" + }, + { + "name": "Christopher Clarke", + "github_login": "chrisdev", + "twitter_username": "" + }, + { + "name": "Cole Mackenzie", + "github_login": "cmackenzie1", + "twitter_username": "" + }, + { + "name": "Cole Maclean", + "github_login": "cole", + "twitter_username": "cole" + }, + { + "name": "Collederas", + "github_login": "Collederas", + "twitter_username": "" + }, + { + "name": "Craig Margieson", + "github_login": "cmargieson", + "twitter_username": "" + }, + { + "name": "Cristian Vargas", + "github_login": "cdvv7788", + "twitter_username": "" + }, + { + "name": "Cullen Rhodes", + "github_login": "c-rhodes", + "twitter_username": "" + }, + { + "name": "Curtis St Pierre", + "github_login": "curtisstpierre", + "twitter_username": "cstpierre1388" + }, + { + "name": "Dan Shultz", + "github_login": "shultz", + "twitter_username": "" + }, + { + "name": "Dani Hodovic", + "github_login": "danihodovic", + "twitter_username": "" + }, + { + "name": "Daniel Hepper", + "github_login": "dhepper", + "twitter_username": "danielhepper" + }, + { + "name": "Daniel Hillier", + "github_login": "danifus", + "twitter_username": "" + }, + { + "name": "Daniel Sears", + "github_login": "highpost", + "twitter_username": "highpost" + }, + { + "name": "Daniele Tricoli", + "github_login": "eriol", + "twitter_username": "" + }, + { + "name": "David Díaz", + "github_login": "ddiazpinto", + "twitter_username": "DavidDiazPinto" + }, + { + "name": "Davit Tovmasyan", + "github_login": "davitovmasyan", + "twitter_username": "" + }, + { + "name": "Davur Clementsen", + "github_login": "dsclementsen", + "twitter_username": "davur" + }, + { + "name": "Delio Castillo", + "github_login": "jangeador", + "twitter_username": "jangeador" + }, + { + "name": "Demetris Stavrou", + "github_login": "demestav", + "twitter_username": "" + }, + { + "name": "Denis Bobrov", + "github_login": "delneg", + "twitter_username": "" + }, + { + "name": "Denis Orehovsky", + "github_login": "apirobot", + "twitter_username": "" + }, + { + "name": "Denis Savran", + "github_login": "blaxpy", + "twitter_username": "" + }, + { + "name": "Diane Chen", + "github_login": "purplediane", + "twitter_username": "purplediane88" + }, + { + "name": "Dónal Adams", + "github_login": "epileptic-fish", + "twitter_username": "" + }, + { + "name": "Dong Huynh", + "github_login": "trungdong", + "twitter_username": "" + }, + { + "name": "Duda Nogueira", + "github_login": "dudanogueira", + "twitter_username": "dudanogueira" + }, + { + "name": "Emanuel Calso", + "github_login": "bloodpet", + "twitter_username": "bloodpet" + }, + { + "name": "Eraldo Energy", + "github_login": "eraldo", + "twitter_username": "" + }, + { + "name": "Eric Groom", + "github_login": "ericgroom", + "twitter_username": "" + }, + { + "name": "Ernesto Cedeno", + "github_login": "codnee", + "twitter_username": "" + }, + { + "name": "Eyad Al Sibai", + "github_login": "eyadsibai", + "twitter_username": "" + }, + { + "name": "Felipe Arruda", + "github_login": "arruda", + "twitter_username": "" + }, + { + "name": "Florian Idelberger", + "github_login": "step21", + "twitter_username": "windrush" + }, + { + "name": "Gabriel Mejia", + "github_login": "elgartoinf", + "twitter_username": "elgartoinf" + }, + { + "name": "Garry Cairns", + "github_login": "garry-cairns", + "twitter_username": "" + }, + { + "name": "Garry Polley", + "github_login": "garrypolley", + "twitter_username": "" + }, + { + "name": "Gilbishkosma", + "github_login": "Gilbishkosma", + "twitter_username": "" + }, + { + "name": "Glenn Wiskur", + "github_login": "gwiskur", + "twitter_username": "" + }, + { + "name": "Guilherme Guy", + "github_login": "guilherme1guy", + "twitter_username": "" + }, + { + "name": "Hamish Durkin", + "github_login": "durkode", + "twitter_username": "" + }, + { + "name": "Hana Quadara", + "github_login": "hanaquadara", + "twitter_username": "" + }, + { + "name": "Hannah Lazarus", + "github_login": "hanhanhan", + "twitter_username": "" + }, + { + "name": "Harry Moreno", + "github_login": "morenoh149", + "twitter_username": "morenoh149" + }, + { + "name": "Harry Percival", + "github_login": "hjwp", + "twitter_username": "" + }, + { + "name": "Hendrik Schneider", + "github_login": "hendrikschneider", + "twitter_username": "" + }, + { + "name": "Henrique G. G. Pereira", + "github_login": "ikkebr", + "twitter_username": "" + }, + { + "name": "Howie Zhao", + "github_login": "howiezhao", + "twitter_username": "" + }, + { + "name": "Ian Lee", + "github_login": "IanLee1521", + "twitter_username": "" + }, + { + "name": "Irfan Ahmad", + "github_login": "erfaan", + "twitter_username": "erfaan" + }, + { + "name": "Isaac12x", + "github_login": "Isaac12x", + "twitter_username": "" + }, + { + "name": "Ivan Khomutov", + "github_login": "ikhomutov", + "twitter_username": "" + }, + { + "name": "James Williams", + "github_login": "jameswilliams1", + "twitter_username": "" + }, + { + "name": "Jan Van Bruggen", + "github_login": "jvanbrug", + "twitter_username": "" + }, + { + "name": "Jerome Caisip", + "github_login": "jeromecaisip", + "twitter_username": "" + }, + { + "name": "Jens Nilsson", + "github_login": "phiberjenz", + "twitter_username": "" + }, + { + "name": "Jerome Leclanche", + "github_login": "jleclanche", + "twitter_username": "Adys" + }, + { + "name": "Jimmy Gitonga", + "github_login": "Afrowave", + "twitter_username": "afrowave" + }, + { + "name": "John Cass", + "github_login": "jcass77", + "twitter_username": "cass_john" + }, + { + "name": "Jonathan Thompson", + "github_login": "nojanath", + "twitter_username": "" + }, + { + "name": "Jules Cheron", + "github_login": "jules-ch", + "twitter_username": "" + }, + { + "name": "Julien Almarcha", + "github_login": "sladinji", + "twitter_username": "" + }, + { + "name": "Julio Castillo", + "github_login": "juliocc", + "twitter_username": "" + }, + { + "name": "Kaido Kert", + "github_login": "kaidokert", + "twitter_username": "" + }, + { + "name": "kappataumu", + "github_login": "kappataumu", + "twitter_username": "kappataumu" + }, + { + "name": "Kaveh", + "github_login": "ka7eh", + "twitter_username": "" + }, + { + "name": "Keith Bailey", + "github_login": "keithjeb", + "twitter_username": "" + }, + { + "name": "Keith Webber", + "github_login": "townie", + "twitter_username": "" + }, + { + "name": "Kevin A. Stone", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Kevin Ndung'u", + "github_login": "kevgathuku", + "twitter_username": "" + }, + { + "name": "Keyvan Mosharraf", + "github_login": "keyvanm", + "twitter_username": "" + }, + { + "name": "Krzysztof Szumny", + "github_login": "noisy", + "twitter_username": "" + }, + { + "name": "Krzysztof Żuraw", + "github_login": "krzysztofzuraw", + "twitter_username": "" + }, + { + "name": "Leo won", + "github_login": "leollon", + "twitter_username": "" + }, + { + "name": "Leo Zhou", + "github_login": "glasslion", + "twitter_username": "" + }, + { + "name": "Leon Kim", + "github_login": "PilhwanKim", + "twitter_username": "" + }, + { + "name": "Leonardo Jimenez", + "github_login": "xpostudio4", + "twitter_username": "" + }, + { + "name": "Lin Xianyi", + "github_login": "iynaix", + "twitter_username": "" + }, + { + "name": "Luis Nell", + "github_login": "originell", + "twitter_username": "" + }, + { + "name": "Lukas Klein", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Lyla Fischer", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Malik Sulaimanov", + "github_login": "flyudvik", + "twitter_username": "flyudvik" + }, + { + "name": "Martin Blech", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Martin Saizar", + "github_login": "msaizar", + "twitter_username": "" + }, + { + "name": "Mateusz Ostaszewski", + "github_login": "mostaszewski", + "twitter_username": "" + }, + { + "name": "Mathijs Hoogland", + "github_login": "MathijsHoogland", + "twitter_username": "" + }, + { + "name": "Matt Braymer-Hayes", + "github_login": "mattayes", + "twitter_username": "mattayes" + }, + { + "name": "Matt Knapper", + "github_login": "mknapper1", + "twitter_username": "" + }, + { + "name": "Matt Linares", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Matt Menzenski", + "github_login": "menzenski", + "twitter_username": "" + }, + { + "name": "Matt Warren", + "github_login": "mfwarren", + "twitter_username": "" + }, + { + "name": "Matthew Sisley", + "github_login": "mjsisley", + "twitter_username": "" + }, + { + "name": "Matthias Sieber", + "github_login": "manonthemat", + "twitter_username": "MatzeOne" + }, + { + "name": "Meghan Heintz", + "github_login": "dot2dotseurat", + "twitter_username": "" + }, + { + "name": "Mesut Yılmaz", + "github_login": "myilmaz", + "twitter_username": "" + }, + { + "name": "Michael Gecht", + "github_login": "mimischi", + "twitter_username": "_mischi" + }, + { + "name": "Michael Samoylov", + "github_login": "msamoylov", + "twitter_username": "" + }, + { + "name": "Min ho Kim", + "github_login": "minho42", + "twitter_username": "" + }, + { + "name": "mozillazg", + "github_login": "mozillazg", + "twitter_username": "" + }, + { + "name": "Nico Stefani", + "github_login": "nicolas471", + "twitter_username": "moby_dick91" + }, + { + "name": "Oleg Russkin", + "github_login": "rolep", + "twitter_username": "" + }, + { + "name": "Pablo", + "github_login": "oubiga", + "twitter_username": "" + }, + { + "name": "Parbhat Puri", + "github_login": "parbhat", + "twitter_username": "" + }, + { + "name": "Pawan Chaurasia", + "github_login": "rjsnh1522", + "twitter_username": "" + }, + { + "name": "Peter Bittner", + "github_login": "bittner", + "twitter_username": "" + }, + { + "name": "Peter Coles", + "github_login": "mrcoles", + "twitter_username": "" + }, + { + "name": "Philipp Matthies", + "github_login": "canonnervio", + "twitter_username": "" + }, + { + "name": "Pierre Chiquet", + "github_login": "pchiquet", + "twitter_username": "" + }, + { + "name": "Raony Guimarães Corrêa", + "github_login": "raonyguimaraes", + "twitter_username": "" + }, + { + "name": "Raphael Pierzina", + "github_login": "hackebrot", + "twitter_username": "" + }, + { + "name": "Reggie Riser", + "github_login": "reggieriser", + "twitter_username": "" + }, + { + "name": "René Muhl", + "github_login": "rm--", + "twitter_username": "" + }, + { + "name": "Richard Hajdu", + "github_login": "Tusky", + "twitter_username": "" + }, + { + "name": "Roman Afanaskin", + "github_login": "siauPatrick", + "twitter_username": "" + }, + { + "name": "Roman Osipenko", + "github_login": "romanosipenko", + "twitter_username": "" + }, + { + "name": "Russell Davies", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Sam Collins", + "github_login": "MightySCollins", + "twitter_username": "" + }, + { + "name": "Sascha", + "github_login": "saschalalala", + "twitter_username": "saschalalala" + }, + { + "name": "Sławek Ehlert", + "github_login": "slafs", + "twitter_username": "" + }, + { + "name": "Sorasful", + "github_login": "sorasful", + "twitter_username": "" + }, + { + "name": "Srinivas Nyayapati", + "github_login": "shireenrao", + "twitter_username": "" + }, + { + "name": "stepmr", + "github_login": "stepmr", + "twitter_username": "" + }, + { + "name": "Steve Steiner", + "github_login": "ssteinerX", + "twitter_username": "" + }, + { + "name": "Sudarshan Wadkar", + "github_login": "wadkar", + "twitter_username": "" + }, + { + "name": "Sule Marshall", + "github_login": "suledev", + "twitter_username": "" + }, + { + "name": "Tano Abeleyra", + "github_login": "tanoabeleyra", + "twitter_username": "" + }, + { + "name": "Taylor Baldwin", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Théo Segonds", + "github_login": "show0k", + "twitter_username": "" + }, + { + "name": "Tim Claessens", + "github_login": "timclaessens", + "twitter_username": "" + }, + { + "name": "Tim Freund", + "github_login": "timfreund", + "twitter_username": "" + }, + { + "name": "Tom Atkins", + "github_login": "knitatoms", + "twitter_username": "" + }, + { + "name": "Tom Offermann", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Travis McNeill", + "github_login": "Travistock", + "twitter_username": "tavistock_esq" + }, + { + "name": "Tubo Shi", + "github_login": "Tubo", + "twitter_username": "" + }, + { + "name": "Umair Ashraf", + "github_login": "umrashrf", + "twitter_username": "fabumair" + }, + { + "name": "Vadim Iskuchekov", + "github_login": "Egregors", + "twitter_username": "egregors" + }, + { + "name": "Vicente G. Reyes", + "github_login": "reyesvicente", + "twitter_username": "highcenburg" + }, + { + "name": "Vitaly Babiy", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Vivian Guillen", + "github_login": "viviangb", + "twitter_username": "" + }, + { + "name": "Vlad Doster", + "github_login": "vladdoster", + "twitter_username": "" + }, + { + "name": "Will Farley", + "github_login": "goldhand", + "twitter_username": "g01dhand" + }, + { + "name": "William Archinal", + "github_login": "archinal", + "twitter_username": "" + }, + { + "name": "Xaver Y.R. Chen", + "github_login": "yrchen", + "twitter_username": "yrchen" + }, + { + "name": "Yaroslav Halchenko", + "github_login": "", + "twitter_username": "" + }, + { + "name": "Yuchen Xie", + "github_login": "mapx", + "twitter_username": "" + }, + { + "name": "enchance", + "github_login": "enchance", + "twitter_username": "" + }, + { + "name": "Jan Fabry", + "github_login": "janfabry", + "twitter_username": "" + }, + { + "name": "Corey Garvey", + "github_login": "coreygarvey", + "twitter_username": "" + }, + { + "name": "Arnav Choudhury", + "github_login": "arnav13081994", + "twitter_username": "" + }, + { + "name": "Wes Turner", + "github_login": "westurner", + "twitter_username": "westurner" + }, + { + "name": "Jakub Musko", + "github_login": "umgelurgel", + "twitter_username": "" + }, + { + "name": "Fabian Affolter", + "github_login": "fabaff", + "twitter_username": "fabaff" + }, + { + "name": "Simon Rey", + "github_login": "eqqe", + "twitter_username": "" + }, + { + "name": "Yotam Tal", + "github_login": "yotamtal", + "twitter_username": "" + }, + { + "name": "John", + "github_login": "thorrak", + "twitter_username": "" + }, + { + "name": "vascop", + "github_login": "vascop", + "twitter_username": "" + }, + { + "name": "PJ Hoberman", + "github_login": "pjhoberman", + "twitter_username": "" + }, + { + "name": "lcd1232", + "github_login": "lcd1232", + "twitter_username": "" + }, + { + "name": "Tames McTigue", + "github_login": "Tamerz", + "twitter_username": "" + }, + { + "name": "Ray Besiga", + "github_login": "raybesiga", + "twitter_username": "raybesiga" + }, + { + "name": "Grant McLean", + "github_login": "grantm", + "twitter_username": "grantmnz" + }, + { + "name": "Kuo Chao Cheng", + "github_login": "wwwtony5488", + "twitter_username": "" + }, + { + "name": "LECbg", + "github_login": "LECbg", + "twitter_username": "" + }, + { + "name": "Haseeb ur Rehman", + "github_login": "professorhaseeb", + "twitter_username": "professorhaseeb" + }, + { + "name": "Abdul Qoyyuum", + "github_login": "Qoyyuum", + "twitter_username": "Qoyyuum" + }, + { + "name": "mfosterw", + "github_login": "mfosterw", + "twitter_username": "" + }, + { + "name": "Keith Callenberg", + "github_login": "keithcallenberg", + "twitter_username": "" + }, + { + "name": "Mike97M", + "github_login": "Mike97M", + "twitter_username": "" + }, + { + "name": "Charlie Macfarlane Brodie", + "github_login": "tannart", + "twitter_username": "" + }, + { + "name": "Floyd Hightower", + "github_login": "fhightower", + "twitter_username": "" + }, + { + "name": "Manjit Pardeshi", + "github_login": "Manjit2003", + "twitter_username": "" + }, + { + "name": "Meraj ", + "github_login": "ichbinmeraj", + "twitter_username": "merajsafari" + }, + { + "name": "dalrrard", + "github_login": "dalrrard", + "twitter_username": "" + }, + { + "name": "Liam Brenner", + "github_login": "SableWalnut", + "twitter_username": "" + }, + { + "name": "Noah H", + "github_login": "nthall", + "twitter_username": "" + }, + { + "name": "Diego Montes", + "github_login": "d57montes", + "twitter_username": "" + }, + { + "name": "Chao Yang Wu", + "github_login": "goatwu1993", + "twitter_username": "" + }, + { + "name": "mpoli", + "github_login": "mpoli", + "twitter_username": "" + }, + { + "name": "Zach Borboa", + "github_login": "zachborboa", + "twitter_username": "" + }, + { + "name": "Timm Simpkins", + "github_login": "PoDuck", + "twitter_username": "" + }, + { + "name": "Douglas", + "github_login": "douglascdev", + "twitter_username": "" + }, + { + "name": "Will Gordon", + "github_login": "wgordon17", + "twitter_username": "" + }, + { + "name": "Bogdan Mateescu", + "github_login": "mateesville93", + "twitter_username": "" + }, + { + "name": "Fuzzwah", + "github_login": "Fuzzwah", + "twitter_username": "" + }, + { + "name": "Thibault J.", + "github_login": "thibault", + "twitter_username": "thibault" + }, + { + "name": "Pedro Campos", + "github_login": "pcampos119104", + "twitter_username": "" + }, + { + "name": "Vikas Yadav", + "github_login": "vik-y", + "twitter_username": "" + }, + { + "name": "Abdullah Adeel", + "github_login": "mabdullahadeel", + "twitter_username": "abdadeel_" + }, + { + "name": "Jorge Valdez", + "github_login": "jorgeavaldez", + "twitter_username": "" + }, + { + "name": "Ryan Fitch", + "github_login": "ryfi", + "twitter_username": "" + }, + { + "name": "ghazi-git", + "github_login": "ghazi-git", + "twitter_username": "" + }, + { + "name": "Cebrail Yılmaz", + "github_login": "b1sar", + "twitter_username": "" + }, + { + "name": "Artur Barseghyan", + "github_login": "barseghyanartur", + "twitter_username": "" + }, + { + "name": "innicoder", + "github_login": "innicoder", + "twitter_username": "" + }, + { + "name": "Naveen", + "github_login": "naveensrinivasan", + "twitter_username": "snaveen" + }, + { + "name": "Nikita Sobolev", + "github_login": "sobolevn", + "twitter_username": "" + }, + { + "name": "Sebastian Reyes Espinosa", + "github_login": "sebastian-code", + "twitter_username": "sebastianreyese" + }, + { + "name": "jugglinmike", + "github_login": "jugglinmike", + "twitter_username": "" + }, + { + "name": "monosans", + "github_login": "monosans", + "twitter_username": "" + }, + { + "name": "Marcio Mazza", + "github_login": "marciomazza", + "twitter_username": "marciomazza" + }, + { + "name": "Brandon Rumiser", + "github_login": "brumiser1550", + "twitter_username": "" + }, + { + "name": "krati yadav", + "github_login": "krati5", + "twitter_username": "" + }, + { + "name": "Abe Hanoka", + "github_login": "abe-101", + "twitter_username": "abe__101" + }, + { + "name": "Adin Hodovic", + "github_login": "adinhodovic", + "twitter_username": "" + }, + { + "name": "Leifur Halldor Asgeirsson", + "github_login": "leifurhauks", + "twitter_username": "" + }, + { + "name": "David", + "github_login": "buckldav", + "twitter_username": "" + }, + { + "name": "rguptar", + "github_login": "rguptar", + "twitter_username": "" + }, + { + "name": "Omer-5", + "github_login": "Omer-5", + "twitter_username": "" + }, + { + "name": "TAKAHASHI Shuuji", + "github_login": "shuuji3", + "twitter_username": "" + }, + { + "name": "Thomas Booij", + "github_login": "ThomasBooij95", + "twitter_username": "" + }, + { + "name": "Pamela Fox", + "github_login": "pamelafox", + "twitter_username": "pamelafox" + }, + { + "name": "Robin", + "github_login": "Kaffeetasse", + "twitter_username": "" + }, + { + "name": "Patrick Tran", + "github_login": "theptrk", + "twitter_username": "" + }, + { + "name": "tildebox", + "github_login": "tildebox", + "twitter_username": "" + }, + { + "name": "duffn", + "github_login": "duffn", + "twitter_username": "" + }, + { + "name": "Delphine LEMIRE", + "github_login": "DelphineLemire", + "twitter_username": "" + }, + { + "name": "Hoai-Thu Vuong", + "github_login": "thuvh", + "twitter_username": "" + }, + { + "name": "Arkadiusz Michał Ryś", + "github_login": "arrys", + "twitter_username": "" + }, + { + "name": "mpsantos", + "github_login": "mpsantos", + "twitter_username": "" + }, + { + "name": "Morten Kaae", + "github_login": "MortenKaae", + "twitter_username": "" + }, + { + "name": "Birtibu", + "github_login": "Birtibu", + "twitter_username": "" + }, + { + "name": "Matheus Jardim Bernardes", + "github_login": "matheusjardimb", + "twitter_username": "" + } +] \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..7642a3f2d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,88 @@ +# Config for Dependabot updates. See Documentation here: +# https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates + +version: 2 +updates: + # Update GitHub actions in workflows + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + labels: + - "update" + + # Update npm packages + - package-ecosystem: "npm" + directory: "{{cookiecutter.project_slug}}/" + schedule: + interval: "daily" + labels: + - "update" + + # Enable version updates for Docker + # We need to specify each Dockerfile in a separate entry because Dependabot doesn't + # support wildcards or recursively checking subdirectories. Check this issue for updates: + # https://github.com/dependabot/dependabot-core/issues/2178 + - package-ecosystem: "docker" + directory: "{{cookiecutter.project_slug}}/compose/local/django/" + schedule: + interval: "daily" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" + labels: + - "update" + + - package-ecosystem: "docker" + directory: "{{cookiecutter.project_slug}}/compose/local/docs/" + schedule: + interval: "daily" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" + labels: + - "update" + + - package-ecosystem: "docker" + directory: "{{cookiecutter.project_slug}}/compose/local/node/" + schedule: + interval: "daily" + labels: + - "update" + + - package-ecosystem: "docker" + directory: "{{cookiecutter.project_slug}}/compose/production/aws/" + schedule: + interval: "daily" + labels: + - "update" + + - package-ecosystem: "docker" + directory: "{{cookiecutter.project_slug}}/compose/production/django/" + schedule: + interval: "daily" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" + labels: + - "update" + + - package-ecosystem: "docker" + directory: "{{cookiecutter.project_slug}}/compose/production/postgres/" + schedule: + interval: "daily" + labels: + - "update" + + - package-ecosystem: "docker" + directory: "{{cookiecutter.project_slug}}/compose/production/traefik/" + schedule: + interval: "daily" + labels: + - "update" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..dbda77b5e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,115 @@ +name: CI + +on: + push: + branches: ["master", "main"] + pull_request: + +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + tests: + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - windows-latest + - macOS-latest + + name: "pytest ${{ matrix.os }}" + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + cache: pip + - name: Install dependencies + run: pip install -r requirements.txt + - name: Run tests + run: pytest -n auto tests + + docker: + strategy: + fail-fast: false + matrix: + script: + - name: Basic + args: "ci_tool=Gitlab" + - name: Celery & DRF + args: "use_celery=y use_drf=y" + - name: Gulp + args: "frontend_pipeline=Gulp" + - name: Webpack + args: "frontend_pipeline=Webpack" + + name: "Docker ${{ matrix.script.name }}" + runs-on: ubuntu-latest + env: + DOCKER_BUILDKIT: 1 + COMPOSE_DOCKER_CLI_BUILD: 1 + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + cache: pip + - name: Install dependencies + run: pip install -r requirements.txt + - name: Docker ${{ matrix.script.name }} + run: sh tests/test_docker.sh ${{ matrix.script.args }} + + bare: + strategy: + fail-fast: false + matrix: + script: + - name: Celery + args: "use_celery=y frontend_pipeline='Django Compressor'" + - name: Gulp + args: "frontend_pipeline=Gulp" + - name: Webpack + args: "frontend_pipeline=Webpack use_heroku=y" + - name: Email Username + args: "username_type=email ci_tool=Github" + + name: "Bare metal ${{ matrix.script.name }}" + runs-on: ubuntu-latest + services: + redis: + image: redis:5.0 + ports: + - 6379:6379 + postgres: + image: postgres:12 + ports: + - 5432:5432 + env: + POSTGRES_PASSWORD: postgres + + env: + CELERY_BROKER_URL: "redis://localhost:6379/0" + # postgres://user:password@host:port/database + DATABASE_URL: "postgres://postgres:postgres@localhost:5432/postgres" + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + cache: pip + cache-dependency-path: | + requirements.txt + {{cookiecutter.project_slug}}/requirements/base.txt + {{cookiecutter.project_slug}}/requirements/local.txt + - name: Install dependencies + run: pip install -r requirements.txt + - uses: actions/setup-node@v3 + with: + node-version: "18" + - name: Bare Metal ${{ matrix.script.name }} + run: sh tests/test_bare.sh ${{ matrix.script.args }} diff --git a/.github/workflows/django-issue-checker.yml b/.github/workflows/django-issue-checker.yml new file mode 100644 index 000000000..cbfea922d --- /dev/null +++ b/.github/workflows/django-issue-checker.yml @@ -0,0 +1,30 @@ +# Creates a new issue for Major/Minor Django updates that keeps track +# of all dependencies that need to be updated/merged in order for the +# latest Django version to also be merged. +name: Django Issue Checker + +on: + schedule: + - cron: "28 5 * * *" + # Manual trigger + workflow_dispatch: + +jobs: + issue-checker: + # Disables this workflow from running in a repository that is not part of the indicated organization/user + if: github.repository_owner == 'cookiecutter' + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Create Django Major Issue + run: python scripts/create_django_issue.py + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml new file mode 100644 index 000000000..a6e074137 --- /dev/null +++ b/.github/workflows/issue-manager.yml @@ -0,0 +1,40 @@ +# Automatically close issues or pull requests that have a label, after a custom delay, if no one replies. +# https://github.com/tiangolo/issue-manager +name: Issue Manager + +on: + schedule: + - cron: "12 0 * * *" + issue_comment: + types: + - created + issues: + types: + - labeled + pull_request_target: + types: + - labeled + workflow_dispatch: + +jobs: + issue-manager: + # Disables this workflow from running in a repository that is not part of the indicated organization/user + if: github.repository_owner == 'cookiecutter' + + runs-on: ubuntu-latest + steps: + - uses: tiangolo/issue-manager@0.4.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + config: > + { + "answered": { + "message": "Assuming the question was answered, this will be automatically closed now." + }, + "solved": { + "message": "Assuming the original issue was solved, it will be automatically closed now." + }, + "waiting": { + "message": "Automatically closing after waiting for additional info. To re-open, please provide the additional information requested." + } + } diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml new file mode 100644 index 000000000..75bfe0a20 --- /dev/null +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -0,0 +1,47 @@ +# Run pre-commit autoupdate every day at midnight +# and create a pull request if any changes + +name: Pre-commit auto-update + +on: + schedule: + - cron: "15 2 * * *" + workflow_dispatch: # to trigger manually + +permissions: + contents: read + +jobs: + auto-update: + # Disables this workflow from running in a repository that is not part of the indicated organization/user + if: github.repository_owner == 'cookiecutter' + permissions: + contents: write # for peter-evans/create-pull-request to create branch + pull-requests: write # for peter-evans/create-pull-request to create a PR + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Install pre-commit + run: pip install pre-commit + + - name: Autoupdate template + run: pre-commit autoupdate + + - name: Autoupdate generated projects + working-directory: "{{cookiecutter.project_slug}}" + run: pre-commit autoupdate + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: update/pre-commit-autoupdate + title: Auto-update pre-commit hooks + commit-message: Auto-update pre-commit hooks + body: Update versions of tools in pre-commit configs to latest version + labels: update diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml new file mode 100644 index 000000000..f48f297aa --- /dev/null +++ b/.github/workflows/update-changelog.yml @@ -0,0 +1,34 @@ +name: Update Changelog + +on: + # Every day at 2am + schedule: + - cron: "0 2 * * *" + # Manual trigger + workflow_dispatch: + +jobs: + release: + # Disables this workflow from running in a repository that is not part of the indicated organization/user + if: github.repository_owner == 'cookiecutter' + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Set git details + run: | + git config --global user.name "github-actions" + git config --global user.email "action@github.com" + - name: Update list + run: python scripts/update_changelog.py + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml new file mode 100644 index 000000000..78d72c241 --- /dev/null +++ b/.github/workflows/update-contributors.yml @@ -0,0 +1,39 @@ +name: Update Contributors + +on: + push: + branches: + - master + +permissions: + contents: read + +jobs: + build: + # Disables this workflow from running in a repository that is not part of the indicated organization/user + if: github.repository_owner == 'cookiecutter' + permissions: + contents: write # for stefanzweifel/git-auto-commit-action to push code in repo + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Update list + run: python scripts/update_contributors.py + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v4.16.0 + with: + commit_message: Update Contributors + file_pattern: CONTRIBUTORS.md .github/contributors.json diff --git a/.gitignore b/.gitignore index 54fafb8be..f753fec91 100644 --- a/.gitignore +++ b/.gitignore @@ -208,18 +208,6 @@ Session.vim tags -### VirtualEnv template -# Virtualenv -# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ -[Bb]in -[Ii]nclude -[Ll]ib -[Ll]ib64 -[Ss]cripts -pyvenv.cfg -pip-selfcheck.json - - # Even though the project might be opened and edited # in any of the JetBrains IDEs, it makes no sence whatsoever # to 'run' anything within it since any particular cookiecutter diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..b35eae073 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,50 @@ +exclude: "{{cookiecutter.project_slug}}|.github/contributors.json|CHANGELOG.md|CONTRIBUTORS.md" +default_stages: [commit] + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-json + - id: check-toml + - id: check-xml + - id: check-yaml + - id: debug-statements + - id: check-builtin-literals + - id: check-case-conflict + - id: detect-private-key + + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "v3.0.0-alpha.9-for-vscode" + hooks: + - id: prettier + args: ["--tab-width", "2"] + + - repo: https://github.com/asottile/pyupgrade + rev: v3.7.0 + hooks: + - id: pyupgrade + args: [--py311-plus] + exclude: hooks/ + + - repo: https://github.com/psf/black + rev: 23.3.0 + hooks: + - id: black + + - repo: https://github.com/PyCQA/isort + rev: 5.12.0 + hooks: + - id: isort + + - repo: https://github.com/PyCQA/flake8 + rev: 6.0.0 + hooks: + - id: flake8 + +ci: + autoupdate_schedule: weekly + skip: [] + submodules: false diff --git a/.pyup.yml b/.pyup.yml new file mode 100644 index 000000000..e5d4752e4 --- /dev/null +++ b/.pyup.yml @@ -0,0 +1,21 @@ +# configure updates globally +# default: all +# allowed: all, insecure, False +update: all + +# configure dependency pinning globally +# default: True +# allowed: True, False +pin: True + +# add a label to pull requests, default is not set +# requires private repo permissions, even on public repos +# default: empty +label_prs: update + +requirements: + - "requirements.txt" + - "docs/requirements.txt" + - "{{cookiecutter.project_slug}}/requirements/base.txt" + - "{{cookiecutter.project_slug}}/requirements/local.txt" + - "{{cookiecutter.project_slug}}/requirements/production.txt" diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..4598ff77c --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,20 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + +# Declare the Python requirements required to build your docs +python: + install: + - requirements: docs/requirements.txt diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a46726d6c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -sudo: required - -services: - - docker - -language: python - -python: 3.6 - -env: - - TOX_ENV=py36 - -before_install: - - docker-compose -v - - docker -v - -script: - - tox -e $TOX_ENV - - sh tests/test_docker.sh - -install: - - pip install tox - -notifications: - email: - on_success: change - on_failure: always diff --git a/CHANGELOG.md b/CHANGELOG.md index 835108280..e60e18d27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,3059 @@ # Change Log All enhancements and patches to Cookiecutter Django will be documented in this file. -This project adheres to [Semantic Versioning](http://semver.org/). -## [2019-01-30] + + +## 2023.06.27 + + +### Changed + +- Populate User `name` field during social auth ([#3968](https://github.com/cookiecutter/cookiecutter-django/pull/3968)) + +- Add djLint for HTML formatting and linting ([#4389](https://github.com/cookiecutter/cookiecutter-django/pull/4389)) + +### Fixed + +- Only include prettier pre-commit hook with node-based front-end pipeline ([#4418](https://github.com/cookiecutter/cookiecutter-django/pull/4418)) + +### Updated + +- Update djangorestframework-stubs to 3.14.2 ([#4420](https://github.com/cookiecutter/cookiecutter-django/pull/4420)) + +- Update django-stubs to 4.2.2 ([#4419](https://github.com/cookiecutter/cookiecutter-django/pull/4419)) + +## 2023.06.26 + + +### Updated + +- Update pytest to 7.4.0 ([#4412](https://github.com/cookiecutter/cookiecutter-django/pull/4412)) + +- Update redis to 4.6.0 ([#4415](https://github.com/cookiecutter/cookiecutter-django/pull/4415)) + +- Update mypy to 1.4.1 ([#4416](https://github.com/cookiecutter/cookiecutter-django/pull/4416)) + +## 2023.06.22 + + +### Updated + +- Update pygithub to 1.59.0 ([#4410](https://github.com/cookiecutter/cookiecutter-django/pull/4410)) + +- Update drf-spectacular to 0.26.3 ([#4411](https://github.com/cookiecutter/cookiecutter-django/pull/4411)) + +- Update sentry-sdk to 1.26.0 ([#4409](https://github.com/cookiecutter/cookiecutter-django/pull/4409)) + +## 2023.06.21 + + +### Updated + +- Upgrade traefik to 2.10.3 ([#4408](https://github.com/cookiecutter/cookiecutter-django/pull/4408)) + +## 2023.06.19 + + +### Updated + +- Auto-update pre-commit hooks ([#4405](https://github.com/cookiecutter/cookiecutter-django/pull/4405)) + +- Update celery to 5.3.1 ([#4404](https://github.com/cookiecutter/cookiecutter-django/pull/4404)) + +## 2023.06.18 + + +### Changed + +- Fix missing celery env variable when running compilemessages ([#4403](https://github.com/cookiecutter/cookiecutter-django/pull/4403)) + +### Updated + +- Update flower to 2.0.0 ([#4402](https://github.com/cookiecutter/cookiecutter-django/pull/4402)) + +## 2023.06.17 + + +## 2023.06.16 + + +### Updated + +- Update whitenoise to 6.5.0 ([#4400](https://github.com/cookiecutter/cookiecutter-django/pull/4400)) + +- Update django-redis to 5.3.0 ([#4399](https://github.com/cookiecutter/cookiecutter-django/pull/4399)) + +- Auto-update pre-commit hooks ([#4395](https://github.com/cookiecutter/cookiecutter-django/pull/4395)) + +## 2023.06.14 + + +### Updated + +- Update django-cors-headers to 4.1.0 ([#4391](https://github.com/cookiecutter/cookiecutter-django/pull/4391)) + +- Update django-upgrade to 1.14.0 ([#4394](https://github.com/cookiecutter/cookiecutter-django/pull/4394)) + +- Update django-webpack-loader to 2.0.1 ([#4392](https://github.com/cookiecutter/cookiecutter-django/pull/4392)) + +- Update pre-commit to 3.3.3 ([#4390](https://github.com/cookiecutter/cookiecutter-django/pull/4390)) + +## 2023.06.11 + + +### Updated + +- Update pytest to 7.3.2 ([#4384](https://github.com/cookiecutter/cookiecutter-django/pull/4384)) + +- Auto-update pre-commit hooks ([#4385](https://github.com/cookiecutter/cookiecutter-django/pull/4385)) + +## 2023.06.09 + + +### Fixed + +- Fix missing `compilemessages` step before deploying to prod ([#4363](https://github.com/cookiecutter/cookiecutter-django/pull/4363)) + +## 2023.06.08 + + +### Fixed + +- Fix failure in user view test caused by translations ([#4374](https://github.com/cookiecutter/cookiecutter-django/pull/4374)) + +### Updated + +- Update to Python 3.11.4 in production Docker compose ([#4378](https://github.com/cookiecutter/cookiecutter-django/pull/4378)) + +- Update to Python 3.11.4 in docs Docker compose ([#4379](https://github.com/cookiecutter/cookiecutter-django/pull/4379)) + +- Update to Python 3.11.4 in local Docker compose ([#4380](https://github.com/cookiecutter/cookiecutter-django/pull/4380)) + +- Update celery to 5.3.0 ([#4369](https://github.com/cookiecutter/cookiecutter-django/pull/4369)) + +- Update werkzeug to 2.3.5 ([#4377](https://github.com/cookiecutter/cookiecutter-django/pull/4377)) + +## 2023.06.07 + + +### Changed + +- Replace `runserver` with `runserver_plus` ([#4373](https://github.com/cookiecutter/cookiecutter-django/pull/4373)) + +- Add translations for Brazilian Portuguese ([#4367](https://github.com/cookiecutter/cookiecutter-django/pull/4367)) + +### Updated + +- Update sentry-sdk to 1.25.1 ([#4376](https://github.com/cookiecutter/cookiecutter-django/pull/4376)) + +- Update django-extensions to 3.2.3 ([#4372](https://github.com/cookiecutter/cookiecutter-django/pull/4372)) + +- Update djangorestframework-stubs to 3.14.1 ([#4366](https://github.com/cookiecutter/cookiecutter-django/pull/4366)) + +- Update django-stubs to 4.2.1 ([#4365](https://github.com/cookiecutter/cookiecutter-django/pull/4365)) + +- Update mypy to 1.3.0 ([#4327](https://github.com/cookiecutter/cookiecutter-django/pull/4327)) + +## 2023.06.02 + + +### Updated + +- Update sentry-sdk to 1.25.0 ([#4364](https://github.com/cookiecutter/cookiecutter-django/pull/4364)) + +## 2023.05.30 + + +### Updated + +- Update hiredis to 2.2.3 ([#4360](https://github.com/cookiecutter/cookiecutter-django/pull/4360)) + +- Update django-debug-toolbar to 4.1.0 ([#4359](https://github.com/cookiecutter/cookiecutter-django/pull/4359)) + +- Update redis to 4.5.5 ([#4358](https://github.com/cookiecutter/cookiecutter-django/pull/4358)) + +- Update django-anymail to 10.0 ([#4357](https://github.com/cookiecutter/cookiecutter-django/pull/4357)) + +- Update coverage to 7.2.7 ([#4356](https://github.com/cookiecutter/cookiecutter-django/pull/4356)) + +## 2023.05.28 + + +## 2023.05.24 + + +### Fixed + +- Prevent Celery restarts on media file changes ([#4352](https://github.com/cookiecutter/cookiecutter-django/pull/4352)) + +### Updated + +- Update coverage to 7.2.6 ([#4351](https://github.com/cookiecutter/cookiecutter-django/pull/4351)) + +## 2023.05.23 + + +### Changed + +- Fix compatibility webpack-bundle-tracker>=2.0.0 js library required after upgrade django-webpack-loader>=2.0.0 ([#4350](https://github.com/cookiecutter/cookiecutter-django/pull/4350)) + +### Updated + +- Update sphinx-rtd-theme to 1.2.1 ([#4348](https://github.com/cookiecutter/cookiecutter-django/pull/4348)) + +- Update sentry-sdk to 1.24.0 ([#4349](https://github.com/cookiecutter/cookiecutter-django/pull/4349)) + +- Bump webpack-bundle-tracker from 1.8.1 to 2.0.0 in /{{cookiecutter.project_slug}} ([#4347](https://github.com/cookiecutter/cookiecutter-django/pull/4347)) + +- Update django-webpack-loader to 2.0.0 ([#4345](https://github.com/cookiecutter/cookiecutter-django/pull/4345)) + +- Update pytest-xdist to 3.3.1 ([#4344](https://github.com/cookiecutter/cookiecutter-django/pull/4344)) + +- Update requests to 2.31.0 ([#4346](https://github.com/cookiecutter/cookiecutter-django/pull/4346)) + +## 2023.05.18 + + +### Updated + +- Update pre-commit to 3.3.2 ([#4342](https://github.com/cookiecutter/cookiecutter-django/pull/4342)) + +## 2023.05.17 + + +### Updated + +- Update sentry-sdk to 1.23.1 ([#4341](https://github.com/cookiecutter/cookiecutter-django/pull/4341)) + +## 2023.05.15 + + +### Updated + +- Update django-cors-headers to 4.0.0 ([#4329](https://github.com/cookiecutter/cookiecutter-django/pull/4329)) + +- Update sentry-sdk to 1.23.0 ([#4337](https://github.com/cookiecutter/cookiecutter-django/pull/4337)) + +## 2023.05.09 + + +### Updated + +- Update werkzeug to 2.3.4 ([#4325](https://github.com/cookiecutter/cookiecutter-django/pull/4325)) + +## 2023.05.08 + + +### Updated + +- Auto-update pre-commit hooks ([#4320](https://github.com/cookiecutter/cookiecutter-django/pull/4320)) + +- Update sentry-sdk to 1.22.2 ([#4321](https://github.com/cookiecutter/cookiecutter-django/pull/4321)) + +## 2023.05.04 + + +### Changed + +- Remove pytz from dependencies ([#4309](https://github.com/cookiecutter/cookiecutter-django/pull/4309)) + +### Updated + +- Update django-anymail to 9.2 ([#4316](https://github.com/cookiecutter/cookiecutter-django/pull/4316)) + +- Update pre-commit to 3.3.1 ([#4315](https://github.com/cookiecutter/cookiecutter-django/pull/4315)) + +- Update coverage to 7.2.5 ([#4314](https://github.com/cookiecutter/cookiecutter-django/pull/4314)) + +- Update django to 4.1.9 ([#4313](https://github.com/cookiecutter/cookiecutter-django/pull/4313)) + +- Update sentry-sdk to 1.21.1 ([#4312](https://github.com/cookiecutter/cookiecutter-django/pull/4312)) + +- Update requests to 2.30.0 ([#4311](https://github.com/cookiecutter/cookiecutter-django/pull/4311)) + +## 2023.05.02 + + +### Updated + +- Upgrade traefik to 2.10.1 ([#4304](https://github.com/cookiecutter/cookiecutter-django/pull/4304)) + +- Update uvicorn to 0.22.0 ([#4305](https://github.com/cookiecutter/cookiecutter-django/pull/4305)) + +- Update werkzeug to 2.3.3 ([#4307](https://github.com/cookiecutter/cookiecutter-django/pull/4307)) + +## 2023.04.28 + + +### Changed + +- Add django-upgrade to pre-commit hooks ([#4298](https://github.com/cookiecutter/cookiecutter-django/pull/4298)) + +## 2023.04.27 + + +### Updated + +- Update djangorestframework-stubs to 3.14.0 ([#4303](https://github.com/cookiecutter/cookiecutter-django/pull/4303)) + +- Update werkzeug to 2.3.1 ([#4302](https://github.com/cookiecutter/cookiecutter-django/pull/4302)) + +- Update django-stubs to 4.2.0 ([#4301](https://github.com/cookiecutter/cookiecutter-django/pull/4301)) + +## 2023.04.26 + + +### Updated + +- Upgrade cssnano to v6.0.0 ([#4233](https://github.com/cookiecutter/cookiecutter-django/pull/4233)) + +- Upgrade concurrently to 8.0.1 ([#4237](https://github.com/cookiecutter/cookiecutter-django/pull/4237)) + +- Upgrade to node v18 ([#4294](https://github.com/cookiecutter/cookiecutter-django/pull/4294)) + +- Update coverage to 7.2.3 ([#4297](https://github.com/cookiecutter/cookiecutter-django/pull/4297)) + +- Update mypy to 1.2.0 ([#4295](https://github.com/cookiecutter/cookiecutter-django/pull/4295)) + +- Update werkzeug to 2.3.0 ([#4296](https://github.com/cookiecutter/cookiecutter-django/pull/4296)) + +## 2023.04.25 + + +### Updated + +- Update sentry-sdk to 1.21.0 ([#4293](https://github.com/cookiecutter/cookiecutter-django/pull/4293)) + +- Update sphinx to 6.2.1 ([#4292](https://github.com/cookiecutter/cookiecutter-django/pull/4292)) + +- Bump traefik from 2.9.10 to 2.10.0 ([#4290](https://github.com/cookiecutter/cookiecutter-django/pull/4290)) + +- Auto-update pre-commit hooks ([#4288](https://github.com/cookiecutter/cookiecutter-django/pull/4288)) + +## 2023.04.24 + + +### Updated + +- Auto-update pre-commit hooks ([#4286](https://github.com/cookiecutter/cookiecutter-django/pull/4286)) + +- Update sphinx to 6.2.0 ([#4285](https://github.com/cookiecutter/cookiecutter-django/pull/4285)) + +## 2023.04.19 + + +### Updated + +- Update sentry-sdk to 1.20.0 ([#4282](https://github.com/cookiecutter/cookiecutter-django/pull/4282)) + +## 2023.04.18 + + +### Documentation + +- Document how to add 3rd party packages with Docker ([#4279](https://github.com/cookiecutter/cookiecutter-django/pull/4279)) + +## 2023.04.15 + + +### Changed + +- Add username_type option ([#3958](https://github.com/cookiecutter/cookiecutter-django/pull/3958)) + +- Fix inconsistent line length and move configs to pyproject.toml ([#4276](https://github.com/cookiecutter/cookiecutter-django/pull/4276)) + +- Relax rules for linting of pull requests on this template ([#4273](https://github.com/cookiecutter/cookiecutter-django/pull/4273)) + +- Add more pre-commit hooks ([#4266](https://github.com/cookiecutter/cookiecutter-django/pull/4266)) + +- Upgrade Python to version 3.11 (Faster CPython) ([#4256](https://github.com/cookiecutter/cookiecutter-django/pull/4256)) + +### Updated + +- Update drf-spectacular to 0.26.2 ([#4277](https://github.com/cookiecutter/cookiecutter-django/pull/4277)) + +- Update pytest to 7.3.1 ([#4272](https://github.com/cookiecutter/cookiecutter-django/pull/4272)) + +## 2023.04.13 + +### Updated +- Update tox to 4.4.12 ([#4271](https://github.com/cookiecutter/cookiecutter-django/pull/4271)) + +## 2023.04.10 + +### Updated +- Update pytest-sugar to 0.9.7 ([#4269](https://github.com/cookiecutter/cookiecutter-django/pull/4269)) +- Update pytest to 7.3.0 ([#4268](https://github.com/cookiecutter/cookiecutter-django/pull/4268)) + +## 2023.04.07 + +### Updated +- Upgrade traefik to 2.9.10 ([#4267](https://github.com/cookiecutter/cookiecutter-django/pull/4267)) + +## 2023.04.05 + +### Changed +- Update indent for nginx config file ([#4260](https://github.com/cookiecutter/cookiecutter-django/pull/4260)) +### Updated +- Update tox to 4.4.11 ([#4262](https://github.com/cookiecutter/cookiecutter-django/pull/4262)) +- Update django to 4.1.8 ([#4258](https://github.com/cookiecutter/cookiecutter-django/pull/4258)) +- Update pre-commit to 3.2.2 ([#4259](https://github.com/cookiecutter/cookiecutter-django/pull/4259)) + +## 2023.04.04 + +### Changed +- Upgrade to Django 4.1 ([#4028](https://github.com/cookiecutter/cookiecutter-django/pull/4028)) +- Remove deprecated security setting ([#4247](https://github.com/cookiecutter/cookiecutter-django/pull/4247)) +### Fixed +- Replace `runserver_plus` with `runserver` ([#4255](https://github.com/cookiecutter/cookiecutter-django/pull/4255)) +- Fix traefik rule priority for media router ([#4244](https://github.com/cookiecutter/cookiecutter-django/pull/4244)) +### Updated +- Update sentry-sdk to 1.19.0 ([#4254](https://github.com/cookiecutter/cookiecutter-django/pull/4254)) +- Update django-debug-toolbar to 4.0.0 ([#4251](https://github.com/cookiecutter/cookiecutter-django/pull/4251)) + +## 2023.04.03 + +### Changed +- fix: Syntax for ignoring specific noqa errors ([#4250](https://github.com/cookiecutter/cookiecutter-django/pull/4250)) +### Updated +- Update psycopg2-binary to 2.9.6 ([#4249](https://github.com/cookiecutter/cookiecutter-django/pull/4249)) +- Update psycopg2 to 2.9.6 ([#4248](https://github.com/cookiecutter/cookiecutter-django/pull/4248)) + +## 2023.04.01 + +### Updated +- Update pytest-instafail to 0.5.0 ([#4240](https://github.com/cookiecutter/cookiecutter-django/pull/4240)) +- Update pillow to 9.5.0 ([#4242](https://github.com/cookiecutter/cookiecutter-django/pull/4242)) +- Update django-allauth to 0.54.0 ([#4241](https://github.com/cookiecutter/cookiecutter-django/pull/4241)) + +## 2023.03.29 + +### Updated +- Update redis to 4.5.4 ([#4239](https://github.com/cookiecutter/cookiecutter-django/pull/4239)) +- Update pytz to 2023.3 ([#4238](https://github.com/cookiecutter/cookiecutter-django/pull/4238)) +- Update black to 23.3.0 ([#4236](https://github.com/cookiecutter/cookiecutter-django/pull/4236)) + +## 2023.03.27 + +### Updated +- Update watchfiles to 0.19.0 ([#4232](https://github.com/cookiecutter/cookiecutter-django/pull/4232)) + +## 2023.03.26 + +### Updated +- Update pre-commit to 3.2.1 ([#4229](https://github.com/cookiecutter/cookiecutter-django/pull/4229)) + +## 2023.03.25 + +### Updated +- Update pytz to 2023.2 ([#4228](https://github.com/cookiecutter/cookiecutter-django/pull/4228)) + +## 2023.03.23 + +### Updated +- Bump traefik from 2.9.8 to 2.9.9 ([#4225](https://github.com/cookiecutter/cookiecutter-django/pull/4225)) + +## 2023.03.22 + +### Updated +- Update redis to 4.5.3 ([#4227](https://github.com/cookiecutter/cookiecutter-django/pull/4227)) + +## 2023.03.20 + +### Updated +- Update django-allauth to 0.53.1 ([#4223](https://github.com/cookiecutter/cookiecutter-django/pull/4223)) +- Update redis to 4.5.2 ([#4222](https://github.com/cookiecutter/cookiecutter-django/pull/4222)) + +## 2023.03.18 + +### Updated +- Update drf-spectacular to 0.26.1 ([#4221](https://github.com/cookiecutter/cookiecutter-django/pull/4221)) +- Update pygithub to 1.58.1 ([#4220](https://github.com/cookiecutter/cookiecutter-django/pull/4220)) +- Update pre-commit to 3.2.0 ([#4219](https://github.com/cookiecutter/cookiecutter-django/pull/4219)) + +## 2023.03.16 + +### Changed +- Pin base Python Docker images to bugfix ([#4194](https://github.com/cookiecutter/cookiecutter-django/pull/4194)) +### Fixed +- Trim leading and trailing space in `domain_name` and `email` ([#4163](https://github.com/cookiecutter/cookiecutter-django/pull/4163)) +### Updated +- Update djangorestframework-stubs to 1.10.0 ([#4217](https://github.com/cookiecutter/cookiecutter-django/pull/4217)) +- Update django-stubs to 1.16.0 ([#4216](https://github.com/cookiecutter/cookiecutter-django/pull/4216)) +- Update coverage to 7.2.2 ([#4218](https://github.com/cookiecutter/cookiecutter-django/pull/4218)) +- Update sentry-sdk to 1.17.0 ([#4215](https://github.com/cookiecutter/cookiecutter-django/pull/4215)) +- Bump Docker python image from 3.10.9 to 3.10.10 on production Django ([#4214](https://github.com/cookiecutter/cookiecutter-django/pull/4214)) +- Bump Docker python image from 3.10.9-slim-bullseye to 3.10.10-slim-bullseye for docs ([#4213](https://github.com/cookiecutter/cookiecutter-django/pull/4213)) +- Bump Docker python image from 3.10.9-slim-bullseye to 3.10.10-slim-bullseye for local Django service ([#4212](https://github.com/cookiecutter/cookiecutter-django/pull/4212)) +- Update uvicorn to 0.21.1 ([#4211](https://github.com/cookiecutter/cookiecutter-django/pull/4211)) +- Update django-allauth to 0.53.0 ([#4210](https://github.com/cookiecutter/cookiecutter-django/pull/4210)) + +## 2023.03.14 + +### Updated +- Update django-celery-beat to 2.5.0 ([#4208](https://github.com/cookiecutter/cookiecutter-django/pull/4208)) + +## 2023.03.13 + +### Updated +- Update uvicorn to 0.21.0 ([#4203](https://github.com/cookiecutter/cookiecutter-django/pull/4203)) +- Update django-anymail to 9.1 ([#4206](https://github.com/cookiecutter/cookiecutter-django/pull/4206)) +- Update tox to 4.4.7 ([#4207](https://github.com/cookiecutter/cookiecutter-django/pull/4207)) + +## 2023.03.09 + +### Fixed +- Fix the omit configuration for coverage ([#4201](https://github.com/cookiecutter/cookiecutter-django/pull/4201)) +### Updated +- Update ipdb to 0.13.13 ([#4202](https://github.com/cookiecutter/cookiecutter-django/pull/4202)) + +## 2023.03.07 + +### Updated +- Update mypy to 1.1.1 ([#4196](https://github.com/cookiecutter/cookiecutter-django/pull/4196)) +- Update django-environ to 0.10.0 ([#4195](https://github.com/cookiecutter/cookiecutter-django/pull/4195)) + +## 2023.03.04 + +### Changed +- Add option to serve media files locally using nginx ([#2457](https://github.com/cookiecutter/cookiecutter-django/pull/2457)) +### Documentation +- Include contributing page to the docs ([#4144](https://github.com/cookiecutter/cookiecutter-django/pull/4144)) +### Updated +- Update myst-parser to 0.19.1 ([#4193](https://github.com/cookiecutter/cookiecutter-django/pull/4193)) +- Update pytest to 7.2.2 ([#4191](https://github.com/cookiecutter/cookiecutter-django/pull/4191)) +- Update drf-spectacular to 0.26.0 ([#4192](https://github.com/cookiecutter/cookiecutter-django/pull/4192)) + +## 2023.02.28 + +### Updated +- Update pre-commit to 3.1.1 ([#4188](https://github.com/cookiecutter/cookiecutter-django/pull/4188)) + +## 2023.02.27 + +### Updated +- Update sentry-sdk to 1.16.0 ([#4187](https://github.com/cookiecutter/cookiecutter-django/pull/4187)) + +## 2023.02.26 + +### Changed +- Fix readthedocs config file for generated project ([#4172](https://github.com/cookiecutter/cookiecutter-django/pull/4172)) +### Updated +- Bump traefik from v2.2.11 to 2.9.8 ([#4164](https://github.com/cookiecutter/cookiecutter-django/pull/4164)) +- Update coverage to 7.2.1 ([#4186](https://github.com/cookiecutter/cookiecutter-django/pull/4186)) + +## 2023.02.25 + +### Changed +- Run linting with pre-commit on GitLab ([#4150](https://github.com/cookiecutter/cookiecutter-django/pull/4150)) +### Fixed +- Disable caching for linter job on GitHub actions ([#4166](https://github.com/cookiecutter/cookiecutter-django/pull/4166)) +### Documentation +- Add instuction to run celery beat ([#4162](https://github.com/cookiecutter/cookiecutter-django/pull/4162)) +### Updated +- Bump garland/aws-cli-docker from 1.15.47 to 1.16.140 ([#4136](https://github.com/cookiecutter/cookiecutter-django/pull/4136)) +- Update djangorestframework-stubs to 1.9.1 ([#4184](https://github.com/cookiecutter/cookiecutter-django/pull/4184)) +- Update whitenoise to 6.4.0 ([#4180](https://github.com/cookiecutter/cookiecutter-django/pull/4180)) +- Update django-stubs to 1.15.0 ([#4183](https://github.com/cookiecutter/cookiecutter-django/pull/4183)) +- Update django-crispy-forms to 2.0 ([#4158](https://github.com/cookiecutter/cookiecutter-django/pull/4158)) +- Update django-cors-headers to 3.14.0 ([#4181](https://github.com/cookiecutter/cookiecutter-django/pull/4181)) +- Update python-slugify to 8.0.1 ([#4178](https://github.com/cookiecutter/cookiecutter-django/pull/4178)) +- Update pre-commit to 3.1.0 ([#4176](https://github.com/cookiecutter/cookiecutter-django/pull/4176)) +- Update mypy to 1.0.1 ([#4168](https://github.com/cookiecutter/cookiecutter-django/pull/4168)) +- Update werkzeug to 2.2.3 ([#4160](https://github.com/cookiecutter/cookiecutter-django/pull/4160)) +- Update coverage to 7.2.0 ([#4177](https://github.com/cookiecutter/cookiecutter-django/pull/4177)) +- Update django to 4.0.10 ([#4159](https://github.com/cookiecutter/cookiecutter-django/pull/4159)) +- Update hiredis to 2.2.2 ([#4156](https://github.com/cookiecutter/cookiecutter-django/pull/4156)) + +## 2023.02.17 + +### Changed +- Update version of github actions on the template project ([#4167](https://github.com/cookiecutter/cookiecutter-django/pull/4167)) + +## 2023.02.09 + +### Changed +- Remove unused pip cache paths in GHA & add a note for pre-commit.ci ([#4151](https://github.com/cookiecutter/cookiecutter-django/pull/4151)) +### Updated +- Update mypy to 0.991 ([#4106](https://github.com/cookiecutter/cookiecutter-django/pull/4106)) + +## 2023.02.08 + +### Updated +- Update sphinx to 6.1.3 ([#4148](https://github.com/cookiecutter/cookiecutter-django/pull/4148)) +- Update redis to 4.5.1 ([#4147](https://github.com/cookiecutter/cookiecutter-django/pull/4147)) + +## 2023.02.07 + +### Updated +- Bump postcss-preset-env from 7.8.3 to 8.0.1 ([#4115](https://github.com/cookiecutter/cookiecutter-django/pull/4115)) +- Bump sass-loader from 12.6.0 to 13.2.0 ([#4116](https://github.com/cookiecutter/cookiecutter-django/pull/4116)) +- Bump babel-loader from 8.3.0 to 9.1.2 ([#4117](https://github.com/cookiecutter/cookiecutter-django/pull/4117)) +- Bump postcss-loader from 6.2.1 to 7.0.2 ([#4114](https://github.com/cookiecutter/cookiecutter-django/pull/4114)) +- Bump webpack-cli from 4.10.0 to 5.0.1 ([#4118](https://github.com/cookiecutter/cookiecutter-django/pull/4118)) +- Update redis to 4.5.0 ([#4142](https://github.com/cookiecutter/cookiecutter-django/pull/4142)) +- Update sentry-sdk to 1.15.0 ([#4141](https://github.com/cookiecutter/cookiecutter-django/pull/4141)) + +## 2023.02.06 + +### Changed +- Change `RequestFactory` to `APIRequestFactory` in tests for API views ([#4110](https://github.com/cookiecutter/cookiecutter-django/pull/4110)) +### Fixed +- Fix django-webpack-loader setup when running tests ([#4128](https://github.com/cookiecutter/cookiecutter-django/pull/4128)) +### Documentation +- Added AWS ECS Full Deployment Article to README ([#2630](https://github.com/cookiecutter/cookiecutter-django/pull/2630)) +### Updated +- Update hiredis to 2.2.1 ([#4123](https://github.com/cookiecutter/cookiecutter-django/pull/4123)) +- Update tox to 4.4.4 ([#4133](https://github.com/cookiecutter/cookiecutter-django/pull/4133)) +- Update django to 4.0.9 ([#4134](https://github.com/cookiecutter/cookiecutter-django/pull/4134)) +- Update django-webpack-loader to 1.8.1 ([#4132](https://github.com/cookiecutter/cookiecutter-django/pull/4132)) + +## 2023.02.05 + +### Documentation +- Add note about which service to request when running locally with Docker & Webpack or Gulp ([#4130](https://github.com/cookiecutter/cookiecutter-django/pull/4130)) + +## 2023.02.03 + +### Updated +- Update pre-commit to 3.0.4 ([#4127](https://github.com/cookiecutter/cookiecutter-django/pull/4127)) + +## 2023.02.02 + +### Updated +- Update python-slugify to 8.0.0 ([#4111](https://github.com/cookiecutter/cookiecutter-django/pull/4111)) +- Update pre-commit to 3.0.3 ([#4121](https://github.com/cookiecutter/cookiecutter-django/pull/4121)) +- Update black to 23.1.0 ([#4120](https://github.com/cookiecutter/cookiecutter-django/pull/4120)) +- Update black pre-commit hook ([#4122](https://github.com/cookiecutter/cookiecutter-django/pull/4122)) + +## 2023.01.29 + +### Changed +- Add Webpack support ([#3623](https://github.com/cookiecutter/cookiecutter-django/pull/3623)) +- Remove `BrokenLinkEmailsMiddleware` ([#4112](https://github.com/cookiecutter/cookiecutter-django/pull/4112)) + +## 2023.01.28 + +### Changed +- Refactor `merge_production_dotenvs_in_dotenv.py` ([#4105](https://github.com/cookiecutter/cookiecutter-django/pull/4105)) +### Updated +- Update isort to 5.12.0 ([#4109](https://github.com/cookiecutter/cookiecutter-django/pull/4109)) +- Auto-update pre-commit hooks ([#4108](https://github.com/cookiecutter/cookiecutter-django/pull/4108)) + +## 2023.01.27 + +### Updated +- Update django-stubs to 1.14.0 ([#4103](https://github.com/cookiecutter/cookiecutter-django/pull/4103)) + +## 2023.01.26 + +### Changed +- Rename BASE_DIR_PATH to BASE_DIR ([#4102](https://github.com/cookiecutter/cookiecutter-django/pull/4102)) +### Updated +- Update pre-commit to 3.0.1 ([#4104](https://github.com/cookiecutter/cookiecutter-django/pull/4104)) +- Update tox to 4.4.2 ([#4101](https://github.com/cookiecutter/cookiecutter-django/pull/4101)) + +## 2023.01.25 + +### Changed +- Rename ROOT_DIR to BASE_DIR ([#4086](https://github.com/cookiecutter/cookiecutter-django/pull/4086)) +- Update postgres and redis to point to mini tiers ([#4099](https://github.com/cookiecutter/cookiecutter-django/pull/4099)) +### Updated +- Update coverage to 7.1.0 ([#4100](https://github.com/cookiecutter/cookiecutter-django/pull/4100)) + +## 2023.01.24 + +### Updated +- Update pre-commit to 3.0.0 ([#4098](https://github.com/cookiecutter/cookiecutter-django/pull/4098)) + +## 2023.01.23 + +### Updated +- Update sentry-sdk to 1.14.0 ([#4096](https://github.com/cookiecutter/cookiecutter-django/pull/4096)) + +## 2023.01.22 + +### Updated +- Update django-compressor to 4.3.1 ([#4094](https://github.com/cookiecutter/cookiecutter-django/pull/4094)) + +## 2023.01.21 + +### Updated +- Update django-stubs to 1.13.2 ([#4093](https://github.com/cookiecutter/cookiecutter-django/pull/4093)) + +## 2023.01.19 + +### Fixed +- Add sourcemaps support to Gulp ([#4089](https://github.com/cookiecutter/cookiecutter-django/pull/4089)) +### Updated +- Update coverage to 7.0.5 ([#4092](https://github.com/cookiecutter/cookiecutter-django/pull/4092)) +- Update redis to 4.4.2 ([#4091](https://github.com/cookiecutter/cookiecutter-django/pull/4091)) +- Update requests to 2.28.2 ([#4090](https://github.com/cookiecutter/cookiecutter-django/pull/4090)) +- Update tox to 4.3.5 ([#4087](https://github.com/cookiecutter/cookiecutter-django/pull/4087)) + +## 2023.01.17 + +### Updated +- Update tox to 4.3.3 ([#4081](https://github.com/cookiecutter/cookiecutter-django/pull/4081)) + +## 2023.01.15 + +### Updated +- Update pytest to 7.2.1 ([#4077](https://github.com/cookiecutter/cookiecutter-django/pull/4077)) +- Update pytz to 2022.7.1 ([#4078](https://github.com/cookiecutter/cookiecutter-django/pull/4078)) + +## 2023.01.12 + +### Updated +- Update sentry-sdk to 1.13.0 ([#4074](https://github.com/cookiecutter/cookiecutter-django/pull/4074)) + +## 2023.01.11 + +### Changed +- Update Celery instructions in the documentation ([#4061](https://github.com/cookiecutter/cookiecutter-django/pull/4061)) +### Updated +- Update tox to 4.2.7 ([#4073](https://github.com/cookiecutter/cookiecutter-django/pull/4073)) + +## 2023.01.10 + +### Changed +- Add dump.rdb to gitignore ([#4062](https://github.com/cookiecutter/cookiecutter-django/pull/4062)) +### Fixed +- Exclude `.venv` from code style checks ([#4069](https://github.com/cookiecutter/cookiecutter-django/pull/4069)) +### Updated +- Update hiredis to 2.1.1 ([#4070](https://github.com/cookiecutter/cookiecutter-django/pull/4070)) + +## 2023.01.08 + +### Updated +- Update redis to 4.4.1 ([#4068](https://github.com/cookiecutter/cookiecutter-django/pull/4068)) +- Update coverage to 7.0.4 ([#4067](https://github.com/cookiecutter/cookiecutter-django/pull/4067)) + +## 2023.01.07 + +### Updated +- Update tox to 4.2.6 ([#4064](https://github.com/cookiecutter/cookiecutter-django/pull/4064)) +- Update django-storages to 1.13.2 ([#4057](https://github.com/cookiecutter/cookiecutter-django/pull/4057)) +- Update isort to 5.11.4 ([#4058](https://github.com/cookiecutter/cookiecutter-django/pull/4058)) +- Update rcssmin to 1.1.1 ([#4060](https://github.com/cookiecutter/cookiecutter-django/pull/4060)) +- Update django-compressor to 4.3 ([#4063](https://github.com/cookiecutter/cookiecutter-django/pull/4063)) + +## 2023.01.06 + +### Changed +- Add `.git` to `.dockerignore` ([#4054](https://github.com/cookiecutter/cookiecutter-django/pull/4054)) +- Fix link and add non-Docker commands to testing page in the docs ([#4036](https://github.com/cookiecutter/cookiecutter-django/pull/4036)) +### Updated +- Update tox to 4.2.3 ([#4051](https://github.com/cookiecutter/cookiecutter-django/pull/4051)) + +## 2023.01.04 + +### Changed +- Fix typo on test settings ([#4049](https://github.com/cookiecutter/cookiecutter-django/pull/4049)) +### Updated +- Update tox to 4.2.2 ([#4050](https://github.com/cookiecutter/cookiecutter-django/pull/4050)) +- Update tox to 4.2.1 ([#4046](https://github.com/cookiecutter/cookiecutter-django/pull/4046)) +- Update coverage to 7.0.3 ([#4047](https://github.com/cookiecutter/cookiecutter-django/pull/4047)) + +## 2023.01.03 + +### Updated +- Update flake8-isort to 6.0.0 ([#4022](https://github.com/cookiecutter/cookiecutter-django/pull/4022)) +- Update tox to 4.1.3 ([#4041](https://github.com/cookiecutter/cookiecutter-django/pull/4041)) +- Update pillow to 9.4.0 ([#4040](https://github.com/cookiecutter/cookiecutter-django/pull/4040)) +- Update gitpython to 3.1.30 ([#4032](https://github.com/cookiecutter/cookiecutter-django/pull/4032)) +- Update coverage to 7.0.2 ([#4042](https://github.com/cookiecutter/cookiecutter-django/pull/4042)) +- Update whitenoise to 6.3.0 ([#4044](https://github.com/cookiecutter/cookiecutter-django/pull/4044)) + +## 2022.12.29 + +### Updated +- Update tox to 4.1.0 ([#4035](https://github.com/cookiecutter/cookiecutter-django/pull/4035)) +- Update tox to 4.0.19 ([#4030](https://github.com/cookiecutter/cookiecutter-django/pull/4030)) +- Update django-allauth to 0.52.0 ([#4033](https://github.com/cookiecutter/cookiecutter-django/pull/4033)) + +## 2022.12.26 + +### Updated +- Update tox to 4.0.17 ([#4027](https://github.com/cookiecutter/cookiecutter-django/pull/4027)) +- Update pre-commit to 2.21.0 ([#4026](https://github.com/cookiecutter/cookiecutter-django/pull/4026)) + +## 2022.12.25 + +### Updated +- Auto-update pre-commit hooks ([#4021](https://github.com/cookiecutter/cookiecutter-django/pull/4021)) + +## 2022.12.24 + +### Updated +- Update coverage to 7.0.1 ([#4024](https://github.com/cookiecutter/cookiecutter-django/pull/4024)) + +## 2022.12.21 + +### Changed +- Retry when trying to store a Celery result in backend ([#3996](https://github.com/cookiecutter/cookiecutter-django/pull/3996)) +- Update image URL for build status shield badge ([#4018](https://github.com/cookiecutter/cookiecutter-django/pull/4018)) +### Updated +- Update pytz to 2022.7 ([#4020](https://github.com/cookiecutter/cookiecutter-django/pull/4020)) +- Update ipdb to 0.13.11 ([#4019](https://github.com/cookiecutter/cookiecutter-django/pull/4019)) +- Update tox to 4.0.16 ([#4017](https://github.com/cookiecutter/cookiecutter-django/pull/4017)) +- Update sentry-sdk to 1.12.1 ([#4014](https://github.com/cookiecutter/cookiecutter-django/pull/4014)) +- Update coverage to 7.0.0 ([#4013](https://github.com/cookiecutter/cookiecutter-django/pull/4013)) +- Update django-anymail to 9.0 ([#4012](https://github.com/cookiecutter/cookiecutter-django/pull/4012)) +- Auto-update pre-commit hooks ([#4005](https://github.com/cookiecutter/cookiecutter-django/pull/4005)) +- Update isort to 5.11.3 ([#4010](https://github.com/cookiecutter/cookiecutter-django/pull/4010)) +- Update drf-spectacular to 0.25.1 ([#4009](https://github.com/cookiecutter/cookiecutter-django/pull/4009)) +- Update hiredis to 2.1.0 ([#4006](https://github.com/cookiecutter/cookiecutter-django/pull/4006)) + +## 2022.12.13 + +### Changed +- Improve documentation for Getting started with Docker ([#4003](https://github.com/cookiecutter/cookiecutter-django/pull/4003)) +### Updated +- Update isort to 5.11.1 ([#3999](https://github.com/cookiecutter/cookiecutter-django/pull/3999)) +- Auto-update pre-commit hooks ([#3998](https://github.com/cookiecutter/cookiecutter-django/pull/3998)) +- Update isort to 5.11.0 ([#3997](https://github.com/cookiecutter/cookiecutter-django/pull/3997)) + +## 2022.12.10 + +### Updated +- Update tox to 4.0.5 ([#3993](https://github.com/cookiecutter/cookiecutter-django/pull/3993)) +- Auto-update pre-commit hooks ([#3991](https://github.com/cookiecutter/cookiecutter-django/pull/3991)) + +## 2022.12.09 + +### Changed +- Remove bind option mounts for docker compose volumes ([#3981](https://github.com/cookiecutter/cookiecutter-django/pull/3981)) +### Updated +- Update djangorestframework-stubs to 1.8.0 ([#3990](https://github.com/cookiecutter/cookiecutter-django/pull/3990)) +- Update black to 22.12.0 ([#3988](https://github.com/cookiecutter/cookiecutter-django/pull/3988)) + +## 2022.12.08 + +### Updated +- Update tox to 4.0.3 ([#3987](https://github.com/cookiecutter/cookiecutter-django/pull/3987)) +- Update tox to 4.0.2 ([#3985](https://github.com/cookiecutter/cookiecutter-django/pull/3985)) +- Update django-stubs to 1.13.1 ([#3986](https://github.com/cookiecutter/cookiecutter-django/pull/3986)) + +## 2022.12.07 + +### Updated +- Auto-update pre-commit hooks ([#3983](https://github.com/cookiecutter/cookiecutter-django/pull/3983)) + +## 2022.12.06 + +### Changed +- Simplify production `DATABASES` setting to extend base definition ([#3969](https://github.com/cookiecutter/cookiecutter-django/pull/3969)) +### Fixed +- Only set `SERVERS` for `drf-spectacular` in production ([#3609](https://github.com/cookiecutter/cookiecutter-django/pull/3609)) +### Updated +- Update django-coverage-plugin to 3.0.0 ([#3979](https://github.com/cookiecutter/cookiecutter-django/pull/3979)) +- Bump stefanzweifel/git-auto-commit-action from 4.15.4 to 4.16.0 ([#3978](https://github.com/cookiecutter/cookiecutter-django/pull/3978)) + +## 2022.12.04 + +### Updated +- Update redis to 4.4.0 ([#3977](https://github.com/cookiecutter/cookiecutter-django/pull/3977)) +- Update django-debug-toolbar to 3.8.1 ([#3976](https://github.com/cookiecutter/cookiecutter-django/pull/3976)) + +## 2022.12.03 + +### Updated +- Auto-update pre-commit hooks ([#3975](https://github.com/cookiecutter/cookiecutter-django/pull/3975)) + +## 2022.12.02 + +### Updated +- Update flake8 to 6.0.0 ([#3974](https://github.com/cookiecutter/cookiecutter-django/pull/3974)) + +## 2022.11.30 + +### Changed +- Add Azure Storage as an option to serve static and media files ([#3967](https://github.com/cookiecutter/cookiecutter-django/pull/3967)) +### Updated +- Auto-update pre-commit hooks ([#3970](https://github.com/cookiecutter/cookiecutter-django/pull/3970)) + +## 2022.11.26 + +### Changed +- Fix typo in flower start for watching celery ([#3966](https://github.com/cookiecutter/cookiecutter-django/pull/3966)) + +## 2022.11.24 + +### Updated +- Auto-update pre-commit hooks ([#3963](https://github.com/cookiecutter/cookiecutter-django/pull/3963)) + +## 2022.11.23 + +### Changed +- Fix graceful shutdown of local dev containers and use watchfiles for beat + flower ([#3925](https://github.com/cookiecutter/cookiecutter-django/pull/3925)) +- feat(celery): Enable sending the sent task event by default ([#3961](https://github.com/cookiecutter/cookiecutter-django/pull/3961)) +### Updated +- Bump stefanzweifel/git-auto-commit-action from 4.15.3 to 4.15.4 ([#3940](https://github.com/cookiecutter/cookiecutter-django/pull/3940)) +- Update django-model-utils to 4.3.1 ([#3948](https://github.com/cookiecutter/cookiecutter-django/pull/3948)) +- Update flake8-isort to 5.0.3 ([#3952](https://github.com/cookiecutter/cookiecutter-django/pull/3952)) + +## 2022.11.22 + +### Changed +- Remove USE_L10N due to deprecation ([#3960](https://github.com/cookiecutter/cookiecutter-django/pull/3960)) +- Remove platform from compose file ([#3957](https://github.com/cookiecutter/cookiecutter-django/pull/3957)) +- feat(celery): Send task events for Celery by default ([#3959](https://github.com/cookiecutter/cookiecutter-django/pull/3959)) +### Updated +- Update python-slugify to 7.0.0 ([#3950](https://github.com/cookiecutter/cookiecutter-django/pull/3950)) +- Update redis to 4.3.5 ([#3954](https://github.com/cookiecutter/cookiecutter-django/pull/3954)) +- Update sentry-sdk to 1.11.1 ([#3955](https://github.com/cookiecutter/cookiecutter-django/pull/3955)) +- Update uvicorn to 0.20.0 ([#3953](https://github.com/cookiecutter/cookiecutter-django/pull/3953)) +- Update tox to 3.27.1 ([#3945](https://github.com/cookiecutter/cookiecutter-django/pull/3945)) + +## 2022.11.11 + +### Updated +- Auto-update pre-commit hooks ([#3942](https://github.com/cookiecutter/cookiecutter-django/pull/3942)) + +## 2022.11.07 + +### Updated +- Update watchfiles to 0.18.1 ([#3938](https://github.com/cookiecutter/cookiecutter-django/pull/3938)) + +## 2022.11.06 + +### Changed +- Store extended Celery task attributes in backend ([#3855](https://github.com/cookiecutter/cookiecutter-django/pull/3855)) +- add os requirements for Ubuntu 22.04 (Jammy) ([#3930](https://github.com/cookiecutter/cookiecutter-django/pull/3930)) +### Updated +- Update pytest-sugar to 0.9.6 ([#3937](https://github.com/cookiecutter/cookiecutter-django/pull/3937)) +- Update pygithub to 1.57 ([#3936](https://github.com/cookiecutter/cookiecutter-django/pull/3936)) +- Update sphinx-rtd-theme to 1.1.1 ([#3935](https://github.com/cookiecutter/cookiecutter-django/pull/3935)) + +## 2022.11.02 + +### Changed +- fix typo in CONTRIBUTING.md ([#3932](https://github.com/cookiecutter/cookiecutter-django/pull/3932)) +### Updated +- Update crispy-bootstrap5 to 0.7 ([#3886](https://github.com/cookiecutter/cookiecutter-django/pull/3886)) +- Update django-coverage-plugin to 2.0.4 ([#3927](https://github.com/cookiecutter/cookiecutter-django/pull/3927)) +- Update pytz to 2022.6 ([#3928](https://github.com/cookiecutter/cookiecutter-django/pull/3928)) +- Update sphinx-rtd-theme to 1.1.0 ([#3929](https://github.com/cookiecutter/cookiecutter-django/pull/3929)) +- Update pillow to 9.3.0 ([#3922](https://github.com/cookiecutter/cookiecutter-django/pull/3922)) + +## 2022.10.30 + +### Updated +- Auto-update pre-commit hooks ([#3924](https://github.com/cookiecutter/cookiecutter-django/pull/3924)) + +## 2022.10.28 + +### Updated +- Bump stefanzweifel/git-auto-commit-action from 4.15.2 to 4.15.3 ([#3921](https://github.com/cookiecutter/cookiecutter-django/pull/3921)) + +## 2022.10.26 + +### Updated +- Update uvicorn to 0.19.0 ([#3920](https://github.com/cookiecutter/cookiecutter-django/pull/3920)) +- Update pytest to 7.2.0 ([#3919](https://github.com/cookiecutter/cookiecutter-django/pull/3919)) +- Update tox to 3.27.0 ([#3917](https://github.com/cookiecutter/cookiecutter-django/pull/3917)) +- Update psycopg2 to 2.9.5 ([#3918](https://github.com/cookiecutter/cookiecutter-django/pull/3918)) + +## 2022.10.24 + +### Changed +- Upgrade Python version from 3.9 to 3.10 ([#3913](https://github.com/cookiecutter/cookiecutter-django/pull/3913)) +### Updated +- Update sentry-sdk to 1.10.1 ([#3911](https://github.com/cookiecutter/cookiecutter-django/pull/3911)) +- Bump stefanzweifel/git-auto-commit-action from 4.15.1 to 4.15.2 ([#3914](https://github.com/cookiecutter/cookiecutter-django/pull/3914)) + +## 2022.10.19 + +### Changed +- Set AWS_S3_MAX_MEMORY_SIZE ([#3810](https://github.com/cookiecutter/cookiecutter-django/pull/3810)) +- Upgrade to Django 4.0 ([#3848](https://github.com/cookiecutter/cookiecutter-django/pull/3848)) +### Updated +- Update pytz to 2022.5 ([#3906](https://github.com/cookiecutter/cookiecutter-django/pull/3906)) +- Update sphinx to 5.3.0 ([#3905](https://github.com/cookiecutter/cookiecutter-django/pull/3905)) +- Update django-celery-beat to 2.4.0 ([#3908](https://github.com/cookiecutter/cookiecutter-django/pull/3908)) +- Update watchfiles to 0.18.0 ([#3907](https://github.com/cookiecutter/cookiecutter-django/pull/3907)) + +## 2022.10.13 + +### Updated +- Update pygithub to 1.56 ([#3904](https://github.com/cookiecutter/cookiecutter-django/pull/3904)) + +## 2022.10.11 + +### Updated +- Auto-update pre-commit hooks ([#3899](https://github.com/cookiecutter/cookiecutter-django/pull/3899)) +- Update flake8-isort to 5.0.0 ([#3901](https://github.com/cookiecutter/cookiecutter-django/pull/3901)) +- Update gitpython to 3.1.29 ([#3902](https://github.com/cookiecutter/cookiecutter-django/pull/3902)) +- Update psycopg2 to 2.9.4 ([#3896](https://github.com/cookiecutter/cookiecutter-django/pull/3896)) +- Bump stefanzweifel/git-auto-commit-action from 4.15.0 to 4.15.1 ([#3903](https://github.com/cookiecutter/cookiecutter-django/pull/3903)) +- Update black to 22.10.0 ([#3898](https://github.com/cookiecutter/cookiecutter-django/pull/3898)) + +## 2022.10.04 + +### Updated +- Update django to 3.2.16 ([#3895](https://github.com/cookiecutter/cookiecutter-django/pull/3895)) +- Update mypy to 0.982 ([#3893](https://github.com/cookiecutter/cookiecutter-django/pull/3893)) +- Auto-update pre-commit hooks ([#3894](https://github.com/cookiecutter/cookiecutter-django/pull/3894)) + +## 2022.10.03 + +### Updated +- Update sentry-sdk to 1.9.10 ([#3892](https://github.com/cookiecutter/cookiecutter-django/pull/3892)) + +## 2022.10.02 + +### Updated +- Update pytz to 2022.4 ([#3891](https://github.com/cookiecutter/cookiecutter-django/pull/3891)) + +## 2022.09.30 + +### Updated +- Update coverage to 6.5.0 ([#3890](https://github.com/cookiecutter/cookiecutter-django/pull/3890)) +- Update mypy to 0.981 ([#3889](https://github.com/cookiecutter/cookiecutter-django/pull/3889)) +- Update sentry-sdk to 1.9.9 ([#3888](https://github.com/cookiecutter/cookiecutter-django/pull/3888)) +- Update sphinx to 5.2.3 ([#3887](https://github.com/cookiecutter/cookiecutter-django/pull/3887)) + +## 2022.09.29 + +### Changed +- Remove outdated & optional Sendgrid settings from production config ([#3885](https://github.com/cookiecutter/cookiecutter-django/pull/3885)) + +## 2022.09.27 + +### Updated +- Update sphinx to 5.2.2 ([#3884](https://github.com/cookiecutter/cookiecutter-django/pull/3884)) + +## 2022.09.26 + +### Updated +- Update drf-spectacular to 0.24.2 ([#3882](https://github.com/cookiecutter/cookiecutter-django/pull/3882)) +- Update djangorestframework to 3.14.0 ([#3881](https://github.com/cookiecutter/cookiecutter-django/pull/3881)) +- Update django-debug-toolbar to 3.7.0 ([#3878](https://github.com/cookiecutter/cookiecutter-django/pull/3878)) +- Auto-update pre-commit hooks ([#3877](https://github.com/cookiecutter/cookiecutter-django/pull/3877)) +- Bump stefanzweifel/git-auto-commit-action from 4.14.1 to 4.15.0 ([#3880](https://github.com/cookiecutter/cookiecutter-django/pull/3880)) +- Update sphinx to 5.2.1 ([#3879](https://github.com/cookiecutter/cookiecutter-django/pull/3879)) + +## 2022.09.24 + +### Fixed +- Remove `--no-deps` in pip wheels command of docs Dockerfile ([#3875](https://github.com/cookiecutter/cookiecutter-django/pull/3875)) + +## 2022.09.23 + +### Changed +- Reload uvicorn on html file change ([#3866](https://github.com/cookiecutter/cookiecutter-django/pull/3866)) +- Mailjet default api url does not work out of the box ([#3871](https://github.com/cookiecutter/cookiecutter-django/pull/3871)) +### Updated +- Auto-update pre-commit hooks ([#3872](https://github.com/cookiecutter/cookiecutter-django/pull/3872)) +- Update django-extensions to 3.2.1 ([#3867](https://github.com/cookiecutter/cookiecutter-django/pull/3867)) +- Update tox to 3.26.0 ([#3864](https://github.com/cookiecutter/cookiecutter-django/pull/3864)) +- Update drf-spectacular to 0.24.1 ([#3874](https://github.com/cookiecutter/cookiecutter-django/pull/3874)) + +## 2022.09.15 + +### Updated +- Update watchfiles to 0.17.0 ([#3869](https://github.com/cookiecutter/cookiecutter-django/pull/3869)) +- Update drf-spectacular to 0.24.0 ([#3870](https://github.com/cookiecutter/cookiecutter-django/pull/3870)) + +## 2022.09.05 + +### Updated +- Update sentry-sdk to 1.9.8 ([#3861](https://github.com/cookiecutter/cookiecutter-django/pull/3861)) + +## 2022.09.02 + +### Updated +- Update pytest to 7.1.3 ([#3860](https://github.com/cookiecutter/cookiecutter-django/pull/3860)) +- Update sentry-sdk to 1.9.7 ([#3859](https://github.com/cookiecutter/cookiecutter-django/pull/3859)) + +## 2022.09.01 + +### Changed +- Add article to README about how to use a hosted DB ([#3844](https://github.com/cookiecutter/cookiecutter-django/pull/3844)) +### Updated +- Update sentry-sdk to 1.9.6 ([#3856](https://github.com/cookiecutter/cookiecutter-django/pull/3856)) +- Auto-update pre-commit hooks ([#3858](https://github.com/cookiecutter/cookiecutter-django/pull/3858)) +- Update black to 22.8.0 ([#3857](https://github.com/cookiecutter/cookiecutter-django/pull/3857)) + +## 2022.08.26 + +### Changed +- Fix formatting in docs ([#3850](https://github.com/cookiecutter/cookiecutter-django/pull/3850)) + +## 2022.08.24 + +### Updated +- Update django-debug-toolbar to 3.6.0 ([#3847](https://github.com/cookiecutter/cookiecutter-django/pull/3847)) +- Update werkzeug to 2.2.2 ([#3846](https://github.com/cookiecutter/cookiecutter-django/pull/3846)) +- Update coverage to 6.4.4 ([#3842](https://github.com/cookiecutter/cookiecutter-django/pull/3842)) +- Update uvicorn to 0.18.3 ([#3845](https://github.com/cookiecutter/cookiecutter-django/pull/3845)) +- Update sentry-sdk to 1.9.5 ([#3841](https://github.com/cookiecutter/cookiecutter-django/pull/3841)) +- Update flower to 1.2.0 ([#3836](https://github.com/cookiecutter/cookiecutter-django/pull/3836)) +- Update django-storages to 1.13.1 ([#3833](https://github.com/cookiecutter/cookiecutter-django/pull/3833)) + +## 2022.08.15 + +### Updated +- Update coverage to 6.4.3 ([#3835](https://github.com/cookiecutter/cookiecutter-django/pull/3835)) +- Update pytz to 2022.2.1 ([#3840](https://github.com/cookiecutter/cookiecutter-django/pull/3840)) +- Update sentry-sdk to 1.9.4 ([#3838](https://github.com/cookiecutter/cookiecutter-django/pull/3838)) + +## 2022.08.09 + +### Updated +- Update sentry-sdk to 1.9.3 ([#3837](https://github.com/cookiecutter/cookiecutter-django/pull/3837)) + +## 2022.08.05 + +### Updated +- Update sentry-sdk to 1.9.2 ([#3832](https://github.com/cookiecutter/cookiecutter-django/pull/3832)) + +## 2022.08.04 + +### Updated +- Auto-update pre-commit hooks ([#3816](https://github.com/cookiecutter/cookiecutter-django/pull/3816)) +- Update flake8 to 5.0.4 ([#3829](https://github.com/cookiecutter/cookiecutter-django/pull/3829)) +- Update django-compressor to 4.1 ([#3823](https://github.com/cookiecutter/cookiecutter-django/pull/3823)) +- Update flake8-isort to 4.2.0 ([#3828](https://github.com/cookiecutter/cookiecutter-django/pull/3828)) + +## 2022.08.03 + +### Updated +- Update django to 3.2.15 ([#3822](https://github.com/cookiecutter/cookiecutter-django/pull/3822)) + +## 2022.07.29 + +### Updated +- Update sentry-sdk to 1.9.0 ([#3815](https://github.com/cookiecutter/cookiecutter-django/pull/3815)) + +## 2022.07.28 + +### Updated +- Update werkzeug to 2.2.1 ([#3814](https://github.com/cookiecutter/cookiecutter-django/pull/3814)) + +## 2022.07.27 + +### Updated +- Update werkzeug to 2.2.0 ([#3813](https://github.com/cookiecutter/cookiecutter-django/pull/3813)) +- Update sphinx to 5.1.1 ([#3811](https://github.com/cookiecutter/cookiecutter-django/pull/3811)) +- Update drf-spectacular to 0.23.1 ([#3812](https://github.com/cookiecutter/cookiecutter-django/pull/3812)) + +## 2022.07.26 + +### Changed +- Switch from `watchgod` to `watchfiles` ([#3791](https://github.com/cookiecutter/cookiecutter-django/pull/3791)) +- Change Django settings file used by pylint ([#3806](https://github.com/cookiecutter/cookiecutter-django/pull/3806)) +- Simplify database access in tests ([#3807](https://github.com/cookiecutter/cookiecutter-django/pull/3807)) +- Provide more context when wating for PostgreSQL takes too long ([#3782](https://github.com/cookiecutter/cookiecutter-django/pull/3782)) +### Updated +- Update django-compressor to 4.0 ([#3802](https://github.com/cookiecutter/cookiecutter-django/pull/3802)) +- Update flake8-isort to 4.1.2.post0 ([#3809](https://github.com/cookiecutter/cookiecutter-django/pull/3809)) +- Update sphinx to 5.1.0 ([#3808](https://github.com/cookiecutter/cookiecutter-django/pull/3808)) +- Update sh to 1.14.3 ([#3798](https://github.com/cookiecutter/cookiecutter-django/pull/3798)) +- Auto-update pre-commit hooks ([#3780](https://github.com/cookiecutter/cookiecutter-django/pull/3780)) + +## 2022.07.22 + +### Updated +- Update pytest-sugar to 0.9.5 ([#3800](https://github.com/cookiecutter/cookiecutter-django/pull/3800)) +- Update sphinx to 5.0.2 ([#3801](https://github.com/cookiecutter/cookiecutter-django/pull/3801)) +- Update pillow to 9.2.0 ([#3799](https://github.com/cookiecutter/cookiecutter-django/pull/3799)) +- Update werkzeug to 2.1.2 ([#3797](https://github.com/cookiecutter/cookiecutter-django/pull/3797)) + +## 2022.07.21 + +### Changed +- Set user to form instance in update user view test ([#3776](https://github.com/cookiecutter/cookiecutter-django/pull/3776)) +- Fix warning from django-coverage-plugin in tests ([#3790](https://github.com/cookiecutter/cookiecutter-django/pull/3790)) +- Always use `const` instead of `var` in `gulpfile.js` ([#3786](https://github.com/cookiecutter/cookiecutter-django/pull/3786)) +### Updated +- Update flower to 1.1.0 ([#3796](https://github.com/cookiecutter/cookiecutter-django/pull/3796)) +- Update coverage to 6.4.2 ([#3783](https://github.com/cookiecutter/cookiecutter-django/pull/3783)) +- Update mypy to 0.971 ([#3788](https://github.com/cookiecutter/cookiecutter-django/pull/3788)) +- Update sentry-sdk to 1.8.0 ([#3792](https://github.com/cookiecutter/cookiecutter-django/pull/3792)) +- Update pre-commit to 2.20.0 ([#3779](https://github.com/cookiecutter/cookiecutter-django/pull/3779)) +- Update django-extensions to 3.2.0 ([#3774](https://github.com/cookiecutter/cookiecutter-django/pull/3774)) +- Update tox to 3.25.1 ([#3767](https://github.com/cookiecutter/cookiecutter-django/pull/3767)) +- Update uvicorn to 0.18.2 ([#3762](https://github.com/cookiecutter/cookiecutter-django/pull/3762)) +- Update redis to 4.3.4 ([#3763](https://github.com/cookiecutter/cookiecutter-django/pull/3763)) +- Update requests to 2.28.1 ([#3766](https://github.com/cookiecutter/cookiecutter-django/pull/3766)) + +## 2022.07.10 + +### Changed +- Revert auto-update pre-commit hooks ([#3778](https://github.com/cookiecutter/cookiecutter-django/pull/3778)) +### Updated +- Auto-update pre-commit hooks ([#3775](https://github.com/cookiecutter/cookiecutter-django/pull/3775)) + +## 2022.07.06 + +### Updated +- Update django to 3.2.14 ([#3768](https://github.com/cookiecutter/cookiecutter-django/pull/3768)) + +## 2022.06.28 + +### Updated +- Auto-update pre-commit hooks ([#3765](https://github.com/cookiecutter/cookiecutter-django/pull/3765)) +- Update black to 22.6.0 ([#3764](https://github.com/cookiecutter/cookiecutter-django/pull/3764)) + +## 2022.06.23 + +### Updated +- Update django-debug-toolbar to 3.5.0 ([#3760](https://github.com/cookiecutter/cookiecutter-django/pull/3760)) + +## 2022.06.22 + +### Updated +- Update django-stubs to 1.12.0 ([#3757](https://github.com/cookiecutter/cookiecutter-django/pull/3757)) +- Update sentry-sdk to 1.6.0 ([#3756](https://github.com/cookiecutter/cookiecutter-django/pull/3756)) +- Update djangorestframework-stubs to 1.7.0 ([#3754](https://github.com/cookiecutter/cookiecutter-django/pull/3754)) + +## 2022.06.15 + +### Updated +- Update django-environ to 0.9.0 ([#3751](https://github.com/cookiecutter/cookiecutter-django/pull/3751)) + +## 2022.06.13 + +### Updated +- Update cookiecutter to 2.1.1 ([#3727](https://github.com/cookiecutter/cookiecutter-django/pull/3727)) + +## 2022.06.11 + +### Updated +- Update requests to 2.28.0 ([#3748](https://github.com/cookiecutter/cookiecutter-django/pull/3748)) + +## 2022.06.09 + +### Updated +- Bump actions/setup-python from 3 to 4 ([#3746](https://github.com/cookiecutter/cookiecutter-django/pull/3746)) + +## 2022.06.08 + +### Updated +- Auto-update pre-commit hooks ([#3744](https://github.com/cookiecutter/cookiecutter-django/pull/3744)) + +## 2022.06.07 + +### Updated +- Update django-allauth to 0.51.0 ([#3743](https://github.com/cookiecutter/cookiecutter-django/pull/3743)) +- Auto-update pre-commit hooks ([#3742](https://github.com/cookiecutter/cookiecutter-django/pull/3742)) + +## 2022.06.06 + +### Updated +- Bump pre-commit/action from 2.0.3 to 3.0.0 ([#3739](https://github.com/cookiecutter/cookiecutter-django/pull/3739)) + +## 2022.06.05 + +### Updated +- Update whitenoise to 6.2.0 ([#3737](https://github.com/cookiecutter/cookiecutter-django/pull/3737)) +- Update django-cors-headers to 3.13.0 ([#3738](https://github.com/cookiecutter/cookiecutter-django/pull/3738)) + +## 2022.06.04 + +### Updated +- Update django-cors-headers to 3.12.0 ([#3736](https://github.com/cookiecutter/cookiecutter-django/pull/3736)) +- Update djangorestframework-stubs to 1.6.0 ([#3718](https://github.com/cookiecutter/cookiecutter-django/pull/3718)) +- Update django-stubs to 1.11.0 ([#3734](https://github.com/cookiecutter/cookiecutter-django/pull/3734)) +- Update sphinx to 5.0.1 ([#3733](https://github.com/cookiecutter/cookiecutter-django/pull/3733)) +- Update sphinx to 5.0.0 ([#3724](https://github.com/cookiecutter/cookiecutter-django/pull/3724)) +- Update celery to 5.2.7 ([#3732](https://github.com/cookiecutter/cookiecutter-django/pull/3732)) +- Update django-celery-beat to 2.3.0 ([#3731](https://github.com/cookiecutter/cookiecutter-django/pull/3731)) + +## 2022.06.02 + +### Updated +- Update coverage to 6.4.1 ([#3729](https://github.com/cookiecutter/cookiecutter-django/pull/3729)) +- Update redis to 4.3.3 ([#3728](https://github.com/cookiecutter/cookiecutter-django/pull/3728)) + +## 2022.06.01 + +### Updated +- Update redis to 4.3.2 ([#3726](https://github.com/cookiecutter/cookiecutter-django/pull/3726)) + +## 2022.05.24 + +### Updated +- Update coverage to 6.4 ([#3716](https://github.com/cookiecutter/cookiecutter-django/pull/3716)) + +## 2022.05.18 + +### Updated +- Update pillow to 9.1.1 ([#3714](https://github.com/cookiecutter/cookiecutter-django/pull/3714)) + +## 2022.05.16 + +### Changed +- Update postgres versions ([#3712](https://github.com/cookiecutter/cookiecutter-django/pull/3712)) +### Updated +- Update django-anymail to 8.6 ([#3713](https://github.com/cookiecutter/cookiecutter-django/pull/3713)) + +## 2022.05.14 + +### Updated +- Update coverage to 6.3.3 ([#3709](https://github.com/cookiecutter/cookiecutter-django/pull/3709)) +- Update whitenoise to 6.1.0 ([#3707](https://github.com/cookiecutter/cookiecutter-django/pull/3707)) +- Update sentry-sdk to 1.5.12 ([#3706](https://github.com/cookiecutter/cookiecutter-django/pull/3706)) +- Update redis to 4.3.1 ([#3704](https://github.com/cookiecutter/cookiecutter-django/pull/3704)) + +## 2022.05.07 + +### Changed +- Add pyupgrade to pre-commit config ([#3702](https://github.com/cookiecutter/cookiecutter-django/pull/3702)) +- Set permissions for GitHub actions ([#3698](https://github.com/cookiecutter/cookiecutter-django/pull/3698)) +### Updated +- Update jinja2 to 3.1.2 ([#3700](https://github.com/cookiecutter/cookiecutter-django/pull/3700)) + +## 2022.05.06 + +### Updated +- Update pre-commit to 2.19.0 ([#3697](https://github.com/cookiecutter/cookiecutter-django/pull/3697)) + +## 2022.05.04 + +### Updated +- Update django-coverage-plugin to 2.0.3 ([#3695](https://github.com/cookiecutter/cookiecutter-django/pull/3695)) + +## 2022.05.03 + +### Updated +- Update django-debug-toolbar to 3.4.0 ([#3692](https://github.com/cookiecutter/cookiecutter-django/pull/3692)) +- Update sentry-sdk to 1.5.11 ([#3693](https://github.com/cookiecutter/cookiecutter-django/pull/3693)) + +## 2022.05.01 + +### Updated +- Update django-debug-toolbar to 3.3.0 ([#3690](https://github.com/cookiecutter/cookiecutter-django/pull/3690)) + +## 2022.04.28 + +### Changed +- Add the possibility to set a max django version on create_django_issue script ([#3680](https://github.com/cookiecutter/cookiecutter-django/pull/3680)) + +## 2022.04.27 + +### Updated +- Update mypy to 0.950 ([#3687](https://github.com/cookiecutter/cookiecutter-django/pull/3687)) +- Update python-slugify to 6.1.2 ([#3686](https://github.com/cookiecutter/cookiecutter-django/pull/3686)) +- Update drf-spectacular to 0.22.1 ([#3684](https://github.com/cookiecutter/cookiecutter-django/pull/3684)) + +## 2022.04.25 + +### Updated +- Update pytest to 7.1.2 ([#3683](https://github.com/cookiecutter/cookiecutter-django/pull/3683)) + +## 2022.04.19 + +### Updated +- Update tox to 3.25.0 ([#3675](https://github.com/cookiecutter/cookiecutter-django/pull/3675)) +- Update sentry-sdk to 1.5.10 ([#3679](https://github.com/cookiecutter/cookiecutter-django/pull/3679)) + +## 2022.04.13 + +### Updated +- Bump stefanzweifel/git-auto-commit-action from 4.14.0 to 4.14.1 ([#3677](https://github.com/cookiecutter/cookiecutter-django/pull/3677)) + +## 2022.04.11 + +### Updated +- Update django to 3.2.13 ([#3676](https://github.com/cookiecutter/cookiecutter-django/pull/3676)) + +## 2022.04.08 + +### Updated +- Auto-update pre-commit hooks ([#3673](https://github.com/cookiecutter/cookiecutter-django/pull/3673)) + +## 2022.04.05 + +### Updated +- Update celery to 5.2.6 ([#3671](https://github.com/cookiecutter/cookiecutter-django/pull/3671)) + +## 2022.04.04 + +### Updated +- Update redis to 4.2.2 ([#3670](https://github.com/cookiecutter/cookiecutter-django/pull/3670)) +- Update celery to 5.2.5 ([#3669](https://github.com/cookiecutter/cookiecutter-django/pull/3669)) +- Update pre-commit to 2.18.1 ([#3668](https://github.com/cookiecutter/cookiecutter-django/pull/3668)) +- Update pillow to 9.1.0 ([#3665](https://github.com/cookiecutter/cookiecutter-django/pull/3665)) + +## 2022.04.01 + +### Changed +- Update domain for Celery docs ([#3663](https://github.com/cookiecutter/cookiecutter-django/pull/3663)) +### Updated +- Update watchgod to 0.8.2 ([#3664](https://github.com/cookiecutter/cookiecutter-django/pull/3664)) +- Update redis to 4.2.1 ([#3660](https://github.com/cookiecutter/cookiecutter-django/pull/3660)) + +## 2022.03.28 + +### Changed +- Update `black` version to `22.3.0` ([#3657](https://github.com/cookiecutter/cookiecutter-django/pull/3657)) + +## 2022.03.27 + +### Updated +- Update sphinx to 4.5.0 ([#3654](https://github.com/cookiecutter/cookiecutter-django/pull/3654)) +- Update jinja2 to 3.1.1 ([#3652](https://github.com/cookiecutter/cookiecutter-django/pull/3652)) +- Update pylint-django to 2.5.3 ([#3650](https://github.com/cookiecutter/cookiecutter-django/pull/3650)) +- Update django-allauth to 0.50.0 ([#3649](https://github.com/cookiecutter/cookiecutter-django/pull/3649)) +- Update mypy to 0.942 ([#3648](https://github.com/cookiecutter/cookiecutter-django/pull/3648)) +- Update jinja2 to 3.1.0 ([#3647](https://github.com/cookiecutter/cookiecutter-django/pull/3647)) +- Update redis to 4.2.0 ([#3646](https://github.com/cookiecutter/cookiecutter-django/pull/3646)) +- Update watchgod to 0.8.1 ([#3643](https://github.com/cookiecutter/cookiecutter-django/pull/3643)) +- Bump stefanzweifel/git-auto-commit-action from 4.13.1 to 4.14.0 ([#3641](https://github.com/cookiecutter/cookiecutter-django/pull/3641)) +- Update drf-spectacular to 0.22.0 ([#3642](https://github.com/cookiecutter/cookiecutter-django/pull/3642)) +- Update pytz to 2022.1 ([#3639](https://github.com/cookiecutter/cookiecutter-django/pull/3639)) +- Update sentry-sdk to 1.5.8 ([#3638](https://github.com/cookiecutter/cookiecutter-django/pull/3638)) +- Update pytest to 7.1.1 ([#3637](https://github.com/cookiecutter/cookiecutter-django/pull/3637)) +- Update uvicorn to 0.17.6 ([#3627](https://github.com/cookiecutter/cookiecutter-django/pull/3627)) + +## 2022.03.23 + +### Updated +- Bump peter-evans/create-pull-request from 3.14.0 to 4 ([#3645](https://github.com/cookiecutter/cookiecutter-django/pull/3645)) + +## 2022.03.20 + +### Changed +- Unify compressor, gulp and custom bootstrap options ([#3535](https://github.com/cookiecutter/cookiecutter-django/pull/3535)) + +## 2022.03.14 + +### Fixed +- Fix broken link in README of generated projects ([#3634](https://github.com/cookiecutter/cookiecutter-django/pull/3634)) + +## 2022.03.13 + +### Changed +- Add DRF spectacular link in requirements ([#3630](https://github.com/cookiecutter/cookiecutter-django/pull/3630)) + +## 2022.03.09 + +### Changed +- Fix a few typos in the documentation ([#3625](https://github.com/cookiecutter/cookiecutter-django/pull/3625)) + +## 2022.03.08 + +### Updated +- Update sentry-sdk to 1.5.7 ([#3624](https://github.com/cookiecutter/cookiecutter-django/pull/3624)) + +## 2022.03.03 + +### Updated +- Upgrade actions/setup-python to v3 ([#3621](https://github.com/cookiecutter/cookiecutter-django/pull/3621)) + +## 2022.03.02 + +### Updated +- Bump actions/checkout from 2 to 3 ([#3619](https://github.com/cookiecutter/cookiecutter-django/pull/3619)) + +## 2022.03.01 + +### Updated +- Bump actions/setup-python from 2 to 3 ([#3617](https://github.com/cookiecutter/cookiecutter-django/pull/3617)) +- Bump peter-evans/create-pull-request from 3.13.0 to 3.14.0 ([#3618](https://github.com/cookiecutter/cookiecutter-django/pull/3618)) + +## 2022.02.28 + +### Updated +- Update python-slugify to 6.1.1 ([#3615](https://github.com/cookiecutter/cookiecutter-django/pull/3615)) +- Bump peter-evans/create-pull-request from 3.12.1 to 3.13.0 ([#3616](https://github.com/cookiecutter/cookiecutter-django/pull/3616)) + +## 2022.02.25 + +### Updated +- Bump actions/setup-node from 2 to 3 ([#3614](https://github.com/cookiecutter/cookiecutter-django/pull/3614)) + +## 2022.02.24 + +### Updated +- Update django-allauth to 0.49.0 ([#3613](https://github.com/cookiecutter/cookiecutter-django/pull/3613)) +- Update sentry-sdk to 1.5.6 ([#3611](https://github.com/cookiecutter/cookiecutter-django/pull/3611)) +- Update python-slugify to 6.1.0 ([#3612](https://github.com/cookiecutter/cookiecutter-django/pull/3612)) + +## 2022.02.21 + +### Changed +- Cancel previous CI runs on successive PR pushes with GitHub actions ([#3575](https://github.com/cookiecutter/cookiecutter-django/pull/3575)) +### Updated +- Update coverage to 6.3.2 ([#3610](https://github.com/cookiecutter/cookiecutter-django/pull/3610)) +- Update gitpython to 3.1.27 ([#3607](https://github.com/cookiecutter/cookiecutter-django/pull/3607)) +- Update pylint-django to 2.5.2 ([#3602](https://github.com/cookiecutter/cookiecutter-django/pull/3602)) +- Update python-slugify to 6.0.1 ([#3599](https://github.com/cookiecutter/cookiecutter-django/pull/3599)) +- Update uvicorn to 0.17.5 ([#3596](https://github.com/cookiecutter/cookiecutter-django/pull/3596)) +- Update redis to 4.1.4 ([#3595](https://github.com/cookiecutter/cookiecutter-django/pull/3595)) + +## 2022.02.20 + +### Changed +- Fix incorrect createdb instruction in documentation ([#3606](https://github.com/cookiecutter/cookiecutter-django/pull/3606)) + +## 2022.02.16 + +### Fixed +- Fix Swagger schema API endpoint & add a test for it ([#3592](https://github.com/cookiecutter/cookiecutter-django/pull/3592)) + +## 2022.02.15 + +### Changed +- Update the drf-spectacular local dev server url to use http instead of https ([#3591](https://github.com/cookiecutter/cookiecutter-django/pull/3591)) + +## 2022.02.13 + +### Changed +- Change docs port from 7000 to 9000 ([#3590](https://github.com/cookiecutter/cookiecutter-django/pull/3590)) + +## 2022.02.12 + +### Updated +- Update pytest to 7.0.1 ([#3588](https://github.com/cookiecutter/cookiecutter-django/pull/3588)) + +## 2022.02.11 + +### Updated +- Update sentry-sdk to 1.5.5 ([#3586](https://github.com/cookiecutter/cookiecutter-django/pull/3586)) + +## 2022.02.10 + +### Fixed +- Fix GitLab CI error caused by Docker Compose's `platform` option ([#3585](https://github.com/cookiecutter/cookiecutter-django/pull/3585)) +### Updated +- Update whitenoise to 6.0.0 ([#3583](https://github.com/cookiecutter/cookiecutter-django/pull/3583)) + +## 2022.02.08 + +### Fixed +- Fixed some typos in drf-spectacular description and comments ([#3579](https://github.com/cookiecutter/cookiecutter-django/pull/3579)) +### Updated +- Update redis to 4.1.3 ([#3577](https://github.com/cookiecutter/cookiecutter-django/pull/3577)) +- Update werkzeug to 2.0.3 ([#3576](https://github.com/cookiecutter/cookiecutter-django/pull/3576)) + +## 2022.02.07 + +### Changed +- Update black to 22.1.0 ([#3572](https://github.com/cookiecutter/cookiecutter-django/pull/3572)) +### Fixed +- Fix docker-compose config on Apple silicon ([#3562](https://github.com/cookiecutter/cookiecutter-django/pull/3562)) +### Updated +- Update uvicorn to 0.17.4 ([#3574](https://github.com/cookiecutter/cookiecutter-django/pull/3574)) +- Update django-allauth to 0.48.0 ([#3573](https://github.com/cookiecutter/cookiecutter-django/pull/3573)) +- Update pytest to 7.0.0 ([#3567](https://github.com/cookiecutter/cookiecutter-django/pull/3567)) +- Update coverage to 6.3.1 ([#3561](https://github.com/cookiecutter/cookiecutter-django/pull/3561)) +- Update pillow to 9.0.1 ([#3571](https://github.com/cookiecutter/cookiecutter-django/pull/3571)) +- Bump peter-evans/create-pull-request from 3.12.0 to 3.12.1 ([#3558](https://github.com/cookiecutter/cookiecutter-django/pull/3558)) +- Update drf-spectacular to 0.21.2 ([#3560](https://github.com/cookiecutter/cookiecutter-django/pull/3560)) +- Update django to 3.2.12 ([#3559](https://github.com/cookiecutter/cookiecutter-django/pull/3559)) + +## 2022.01.27 + +### Updated +- Update redis to 4.1.2 ([#3551](https://github.com/cookiecutter/cookiecutter-django/pull/3551)) + +## 2022.01.26 + +### Updated +- Update coverage to 6.3 ([#3550](https://github.com/cookiecutter/cookiecutter-django/pull/3550)) +- Update sentry-sdk to 1.5.4 ([#3549](https://github.com/cookiecutter/cookiecutter-django/pull/3549)) +- Update django-crispy-forms to 1.14.0 ([#3548](https://github.com/cookiecutter/cookiecutter-django/pull/3548)) +- Update uvicorn to 0.17.0.post1 ([#3547](https://github.com/cookiecutter/cookiecutter-django/pull/3547)) + +## 2022.01.21 + +### Changed +- mysql support link ([#3544](https://github.com/cookiecutter/cookiecutter-django/pull/3544)) +### Updated +- Update sentry-sdk to 1.5.3 ([#3543](https://github.com/cookiecutter/cookiecutter-django/pull/3543)) +- Update django-anymail to 8.5 ([#3542](https://github.com/cookiecutter/cookiecutter-django/pull/3542)) + +## 2022.01.19 + +### Changed +- Add swagger API documentation when DRF is enabled ([#3536](https://github.com/cookiecutter/cookiecutter-django/pull/3536)) +### Updated +- Update pre-commit to 2.17.0 ([#3541](https://github.com/cookiecutter/cookiecutter-django/pull/3541)) + +## 2022.01.17 + +### Changed +- Avoid docker image/volume collision by prefixing with project slug ([#3528](https://github.com/cookiecutter/cookiecutter-django/pull/3528)) +### Updated +- Update redis to 4.1.1 ([#3540](https://github.com/cookiecutter/cookiecutter-django/pull/3540)) +- Update sphinx to 4.4.0 ([#3537](https://github.com/cookiecutter/cookiecutter-django/pull/3537)) + +## 2022.01.14 + +### Updated +- Update uvicorn to 0.17.0 ([#3534](https://github.com/cookiecutter/cookiecutter-django/pull/3534)) +- Bump stefanzweifel/git-auto-commit-action from 4.13.0 to 4.13.1 ([#3532](https://github.com/cookiecutter/cookiecutter-django/pull/3532)) + +## 2022.01.13 + +### Changed +- Add UserSignupForm and UserSocialSignupForm ([#3515](https://github.com/cookiecutter/cookiecutter-django/pull/3515)) +### Fixed +- Fix high CPU usage when running `runserver_plus` in Docker ([#3531](https://github.com/cookiecutter/cookiecutter-django/pull/3531)) +- Fix out-of-sync sequence for Site ID ([#3511](https://github.com/cookiecutter/cookiecutter-django/pull/3511)) + +## 2022.01.11 + +### Updated +- Bump stefanzweifel/git-auto-commit-action from 4.12.0 to 4.13.0 ([#3527](https://github.com/cookiecutter/cookiecutter-django/pull/3527)) + +## 2022.01.10 + +### Updated +- Update django-cors-headers to 3.11.0 ([#3526](https://github.com/cookiecutter/cookiecutter-django/pull/3526)) +- Update sentry-sdk to 1.5.2 ([#3525](https://github.com/cookiecutter/cookiecutter-django/pull/3525)) +- Update gitpython to 3.1.26 ([#3524](https://github.com/cookiecutter/cookiecutter-django/pull/3524)) + +## 2022.01.09 + +### Changed +- Fix broken center align of image links in README ([#3522](https://github.com/cookiecutter/cookiecutter-django/pull/3522)) + +## 2022.01.07 + +### Fixed +- Fix cache dependency path for linter job in CI workflow ([#3520](https://github.com/cookiecutter/cookiecutter-django/pull/3520)) +- Fix `open` option for `initBrowserSync` when using Docker ([#3519](https://github.com/cookiecutter/cookiecutter-django/pull/3519)) +### Updated +- Update mypy to 0.931 ([#3521](https://github.com/cookiecutter/cookiecutter-django/pull/3521)) +- Update gitpython to 3.1.25 ([#3518](https://github.com/cookiecutter/cookiecutter-django/pull/3518)) + +## 2022.01.06 + +### Changed +- Update output example in README ([#3512](https://github.com/cookiecutter/cookiecutter-django/pull/3512)) + +## 2022.01.05 + +### Changed +- Update references to Bootstrap from v4 to v5 in README ([#3513](https://github.com/cookiecutter/cookiecutter-django/pull/3513)) +### Updated +- Update requests to 2.27.1 ([#3516](https://github.com/cookiecutter/cookiecutter-django/pull/3516)) + +## 2022.01.04 + +### Changed +- Double quote array expansions to avoid re-splitting elements ([#3514](https://github.com/cookiecutter/cookiecutter-django/pull/3514)) +### Updated +- Update django to 3.2.11 ([#3510](https://github.com/cookiecutter/cookiecutter-django/pull/3510)) + +## 2022.01.03 + +### Changed +- Convert top level RST files to Markdown ([#3489](https://github.com/cookiecutter/cookiecutter-django/pull/3489)) +### Updated +- Update requests to 2.27.0 ([#3509](https://github.com/cookiecutter/cookiecutter-django/pull/3509)) +- Update pillow to 9.0.0 ([#3508](https://github.com/cookiecutter/cookiecutter-django/pull/3508)) +- Update pylint-django to 2.5.0 ([#3505](https://github.com/cookiecutter/cookiecutter-django/pull/3505)) + +## 2021.12.29 + +### Fixed +- Add generated files to `.gitignore` when selecting Gulp ([#3500](https://github.com/cookiecutter/cookiecutter-django/pull/3500)) +### Updated +- Update psycopg2-binary to 2.9.3 ([#3504](https://github.com/cookiecutter/cookiecutter-django/pull/3504)) +- Update psycopg2 to 2.9.3 ([#3503](https://github.com/cookiecutter/cookiecutter-django/pull/3503)) +- Update celery to 5.2.3 ([#3502](https://github.com/cookiecutter/cookiecutter-django/pull/3502)) +- Update tox to 3.24.5 ([#3501](https://github.com/cookiecutter/cookiecutter-django/pull/3501)) + +## 2021.12.28 + +### Changed +- Build the HTML for the documentation as part of the CI ([#3498](https://github.com/cookiecutter/cookiecutter-django/pull/3498)) + +## 2021.12.27 + +### Changed +- Hides 'sign up' elements when ACCOUNT_ALLOW_REGISTRATION is disabled ([#1914](https://github.com/cookiecutter/cookiecutter-django/pull/1914)) + +## 2021.12.26 + +### Fixed +- Fix missing psycopg2 dependency in docs Docker image ([#3494](https://github.com/cookiecutter/cookiecutter-django/pull/3494)) +### Updated +- Update celery to 5.2.2 ([#3496](https://github.com/cookiecutter/cookiecutter-django/pull/3496)) +- Update redis to 4.1.0 ([#3495](https://github.com/cookiecutter/cookiecutter-django/pull/3495)) + +## 2021.12.25 + +### Changed +- Automatically add Django version label to issue ([#3492](https://github.com/cookiecutter/cookiecutter-django/pull/3492)) +### Updated +- Auto-update pre-commit hooks ([#3493](https://github.com/cookiecutter/cookiecutter-django/pull/3493)) + +## 2021.12.24 + +### Changed +- Simplify `TEMPLATES` settings with `APP_DIRS=True` ([#3488](https://github.com/cookiecutter/cookiecutter-django/pull/3488)) +- Fix docs not building ([#3491](https://github.com/cookiecutter/cookiecutter-django/pull/3491)) +- Remove pylint-django from VITAL_BUT_UNKNOWN ([#3490](https://github.com/cookiecutter/cookiecutter-django/pull/3490)) +- Making docs image 40% smaller and also making python version upgrades easier for multi-stage builds. ([#2836](https://github.com/cookiecutter/cookiecutter-django/pull/2836)) +- Added Django's current language to the lang attribute of the html tag ([#3174](https://github.com/cookiecutter/cookiecutter-django/pull/3174)) +### Updated +- Update uvicorn to 0.16.0 ([#3454](https://github.com/cookiecutter/cookiecutter-django/pull/3454)) + +## 2021.12.22 + +### Changed +- Use built-in pip caching from actions/setup-python in generated project ([#3481](https://github.com/cookiecutter/cookiecutter-django/pull/3481)) +- Speed up CI tests on macOS ([#3480](https://github.com/cookiecutter/cookiecutter-django/pull/3480)) +### Updated +- Update mypy to 0.930 ([#3487](https://github.com/cookiecutter/cookiecutter-django/pull/3487)) +- Update redis to 4.0.2 ([#3486](https://github.com/cookiecutter/cookiecutter-django/pull/3486)) +- Update django-redis to 5.2.0 ([#3485](https://github.com/cookiecutter/cookiecutter-django/pull/3485)) + +## 2021.12.20 + +### Changed +- Add a PyCharm run configuration for docker-compose ([#3462](https://github.com/cookiecutter/cookiecutter-django/pull/3462)) + +## 2021.12.19 + +### Updated +- Update mypy to 0.920 ([#3478](https://github.com/cookiecutter/cookiecutter-django/pull/3478)) +- Update django-compressor to 3.1 ([#3476](https://github.com/cookiecutter/cookiecutter-django/pull/3476)) +- Update sphinx to 4.3.2 ([#3477](https://github.com/cookiecutter/cookiecutter-django/pull/3477)) + +## 2021.12.17 + +### Fixed +- Fix BrowserSync config on non-Docker setup ([#3461](https://github.com/cookiecutter/cookiecutter-django/pull/3461)) + +## 2021.12.16 + +### Fixed +- Fix carriage return in `.gitignore` on Windows ([#3456](https://github.com/cookiecutter/cookiecutter-django/pull/3456)) +### Updated +- Update django-debug-toolbar to 3.2.4 ([#3473](https://github.com/cookiecutter/cookiecutter-django/pull/3473)) + +## 2021.12.15 + +### Updated +- Update djangorestframework to 3.13.1 ([#3472](https://github.com/cookiecutter/cookiecutter-django/pull/3472)) + +## 2021.12.14 + +### Changed +- Update rcssmin & django-compressor ([#3470](https://github.com/cookiecutter/cookiecutter-django/pull/3470)) +### Updated +- Update pytest-django to 4.5.2 ([#3471](https://github.com/cookiecutter/cookiecutter-django/pull/3471)) +- Bump peter-evans/create-pull-request from 3.11.0 to 3.12.0 ([#3469](https://github.com/cookiecutter/cookiecutter-django/pull/3469)) + +## 2021.12.13 + +### Updated +- Update djangorestframework to 3.13.0 ([#3468](https://github.com/cookiecutter/cookiecutter-django/pull/3468)) +- Update sentry-sdk to 1.5.1 ([#3467](https://github.com/cookiecutter/cookiecutter-django/pull/3467)) +- Update django-debug-toolbar to 3.2.3 ([#3466](https://github.com/cookiecutter/cookiecutter-django/pull/3466)) +- Update argon2-cffi to 21.3.0 ([#3464](https://github.com/cookiecutter/cookiecutter-django/pull/3464)) +- Update django-allauth to 0.47.0 ([#3459](https://github.com/cookiecutter/cookiecutter-django/pull/3459)) + +## 2021.12.09 + +### Updated +- Auto-update pre-commit hooks ([#3457](https://github.com/cookiecutter/cookiecutter-django/pull/3457)) + +## 2021.12.08 + +### Changed +- Reword introduction in documentation ([#3452](https://github.com/cookiecutter/cookiecutter-django/pull/3452)) +### Updated +- Update argon2-cffi to 21.2.0 ([#3453](https://github.com/cookiecutter/cookiecutter-django/pull/3453)) + +## 2021.12.07 + +### Changed +- Add docker, pip and npm to GitHub's Dependabot ([#3401](https://github.com/cookiecutter/cookiecutter-django/pull/3401)) +- Configure Dependabot for npm packages at the template level ([#3436](https://github.com/cookiecutter/cookiecutter-django/pull/3436)) +### Updated +- Update django to 3.2.10 ([#3451](https://github.com/cookiecutter/cookiecutter-django/pull/3451)) + +## 2021.12.06 + +### Updated +- Auto-update pre-commit hooks ([#3449](https://github.com/cookiecutter/cookiecutter-django/pull/3449)) +- Update black to 21.12b0 ([#3448](https://github.com/cookiecutter/cookiecutter-django/pull/3448)) +- Update django-cors-headers to 3.10.1 ([#3447](https://github.com/cookiecutter/cookiecutter-django/pull/3447)) + +## 2021.12.04 + +### Changed +- Removed mention of Foundation fork from readme ([#3445](https://github.com/cookiecutter/cookiecutter-django/pull/3445)) +### Updated +- Update pytest-django to 4.5.1 ([#3443](https://github.com/cookiecutter/cookiecutter-django/pull/3443)) + +## 2021.12.01 + +### Updated +- Update pre-commit to 2.16.0 ([#3442](https://github.com/cookiecutter/cookiecutter-django/pull/3442)) + +## 2021.11.30 + +### Updated +- Update django-redis to 5.1.0 ([#3440](https://github.com/cookiecutter/cookiecutter-django/pull/3440)) +- Update django-stubs to 1.9.0 ([#3439](https://github.com/cookiecutter/cookiecutter-django/pull/3439)) + +## 2021.11.29 + +### Fixed +- Fix pre-commit config ([#3435](https://github.com/cookiecutter/cookiecutter-django/pull/3435)) +### Updated +- Update sphinx to 4.3.1 ([#3438](https://github.com/cookiecutter/cookiecutter-django/pull/3438)) + +## 2021.11.27 + +### Updated +- Update coverage to 6.2 ([#3437](https://github.com/cookiecutter/cookiecutter-django/pull/3437)) + +## 2021.11.26 + +### Changed +- Setup pre-commit for the template files ([#3433](https://github.com/cookiecutter/cookiecutter-django/pull/3433)) + +## 2021.11.25 + +### Changed +- Add an assertion to fix mypy type error ([#3150](https://github.com/cookiecutter/cookiecutter-django/pull/3150)) +- Make `django` depend on `redis` in local Docker ([#3265](https://github.com/cookiecutter/cookiecutter-django/pull/3265)) + +## 2021.11.24 + +### Changed +- Cache Python dependencies on our CI ([#3434](https://github.com/cookiecutter/cookiecutter-django/pull/3434)) +- Small formatting fixes to Deploy to PythonAnywhere page ([#3432](https://github.com/cookiecutter/cookiecutter-django/pull/3432)) +### Updated +- Upgrade to Django 3.2 ([#3425](https://github.com/cookiecutter/cookiecutter-django/pull/3425)) + +## 2021.11.22 + +### Changed +- Removed unnecessary custom context processor exposing the DEBUG Template Context Variable ([#3042](https://github.com/cookiecutter/cookiecutter-django/pull/3042)) +- Clean up trailing whitespace ([#3430](https://github.com/cookiecutter/cookiecutter-django/pull/3430)) +### Updated +- Update redis to 4.0.2 ([#3431](https://github.com/cookiecutter/cookiecutter-django/pull/3431)) +- Bump Postgres to 13.5 12.9 11.14 10.19; add 14.1 ([#3428](https://github.com/cookiecutter/cookiecutter-django/pull/3428)) + +## 2021.11.20 + +### Fixed +- Update repos for pre-commit hooks ([#3424](https://github.com/cookiecutter/cookiecutter-django/pull/3424)) +### Updated +- Bump pre-commit/action to 2.0.3 ([#3426](https://github.com/cookiecutter/cookiecutter-django/pull/3426)) + +## 2021.11.19 + +### Updated +- Update celery to 5.2.1 ([#3423](https://github.com/cookiecutter/cookiecutter-django/pull/3423)) +- Auto-update pre-commit hooks ([#3420](https://github.com/cookiecutter/cookiecutter-django/pull/3420)) + +## 2021.11.18 + +### Changed +- Switch template to calendar versioning & automate releases ([#3415](https://github.com/cookiecutter/cookiecutter-django/pull/3415)) +### Updated +- Update black to 21.11b1 ([#3421](https://github.com/cookiecutter/cookiecutter-django/pull/3421)) +- Update redis to 4.0.1 ([#3416](https://github.com/cookiecutter/cookiecutter-django/pull/3416)) + +## [2021-11-17] +### Updated +- Update sentry-sdk to 1.5.0 ([#3417](https://github.com/cookiecutter/cookiecutter-django/pull/3417)) +- Update black to 21.11b0 ([#3414](https://github.com/cookiecutter/cookiecutter-django/pull/3414)) + +## [2021-11-16] +### Changed +- Upgrade JS dependencies and upgrade to node 16 ([#3400](https://github.com/cookiecutter/cookiecutter-django/pull/3400)) +### Fixed +- Fix ungraceful Celery workers shutdown in container ([#3405](https://github.com/cookiecutter/cookiecutter-django/pull/3405)) +### Updated +- Update psycopg2-binary to 2.9.2 ([#3411](https://github.com/cookiecutter/cookiecutter-django/pull/3411)) +- Update psycopg2 to 2.9.2 ([#3410](https://github.com/cookiecutter/cookiecutter-django/pull/3410)) +- Update redis to 4.0.0 ([#3406](https://github.com/cookiecutter/cookiecutter-django/pull/3406)) +- Update django-coverage-plugin to 2.0.2 ([#3409](https://github.com/cookiecutter/cookiecutter-django/pull/3409)) +- Update black to 21.10b0 ([#3408](https://github.com/cookiecutter/cookiecutter-django/pull/3408)) + +## [2021-11-15] +### Updated +- Update django-allauth to 0.46.0 ([#3407](https://github.com/cookiecutter/cookiecutter-django/pull/3407)) + +## [2021-11-13] +### Fixed +- Fix incorrect node version in `package.json` ([#3399](https://github.com/cookiecutter/cookiecutter-django/pull/3399)) + +## [2021-11-12] +### Changed +- Add Django major/minor release table maker in GitHub issues ([#3288](https://github.com/cookiecutter/cookiecutter-django/pull/3288)) +- Upgrade to Bootstrap 5 ([#3276](https://github.com/cookiecutter/cookiecutter-django/pull/3276)) +### Updated +- Update requests to 2.26.0 ([#3397](https://github.com/cookiecutter/cookiecutter-django/pull/3397)) +- Update crispy-bootstrap5 to 0.6 ([#3396](https://github.com/cookiecutter/cookiecutter-django/pull/3396)) + +## [2021-11-11] +### Changed +- Build all images on CI ([#3394](https://github.com/cookiecutter/cookiecutter-django/pull/3394)) +### Updated +- Update coverage to 6.1.2 ([#3393](https://github.com/cookiecutter/cookiecutter-django/pull/3393)) + +## [2021-11-10] +### Changed +- Update sphinx to 4.3.0 ([#3392](https://github.com/cookiecutter/cookiecutter-django/pull/3392)) +### Updated +- Auto-update pre-commit hooks ([#3389](https://github.com/cookiecutter/cookiecutter-django/pull/3389)) +- Update jinja2 to 3.0.3 ([#3388](https://github.com/cookiecutter/cookiecutter-django/pull/3388)) + +## [2021-11-09] +### Changed +- refactor: remove user API methods parameter ([#3385](https://github.com/cookiecutter/cookiecutter-django/pull/3385)) +- Get GitHub repo from environment ([#3387](https://github.com/cookiecutter/cookiecutter-django/pull/3387)) +### Updated +- Update celery to 5.2.0 ([#3384](https://github.com/cookiecutter/cookiecutter-django/pull/3384)) +- Update isort to 5.10.1 ([#3386](https://github.com/cookiecutter/cookiecutter-django/pull/3386)) + +## [2021-11-08] +### Changed +- Update docker and non-docker configs to Debian 11 (bullseye) ([#3372](https://github.com/cookiecutter/cookiecutter-django/pull/3372)) + +## [2021-11-07] +### Updated +- Update django-extensions to 3.1.5 ([#3383](https://github.com/cookiecutter/cookiecutter-django/pull/3383)) + +## [2021-11-04] +### Changed +- change path in docs Makefile to use APP variable ([#3379](https://github.com/cookiecutter/cookiecutter-django/pull/3379)) +### Fixed +- fix help in docs Makefile ([#3380](https://github.com/cookiecutter/cookiecutter-django/pull/3380)) +### Updated +- Bump peter-evans/create-pull-request from 3.10.1 to 3.11.0 ([#3382](https://github.com/cookiecutter/cookiecutter-django/pull/3382)) +- Auto-update pre-commit hooks ([#3381](https://github.com/cookiecutter/cookiecutter-django/pull/3381)) +- Update isort to 5.10.0 ([#3378](https://github.com/cookiecutter/cookiecutter-django/pull/3378)) + +## [2021-11-02] +### Updated +- Auto-update pre-commit hooks ([#3377](https://github.com/cookiecutter/cookiecutter-django/pull/3377)) + +## [2021-11-01] +### Updated +- Update django-storages to 1.12.3 ([#3374](https://github.com/cookiecutter/cookiecutter-django/pull/3374)) +- Update coverage to 6.1.1 ([#3376](https://github.com/cookiecutter/cookiecutter-django/pull/3376)) + +## [2021-10-28] +### Updated +- Update factory-boy to 3.2.1 ([#3373](https://github.com/cookiecutter/cookiecutter-django/pull/3373)) + +## [2021-10-26] +### Changed +- use Wayback Machine to fix dead link for postgres user setup ([#3363](https://github.com/cookiecutter/cookiecutter-django/pull/3363)) +- Fix pull request links to correct repo URL on CHANGELOG.md ([#3370](https://github.com/cookiecutter/cookiecutter-django/pull/3370)) +### Updated +- Update pyyaml to 6.0 ([#3362](https://github.com/cookiecutter/cookiecutter-django/pull/3362)) +- Update pillow to 8.4.0 ([#3364](https://github.com/cookiecutter/cookiecutter-django/pull/3364)) +- Update django-storages to 1.12.2 ([#3365](https://github.com/cookiecutter/cookiecutter-django/pull/3365)) +- Update django-environ to 0.8.1 ([#3368](https://github.com/cookiecutter/cookiecutter-django/pull/3368)) + +## [2021-10-22] +### Changed +- Move repo under cookiecutter organisation ([#3357](https://github.com/cookiecutter/cookiecutter-django/pull/3357)) + +## [2021-10-18] +### Updated +- Update django-environ to 0.8.0 ([#3367](https://github.com/cookiecutter/cookiecutter-django/pull/3367)) + +## [2021-10-14] +### Updated +- Update flake8 to 4.0.1 ([#3361](https://github.com/cookiecutter/cookiecutter-django/pull/3361)) +- Update flake8-isort to 4.1.1 ([#3360](https://github.com/cookiecutter/cookiecutter-django/pull/3360)) +- Update django-model-utils to 4.2.0 ([#3359](https://github.com/cookiecutter/cookiecutter-django/pull/3359)) + +## [2021-10-13] +### Changed +- Add drf stubs ([#3353](https://github.com/cookiecutter/cookiecutter-django/pull/3353)) + +## [2021-10-12] +### Updated +- Update coverage to 6.0.2 ([#3356](https://github.com/cookiecutter/cookiecutter-django/pull/3356)) + +## [2021-10-11] +### Updated +- Update werkzeug to 2.0.2 ([#3344](https://github.com/cookiecutter/cookiecutter-django/pull/3344)) +- Update coverage to 6.0.1 ([#3348](https://github.com/cookiecutter/cookiecutter-django/pull/3348)) +- Update django-coverage-plugin to 2.0.1 ([#3349](https://github.com/cookiecutter/cookiecutter-django/pull/3349)) +- Update django-cors-headers to 3.10.0 ([#3345](https://github.com/cookiecutter/cookiecutter-django/pull/3345)) +- Update jinja2 to 3.0.2 ([#3343](https://github.com/cookiecutter/cookiecutter-django/pull/3343)) +- Update django-storages to 1.12.1 ([#3355](https://github.com/cookiecutter/cookiecutter-django/pull/3355)) + +## [2021-10-03] +### Updated +- Update pytz to 2021.3 ([#3340](https://github.com/cookiecutter/cookiecutter-django/pull/3340)) + +## [2021-10-01] +### Changed +- Fix the wrong pre-commit hyperlink in Prerequisites section ([#3338](https://github.com/cookiecutter/cookiecutter-django/pull/3338)) + +## [2021-09-30] +### Updated +- Update sentry-sdk to 1.4.3 ([#3334](https://github.com/cookiecutter/cookiecutter-django/pull/3334)) + +## [2021-09-29] +### Updated +- Update django-cors-headers to 3.9.0 ([#3332](https://github.com/cookiecutter/cookiecutter-django/pull/3332)) + +## [2021-09-27] +### Updated +- Update sentry-sdk to 1.4.2 ([#3329](https://github.com/cookiecutter/cookiecutter-django/pull/3329)) + +## [2021-09-26] +### Updated +- Update django-crispy-forms to 1.13.0 ([#3327](https://github.com/cookiecutter/cookiecutter-django/pull/3327)) + +## [2021-09-24] +### Changed +- Add django-settings-module to .pylintrc ([#3326](https://github.com/cookiecutter/cookiecutter-django/pull/3326)) + +## [2021-09-23] +### Updated +- Update sentry-sdk to 1.4.1 ([#3325](https://github.com/cookiecutter/cookiecutter-django/pull/3325)) + +## [2021-09-22] +### Updated +- Update sentry-sdk to 1.4.0 ([#3324](https://github.com/cookiecutter/cookiecutter-django/pull/3324)) + +## [2021-09-16] +### Updated +- Update tox to 3.24.4 ([#3323](https://github.com/cookiecutter/cookiecutter-django/pull/3323)) + +## [2021-09-15] +### Updated +- Auto-update pre-commit hooks ([#3322](https://github.com/cookiecutter/cookiecutter-django/pull/3322)) + +## [2021-09-14] +### Updated +- Update black to 21.9b0 ([#3321](https://github.com/cookiecutter/cookiecutter-django/pull/3321)) + +## [2021-09-13] +### Updated +- Bump stefanzweifel/git-auto-commit-action from 4.11.0 to 4.12.0 ([#3320](https://github.com/cookiecutter/cookiecutter-django/pull/3320)) +- Update sphinx to 4.2.0 ([#3319](https://github.com/cookiecutter/cookiecutter-django/pull/3319)) + +## [2021-09-11] +### Changed +- Removing pycharm docs if app does not use pycharm ([#3139](https://github.com/cookiecutter/cookiecutter-django/pull/3139)) +### Updated +- Update django-environ to 0.7.0 ([#3317](https://github.com/cookiecutter/cookiecutter-django/pull/3317)) + +## [2021-09-06] +### Changed +- Update Celery to v5 ([#3280](https://github.com/cookiecutter/cookiecutter-django/pull/3280)) + +## [2021-09-05] +### Updated +- Update django-environ to 0.6.0 ([#3314](https://github.com/cookiecutter/cookiecutter-django/pull/3314)) + +## [2021-09-03] +### Changed +- Update available postgres versions ([#3297](https://github.com/cookiecutter/cookiecutter-django/pull/3297)) +### Updated +- Update pre-commit to 2.15.0 ([#3313](https://github.com/cookiecutter/cookiecutter-django/pull/3313)) +- Auto-update pre-commit hooks ([#3307](https://github.com/cookiecutter/cookiecutter-django/pull/3307)) +- Update pillow to 8.3.2 ([#3312](https://github.com/cookiecutter/cookiecutter-django/pull/3312)) +- Update django-environ to 0.5.0 ([#3311](https://github.com/cookiecutter/cookiecutter-django/pull/3311)) +- Update pytest to 6.2.5 ([#3310](https://github.com/cookiecutter/cookiecutter-django/pull/3310)) +- Update black to 21.8b0 ([#3308](https://github.com/cookiecutter/cookiecutter-django/pull/3308)) +- Update argon2-cffi to 21.1.0 ([#3306](https://github.com/cookiecutter/cookiecutter-django/pull/3306)) +- Bump peter-evans/create-pull-request from 3.10.0 to 3.10.1 ([#3303](https://github.com/cookiecutter/cookiecutter-django/pull/3303)) +- Update django-debug-toolbar to 3.2.2 ([#3296](https://github.com/cookiecutter/cookiecutter-django/pull/3296)) +- Update django-cors-headers to 3.8.0 ([#3295](https://github.com/cookiecutter/cookiecutter-django/pull/3295)) +- Update uvicorn to 0.15.0 ([#3294](https://github.com/cookiecutter/cookiecutter-django/pull/3294)) + +## [2021-08-27] +### Updated +- Update tox to 3.24.3 ([#3302](https://github.com/cookiecutter/cookiecutter-django/pull/3302)) + +## [2021-08-20] +### Changed +- Fix Jinja2 break line control on Procfile ([#3300](https://github.com/cookiecutter/cookiecutter-django/pull/3300)) + +## [2021-08-19] +### Changed +- Fix several minor typos ([#3301](https://github.com/cookiecutter/cookiecutter-django/pull/3301)) + +## [2021-08-13] +### Changed +- Upgrade to Redis 6 ([#3255](https://github.com/cookiecutter/cookiecutter-django/pull/3255)) +### Fixed +- Fix RTD build image to support Python 3.9 ([#3293](https://github.com/cookiecutter/cookiecutter-django/pull/3293)) + +## [2021-08-12] +### Changed +- Add documentation for automating backups ([#3268](https://github.com/cookiecutter/cookiecutter-django/pull/3268)) +- Add missing step to getting started locally in docs ([#3291](https://github.com/cookiecutter/cookiecutter-django/pull/3291)) +- Moved isort config from `.editorconfig` to `setup.cfg` ([#3290](https://github.com/cookiecutter/cookiecutter-django/pull/3290)) +- How to pre-commit in Docker Development ([#3287](https://github.com/cookiecutter/cookiecutter-django/pull/3287)) +### Updated +- Update sentry-sdk to 1.3.1 ([#3281](https://github.com/cookiecutter/cookiecutter-django/pull/3281)) +- Update tox to 3.24.1 ([#3285](https://github.com/cookiecutter/cookiecutter-django/pull/3285)) +- Update pre-commit to 2.14.0 ([#3289](https://github.com/cookiecutter/cookiecutter-django/pull/3289)) + +## [2021-07-30] +### Updated +- Auto-update pre-commit hooks ([#3283](https://github.com/cookiecutter/cookiecutter-django/pull/3283)) +- Update isort to 5.9.3 ([#3282](https://github.com/cookiecutter/cookiecutter-django/pull/3282)) + +## [2021-07-27] +### Changed +- Convert trans to translate in templates ([#3277](https://github.com/cookiecutter/cookiecutter-django/pull/3277)) +### Updated +- Update hiredis to 2.0.0 ([#3110](https://github.com/cookiecutter/cookiecutter-django/pull/3110)) +- Update mypy to 0.910 ([#3237](https://github.com/cookiecutter/cookiecutter-django/pull/3237)) +- Update whitenoise to 5.3.0 ([#3273](https://github.com/cookiecutter/cookiecutter-django/pull/3273)) +- Update tox to 3.24.0 ([#3269](https://github.com/cookiecutter/cookiecutter-django/pull/3269)) +- Update django-allauth to 0.45.0 ([#3267](https://github.com/cookiecutter/cookiecutter-django/pull/3267)) +- Update sentry-sdk to 1.3.0 ([#3262](https://github.com/cookiecutter/cookiecutter-django/pull/3262)) +- Update sphinx to 4.1.2 ([#3278](https://github.com/cookiecutter/cookiecutter-django/pull/3278)) +- Auto-update pre-commit hooks ([#3264](https://github.com/cookiecutter/cookiecutter-django/pull/3264)) +- Update isort to 5.9.2 ([#3279](https://github.com/cookiecutter/cookiecutter-django/pull/3279)) +- Update pillow to 8.3.1 ([#3259](https://github.com/cookiecutter/cookiecutter-django/pull/3259)) +- Update black to 21.7b0 ([#3272](https://github.com/cookiecutter/cookiecutter-django/pull/3272)) + +## [2021-07-12] +### Changed +- Define REMAP_SIGTERM=SIGQUIT on Profile of Celery on Heroku ([#3263](https://github.com/cookiecutter/cookiecutter-django/pull/3263)) + +## [2021-07-08] +### Updated +- Update django to 3.1.13 ([#3247](https://github.com/cookiecutter/cookiecutter-django/pull/3247)) + +## [2021-06-29] +### Changed +- Improve github bug report template ([#3243](https://github.com/cookiecutter/cookiecutter-django/pull/3243)) + +## [2021-06-28] +### Changed +- Revert "Fix Celery ports error on local Docker" ([#3242](https://github.com/cookiecutter/cookiecutter-django/pull/3242)) +### Fixed +- Fix Celery ports error on local Docker ([#3241](https://github.com/cookiecutter/cookiecutter-django/pull/3241)) + +## [2021-06-25] +### Changed +- Update `.gitignore` file for VSCode ([#3238](https://github.com/cookiecutter/cookiecutter-django/pull/3238)) +### Fixed +- Wrap jQuery call in `DOMContentLoaded` event listener on account email page ([#3239](https://github.com/cookiecutter/cookiecutter-django/pull/3239)) + +## [2021-06-22] +### Changed +- Update docs/howto.rst ([#3230](https://github.com/cookiecutter/cookiecutter-django/pull/3230)) +- Add support for PG 13. Drop PG 9. Update all minor versions ([#3154](https://github.com/cookiecutter/cookiecutter-django/pull/3154)) +### Updated +- Update isort to 5.9.1 ([#3236](https://github.com/cookiecutter/cookiecutter-django/pull/3236)) +- Auto-update pre-commit hooks ([#3235](https://github.com/cookiecutter/cookiecutter-django/pull/3235)) + +## [2021-06-21] +### Updated +- Update isort to 5.9.0 ([#3234](https://github.com/cookiecutter/cookiecutter-django/pull/3234)) +- Update django-anymail to 8.4 ([#3225](https://github.com/cookiecutter/cookiecutter-django/pull/3225)) +- Update django-redis to 5.0.0 ([#3205](https://github.com/cookiecutter/cookiecutter-django/pull/3205)) +- Update pylint-django to 2.4.4 ([#3233](https://github.com/cookiecutter/cookiecutter-django/pull/3233)) +- Auto-update pre-commit hooks ([#3220](https://github.com/cookiecutter/cookiecutter-django/pull/3220)) +- Bump peter-evans/create-pull-request from 3.9.2 to 3.10.0 ([#3197](https://github.com/cookiecutter/cookiecutter-django/pull/3197)) +- Update black to 21.6b0 ([#3232](https://github.com/cookiecutter/cookiecutter-django/pull/3232)) +- Update pytest to 6.2.4 ([#3231](https://github.com/cookiecutter/cookiecutter-django/pull/3231)) +- Update django-crispy-forms to 1.12.0 ([#3221](https://github.com/cookiecutter/cookiecutter-django/pull/3221)) +- Update mypy to 0.902 ([#3219](https://github.com/cookiecutter/cookiecutter-django/pull/3219)) +- Update django-coverage-plugin to 2.0.0 ([#3217](https://github.com/cookiecutter/cookiecutter-django/pull/3217)) +- Update ipdb to 0.13.9 ([#3210](https://github.com/cookiecutter/cookiecutter-django/pull/3210)) +- Update uvicorn to 0.14.0 ([#3207](https://github.com/cookiecutter/cookiecutter-django/pull/3207)) +- Update pytest-cookies to 0.6.1 ([#3196](https://github.com/cookiecutter/cookiecutter-django/pull/3196)) +- Update sphinx to 4.0.2 ([#3193](https://github.com/cookiecutter/cookiecutter-django/pull/3193)) +- Update jinja2 to 3.0.1 ([#3189](https://github.com/cookiecutter/cookiecutter-django/pull/3189)) + +## [2021-06-19] +### Updated +- Update psycopg2 to 2.9.1 ([#3227](https://github.com/cookiecutter/cookiecutter-django/pull/3227)) +- Update psycopg2-binary to 2.9.1 ([#3228](https://github.com/cookiecutter/cookiecutter-django/pull/3228)) + +## [2021-06-14] +### Changed +- Update black GitHub link in requirements ([#3222](https://github.com/cookiecutter/cookiecutter-django/pull/3222)) + +## [2021-06-09] +### Changed +- Fix link format in developing-locally.rst ([#3214](https://github.com/cookiecutter/cookiecutter-django/pull/3214)) +### Updated +- Update pre-commit to 2.13.0 ([#3195](https://github.com/cookiecutter/cookiecutter-django/pull/3195)) +- Update pytest-django to 4.4.0 ([#3212](https://github.com/cookiecutter/cookiecutter-django/pull/3212)) +- Update mypy to 0.901 ([#3215](https://github.com/cookiecutter/cookiecutter-django/pull/3215)) +- Auto-update pre-commit hooks ([#3206](https://github.com/cookiecutter/cookiecutter-django/pull/3206)) +- Update black to 21.5b2 ([#3204](https://github.com/cookiecutter/cookiecutter-django/pull/3204)) + +## [2021-06-06] +### Changed +- Updated .pre-commit-config.yaml to self-update its dependencies ([#3208](https://github.com/cookiecutter/cookiecutter-django/pull/3208)) + +## [2021-06-05] +### Changed +- Shorthand for the officially supported buildpack ([#3211](https://github.com/cookiecutter/cookiecutter-django/pull/3211)) + +## [2021-06-02] +### Updated +- Update django to 3.1.12 ([#3209](https://github.com/cookiecutter/cookiecutter-django/pull/3209)) + +## [2021-05-18] +### Changed +- Move ARG PYTHON_VERSION=3.9-slim-buster to the global scope ([#3188](https://github.com/cookiecutter/cookiecutter-django/pull/3188)) + +## [2021-05-17] +### Updated +- Bump tiangolo/issue-manager from 0.3.0 to 0.4.0 ([#3186](https://github.com/cookiecutter/cookiecutter-django/pull/3186)) +- Auto-update pre-commit hooks ([#3185](https://github.com/cookiecutter/cookiecutter-django/pull/3185)) + +## [2021-05-15] +### Changed +- Update watchgod to 0.7 ([#3177](https://github.com/cookiecutter/cookiecutter-django/pull/3177)) +### Updated +- Auto-update pre-commit hooks ([#3184](https://github.com/cookiecutter/cookiecutter-django/pull/3184)) +- Update black to 21.5b1 ([#3167](https://github.com/cookiecutter/cookiecutter-django/pull/3167)) +- Update flake8 to 3.9.2 ([#3164](https://github.com/cookiecutter/cookiecutter-django/pull/3164)) +- Update pytest-django to 4.3.0 ([#3182](https://github.com/cookiecutter/cookiecutter-django/pull/3182)) +- Auto-update pre-commit hooks ([#3157](https://github.com/cookiecutter/cookiecutter-django/pull/3157)) +- Update python-slugify to 5.0.2 ([#3161](https://github.com/cookiecutter/cookiecutter-django/pull/3161)) +- Bump stefanzweifel/git-auto-commit-action from 4.10.0 to 4.11.0 ([#3171](https://github.com/cookiecutter/cookiecutter-django/pull/3171)) +- Update sentry-sdk to 1.1.0 ([#3163](https://github.com/cookiecutter/cookiecutter-django/pull/3163)) +- Bump actions/setup-python from 2 to 2.2.2 ([#3173](https://github.com/cookiecutter/cookiecutter-django/pull/3173)) +- Update tox to 3.23.1 ([#3160](https://github.com/cookiecutter/cookiecutter-django/pull/3160)) +- Update pytest to 6.2.4 ([#3156](https://github.com/cookiecutter/cookiecutter-django/pull/3156)) +- Bump peter-evans/create-pull-request from 3.8.2 to 3.9.2 ([#3179](https://github.com/cookiecutter/cookiecutter-django/pull/3179)) +- Update sphinx to 4.0.1 ([#3169](https://github.com/cookiecutter/cookiecutter-django/pull/3169)) +- Update cookiecutter to 1.7.3 ([#3180](https://github.com/cookiecutter/cookiecutter-django/pull/3180)) +- Update django to 3.1.11 ([#3178](https://github.com/cookiecutter/cookiecutter-django/pull/3178)) + +## [2021-05-06] +### Updated +- Update django to 3.1.10 ([#3162](https://github.com/cookiecutter/cookiecutter-django/pull/3162)) + +## [2021-05-04] +### Updated +- Update django to 3.1.9 ([#3155](https://github.com/cookiecutter/cookiecutter-django/pull/3155)) + +## [2021-04-30] +### Fixed +- Fix linting error in production.py ([#3148](https://github.com/cookiecutter/cookiecutter-django/pull/3148)) + +## [2021-04-29] +### Updated +- Update black to 21.4b2 ([#3147](https://github.com/cookiecutter/cookiecutter-django/pull/3147)) +- Auto-update pre-commit hooks ([#3146](https://github.com/cookiecutter/cookiecutter-django/pull/3146)) + +## [2021-04-28] +### Changed +- Fix README link ([#3144](https://github.com/cookiecutter/cookiecutter-django/pull/3144)) +### Updated +- Auto-update pre-commit hooks ([#3145](https://github.com/cookiecutter/cookiecutter-django/pull/3145)) + +## [2021-04-27] +### Updated +- Update pygithub to 1.55 ([#3141](https://github.com/cookiecutter/cookiecutter-django/pull/3141)) +- Update black to 21.4b1 ([#3143](https://github.com/cookiecutter/cookiecutter-django/pull/3143)) + +## [2021-04-26] +### Updated +- Update black to 21.4b0 ([#3138](https://github.com/cookiecutter/cookiecutter-django/pull/3138)) +- Auto-update pre-commit hooks ([#3137](https://github.com/cookiecutter/cookiecutter-django/pull/3137)) + +## [2021-04-21] +### Updated +- Auto-update pre-commit hooks ([#3133](https://github.com/cookiecutter/cookiecutter-django/pull/3133)) +- Update django-extensions to 3.1.3 ([#3136](https://github.com/cookiecutter/cookiecutter-django/pull/3136)) +- Update django-compressor to 2.4.1 ([#3135](https://github.com/cookiecutter/cookiecutter-django/pull/3135)) +- Update pre-commit to 2.12.1 ([#3134](https://github.com/cookiecutter/cookiecutter-django/pull/3134)) +- Update flake8 to 3.9.1 ([#3131](https://github.com/cookiecutter/cookiecutter-django/pull/3131)) +- Update django-stubs to 1.8.0 ([#3127](https://github.com/cookiecutter/cookiecutter-django/pull/3127)) +- Update sphinx to 3.5.4 ([#3126](https://github.com/cookiecutter/cookiecutter-django/pull/3126)) + +## [2021-04-15] +### Updated +- Update django-debug-toolbar to 3.2.1 ([#3129](https://github.com/cookiecutter/cookiecutter-django/pull/3129)) + +## [2021-04-14] +### Updated +- Bump stefanzweifel/git-auto-commit-action from v4.9.2 to v4.10.0 ([#3128](https://github.com/cookiecutter/cookiecutter-django/pull/3128)) + +## [2021-04-11] +### Updated +- Update pytest-django to 4.2.0 ([#3125](https://github.com/cookiecutter/cookiecutter-django/pull/3125)) +- Update pylint-django to 2.4.3 ([#3122](https://github.com/cookiecutter/cookiecutter-django/pull/3122)) + +## [2021-04-09] +### Changed +- Update from Python 3.8 to Python 3.9 ([#3023](https://github.com/cookiecutter/cookiecutter-django/pull/3023)) + +## [2021-04-08] +### Changed +- Switch .dockerignore to explicit list ([#3121](https://github.com/cookiecutter/cookiecutter-django/pull/3121)) +- Change Docker image to multi-stage build for Django ([#2815](https://github.com/cookiecutter/cookiecutter-django/pull/2815)) +- Fix deprecated warning in middleware tests ([#3038](https://github.com/cookiecutter/cookiecutter-django/pull/3038)) +### Updated +- Update pre-commit to 2.12.0 ([#3120](https://github.com/cookiecutter/cookiecutter-django/pull/3120)) + +## [2021-04-07] +### Changed +- Update django to 3.1.8 ([#3117](https://github.com/cookiecutter/cookiecutter-django/pull/3117)) +### Fixed +- Fix linting via pre-commit on Github CI ([#3077](https://github.com/cookiecutter/cookiecutter-django/pull/3077)) +- Fix gitlab-ci using duplicate key name for image ([#3112](https://github.com/cookiecutter/cookiecutter-django/pull/3112)) +### Updated +- Update sentry-sdk to 1.0.0 ([#3080](https://github.com/cookiecutter/cookiecutter-django/pull/3080)) +- Update gunicorn to 20.1.0 ([#3108](https://github.com/cookiecutter/cookiecutter-django/pull/3108)) +- Update pre-commit to 2.12.0 ([#3118](https://github.com/cookiecutter/cookiecutter-django/pull/3118)) +- Update django-extensions to 3.1.2 ([#3116](https://github.com/cookiecutter/cookiecutter-django/pull/3116)) +- Update pillow to 8.2.0 ([#3113](https://github.com/cookiecutter/cookiecutter-django/pull/3113)) +- Update pytest to 6.2.3 ([#3115](https://github.com/cookiecutter/cookiecutter-django/pull/3115)) + +## [2021-03-26] +### Updated +- Update djangorestframework to 3.12.4 ([#3107](https://github.com/cookiecutter/cookiecutter-django/pull/3107)) + +## [2021-03-25] +### Updated +- Update djangorestframework to 3.12.3 ([#3105](https://github.com/cookiecutter/cookiecutter-django/pull/3105)) + +## [2021-03-22] +### Updated +- Update django-crispy-forms to 1.11.2 ([#3104](https://github.com/cookiecutter/cookiecutter-django/pull/3104)) +- Update sphinx to 3.5.3 ([#3103](https://github.com/cookiecutter/cookiecutter-django/pull/3103)) +- Update ipdb to 0.13.7 ([#3102](https://github.com/cookiecutter/cookiecutter-django/pull/3102)) +- Update sphinx-autobuild to 2021.3.14 ([#3101](https://github.com/cookiecutter/cookiecutter-django/pull/3101)) +- Update isort to 5.8.0 ([#3100](https://github.com/cookiecutter/cookiecutter-django/pull/3100)) +- Update pre-commit to 2.11.1 ([#3089](https://github.com/cookiecutter/cookiecutter-django/pull/3089)) +- Update flake8 to 3.9.0 ([#3096](https://github.com/cookiecutter/cookiecutter-django/pull/3096)) +- Update pillow to 8.1.2 ([#3084](https://github.com/cookiecutter/cookiecutter-django/pull/3084)) +- Auto-update pre-commit hooks ([#3095](https://github.com/cookiecutter/cookiecutter-django/pull/3095)) + +## [2021-03-05] +### Changed +- Updated test_urls.py and views.py to re-use User.get_absolute_url() ([#3070](https://github.com/cookiecutter/cookiecutter-django/pull/3070)) +### Updated +- Bump stefanzweifel/git-auto-commit-action from v4.9.1 to v4.9.2 ([#3082](https://github.com/cookiecutter/cookiecutter-django/pull/3082)) + +## [2021-03-03] +### Updated +- Update tox to 3.23.0 ([#3079](https://github.com/cookiecutter/cookiecutter-django/pull/3079)) +- Update ipdb to 0.13.5 ([#3078](https://github.com/cookiecutter/cookiecutter-django/pull/3078)) + +## [2021-03-02] +### Fixed +- Fixes for pytest job in Github CI workflow ([#3076](https://github.com/cookiecutter/cookiecutter-django/pull/3076)) +### Updated +- Update pillow to 8.1.1 ([#3075](https://github.com/cookiecutter/cookiecutter-django/pull/3075)) +- Update coverage to 5.5 ([#3074](https://github.com/cookiecutter/cookiecutter-django/pull/3074)) + +## [2021-02-24] +### Updated +- Bump stefanzweifel/git-auto-commit-action from v4.9.0 to v4.9.1 ([#3069](https://github.com/cookiecutter/cookiecutter-django/pull/3069)) + +## [2021-02-23] +### Changed +- Update to Django 3.1 ([#3043](https://github.com/cookiecutter/cookiecutter-django/pull/3043)) +- Lint with pre-commit on CI with Github actions ([#3066](https://github.com/cookiecutter/cookiecutter-django/pull/3066)) +- Use exception var in status code pages if available ([#2992](https://github.com/cookiecutter/cookiecutter-django/pull/2992)) + +## [2021-02-22] +### Changed +- refactor: remove default cache settings in test.py ([#3064](https://github.com/cookiecutter/cookiecutter-django/pull/3064)) +- Update django to 3.0.13 ([#3060](https://github.com/cookiecutter/cookiecutter-django/pull/3060)) +### Fixed +- Fix missing Django Debug toolbar with node container ([#2865](https://github.com/cookiecutter/cookiecutter-django/pull/2865)) +- Remove Email from User API ([#3055](https://github.com/cookiecutter/cookiecutter-django/pull/3055)) +### Updated +- Bump stefanzweifel/git-auto-commit-action from v4.8.0 to v4.9.0 ([#3065](https://github.com/cookiecutter/cookiecutter-django/pull/3065)) +- Update django-crispy-forms to 1.11.1 ([#3063](https://github.com/cookiecutter/cookiecutter-django/pull/3063)) +- Update uvicorn to 0.13.4 ([#3062](https://github.com/cookiecutter/cookiecutter-django/pull/3062)) +- Update mypy to 0.812 ([#3061](https://github.com/cookiecutter/cookiecutter-django/pull/3061)) +- Update sentry-sdk to 0.20.3 ([#3059](https://github.com/cookiecutter/cookiecutter-django/pull/3059)) +- Update tox to 3.22.0 ([#3057](https://github.com/cookiecutter/cookiecutter-django/pull/3057)) +- Update sphinx to 3.5.1 ([#3056](https://github.com/cookiecutter/cookiecutter-django/pull/3056)) + +## [2021-02-16] +### Updated +- Update sentry-sdk to 0.20.2 ([#3054](https://github.com/cookiecutter/cookiecutter-django/pull/3054)) +- Update sphinx to 3.5.0 ([#3053](https://github.com/cookiecutter/cookiecutter-django/pull/3053)) + +## [2021-02-13] +### Updated +- Update sentry-sdk to 0.20.1 ([#3052](https://github.com/cookiecutter/cookiecutter-django/pull/3052)) + +## [2021-02-12] +### Updated +- Update pre-commit to 2.10.1 ([#3045](https://github.com/cookiecutter/cookiecutter-django/pull/3045)) +- Update sentry-sdk to 0.20.0 ([#3051](https://github.com/cookiecutter/cookiecutter-django/pull/3051)) + +## [2021-02-10] +### Updated +- Bump peter-evans/create-pull-request from v3.8.1 to v3.8.2 ([#3049](https://github.com/cookiecutter/cookiecutter-django/pull/3049)) + +## [2021-02-08] +### Updated +- Update django-extensions to 3.1.1 ([#3047](https://github.com/cookiecutter/cookiecutter-django/pull/3047)) +- Bump peter-evans/create-pull-request from v3.8.0 to v3.8.1 ([#3046](https://github.com/cookiecutter/cookiecutter-django/pull/3046)) + +## [2021-02-06] +### Changed +- Removed Redundant test_case_sensitivity() and made test_not_authenticated() get the LOGIN_URL dynamically. ([#3041](https://github.com/cookiecutter/cookiecutter-django/pull/3041)) +- Refactored users.forms to make the code more readeable ([#3029](https://github.com/cookiecutter/cookiecutter-django/pull/3029)) +- Update django to 3.0.12 ([#3037](https://github.com/cookiecutter/cookiecutter-django/pull/3037)) +### Updated +- Update tox to 3.21.4 ([#3044](https://github.com/cookiecutter/cookiecutter-django/pull/3044)) + +## [2021-02-01] +### Updated +- Update pytz to 2021.1 ([#3035](https://github.com/cookiecutter/cookiecutter-django/pull/3035)) +- Update jinja2 to 2.11.3 ([#3033](https://github.com/cookiecutter/cookiecutter-django/pull/3033)) +- Bump peter-evans/create-pull-request from v3.7.0 to v3.8.0 ([#3034](https://github.com/cookiecutter/cookiecutter-django/pull/3034)) + +## [2021-01-31] +### Changed +- Adding local celery instructions to developing-locally ([#3031](https://github.com/cookiecutter/cookiecutter-django/pull/3031)) +### Updated +- Update django-crispy-forms to 1.11.0 ([#3032](https://github.com/cookiecutter/cookiecutter-django/pull/3032)) + +## [2021-01-28] +### Updated +- Update pre-commit to 2.10.0 ([#3028](https://github.com/cookiecutter/cookiecutter-django/pull/3028)) +- Update django-anymail to 8.2 ([#3027](https://github.com/cookiecutter/cookiecutter-django/pull/3027)) +- Update tox to 3.21.3 ([#3026](https://github.com/cookiecutter/cookiecutter-django/pull/3026)) + +## [2021-01-26] +### Changed +- Bump peter-evans/create-pull-request from v3.6.0 to v3.7.0 ([#3022](https://github.com/cookiecutter/cookiecutter-django/pull/3022)) +- Using SuccessMessageMixin to send success message to django template ([#3021](https://github.com/cookiecutter/cookiecutter-django/pull/3021)) +### Fixed +- Update admin to ignore *_name User attributes ([#3018](https://github.com/cookiecutter/cookiecutter-django/pull/3018)) +### Updated +- Update coverage to 5.4 ([#3024](https://github.com/cookiecutter/cookiecutter-django/pull/3024)) +- Update pytest to 6.2.2 ([#3020](https://github.com/cookiecutter/cookiecutter-django/pull/3020)) +- Update django-cors-headers to 3.7.0 ([#3019](https://github.com/cookiecutter/cookiecutter-django/pull/3019)) + +## [2021-01-24] +### Changed +- Use defer for script tags (Fix #2922) ([#2927](https://github.com/cookiecutter/cookiecutter-django/pull/2927)) +- Made Traefik conf much easier to understand and improved redirect res… ([#2838](https://github.com/cookiecutter/cookiecutter-django/pull/2838)) +- Sentry Redis integration enabled by default in production. ([#2989](https://github.com/cookiecutter/cookiecutter-django/pull/2989)) +- Add test for UserUpdateView.form_valid() ([#2949](https://github.com/cookiecutter/cookiecutter-django/pull/2949)) +### Fixed +- Omit first_name and last_name in User model ([#2998](https://github.com/cookiecutter/cookiecutter-django/pull/2998)) +### Updated +- Update django-celery-beat to 2.2.0 ([#3009](https://github.com/cookiecutter/cookiecutter-django/pull/3009)) +- Update pyyaml to 5.4.1 ([#3011](https://github.com/cookiecutter/cookiecutter-django/pull/3011)) +- Update mypy to 0.800 ([#3013](https://github.com/cookiecutter/cookiecutter-django/pull/3013)) +- Update factory-boy to 3.2.0 ([#2986](https://github.com/cookiecutter/cookiecutter-django/pull/2986)) +- Update tox to 3.21.2 ([#3010](https://github.com/cookiecutter/cookiecutter-django/pull/3010)) + +## [2021-01-22] +### Changed +- Use self.request.user instead of second query ([#3012](https://github.com/cookiecutter/cookiecutter-django/pull/3012)) + +## [2021-01-14] +### Updated +- Update tox to 3.21.1 ([#3006](https://github.com/cookiecutter/cookiecutter-django/pull/3006)) + +## [2021-01-10] +### Updated +- Update pylint-django to 2.4.2 ([#3003](https://github.com/cookiecutter/cookiecutter-django/pull/3003)) +- Update tox to 3.21.0 ([#3002](https://github.com/cookiecutter/cookiecutter-django/pull/3002)) + +## [2021-01-08] +### Changed +- Upgrade Travis to Focal ([#2999](https://github.com/cookiecutter/cookiecutter-django/pull/2999)) +### Updated +- Update pylint-django to 2.4.1 ([#3001](https://github.com/cookiecutter/cookiecutter-django/pull/3001)) +- Update sphinx to 3.4.3 ([#3000](https://github.com/cookiecutter/cookiecutter-django/pull/3000)) +- Update pylint-django to 2.4.0 ([#2996](https://github.com/cookiecutter/cookiecutter-django/pull/2996)) + +## [2021-01-04] +### Updated +- Update isort to 5.7.0 ([#2988](https://github.com/cookiecutter/cookiecutter-django/pull/2988)) +- Update uvicorn to 0.13.3 ([#2987](https://github.com/cookiecutter/cookiecutter-django/pull/2987)) +- Auto-update pre-commit hooks ([#2990](https://github.com/cookiecutter/cookiecutter-django/pull/2990)) +- Update sphinx to 3.4.2 ([#2995](https://github.com/cookiecutter/cookiecutter-django/pull/2995)) +- Update pillow to 8.1.0 ([#2993](https://github.com/cookiecutter/cookiecutter-django/pull/2993)) + +## [2020-12-29] +### Updated +- Update pygithub to 1.54.1 ([#2982](https://github.com/cookiecutter/cookiecutter-django/pull/2982)) +- Update django-storages to 1.11.1 ([#2981](https://github.com/cookiecutter/cookiecutter-django/pull/2981)) + +## [2020-12-26] +### Updated +- Update sphinx to 3.4.1 ([#2985](https://github.com/cookiecutter/cookiecutter-django/pull/2985)) +- Update pytz to 2020.5 ([#2984](https://github.com/cookiecutter/cookiecutter-django/pull/2984)) + +## [2020-12-23] +### Changed +- Bump peter-evans/create-pull-request from v3.5.2 to v3.6.0 ([#2980](https://github.com/cookiecutter/cookiecutter-django/pull/2980)) +### Updated +- Update flower to 0.9.7 ([#2979](https://github.com/cookiecutter/cookiecutter-django/pull/2979)) +- Update sphinx to 3.4.0 ([#2978](https://github.com/cookiecutter/cookiecutter-django/pull/2978)) +- Update coverage to 5.3.1 ([#2977](https://github.com/cookiecutter/cookiecutter-django/pull/2977)) +- Update uvicorn to 0.13.2 ([#2976](https://github.com/cookiecutter/cookiecutter-django/pull/2976)) + +## [2020-12-18] +### Changed +- Bump stefanzweifel/git-auto-commit-action from v4.7.2 to v4.8.0 ([#2972](https://github.com/cookiecutter/cookiecutter-django/pull/2972)) +### Updated +- Update django-storages to 1.11 ([#2973](https://github.com/cookiecutter/cookiecutter-django/pull/2973)) +- Update pytest to 6.2.1 ([#2971](https://github.com/cookiecutter/cookiecutter-django/pull/2971)) +- Auto-update pre-commit hooks ([#2970](https://github.com/cookiecutter/cookiecutter-django/pull/2970)) + +## [2020-12-14] +### Updated +- Update pytest to 6.2.0 ([#2968](https://github.com/cookiecutter/cookiecutter-django/pull/2968)) +- Update django-cors-headers to 3.6.0 ([#2967](https://github.com/cookiecutter/cookiecutter-django/pull/2967)) +- Update uvicorn to 0.13.1 ([#2966](https://github.com/cookiecutter/cookiecutter-django/pull/2966)) + +## [2020-12-10] +### Changed +- Hot-reload support to celery ([#2554](https://github.com/cookiecutter/cookiecutter-django/pull/2554)) +### Updated +- Update uvicorn to 0.13.0 ([#2962](https://github.com/cookiecutter/cookiecutter-django/pull/2962)) +- Update sentry-sdk to 0.19.5 ([#2965](https://github.com/cookiecutter/cookiecutter-django/pull/2965)) + +## [2020-12-09] +### Changed +- Bump peter-evans/create-pull-request from v3.5.1 to v3.5.2 ([#2964](https://github.com/cookiecutter/cookiecutter-django/pull/2964)) + +## [2020-12-08] +### Updated +- Update pre-commit to 2.9.3 ([#2961](https://github.com/cookiecutter/cookiecutter-django/pull/2961)) + +## [2020-12-04] +### Updated +- Update django-debug-toolbar to 3.2 ([#2959](https://github.com/cookiecutter/cookiecutter-django/pull/2959)) + +## [2020-12-02] +### Updated +- Update django-model-utils to 4.1.1 ([#2957](https://github.com/cookiecutter/cookiecutter-django/pull/2957)) +- Update pygithub to 1.54 ([#2958](https://github.com/cookiecutter/cookiecutter-django/pull/2958)) + +## [2020-11-26] +### Updated +- Update django-extensions to 3.1.0 ([#2947](https://github.com/cookiecutter/cookiecutter-django/pull/2947)) +- Update pre-commit to 2.9.2 ([#2948](https://github.com/cookiecutter/cookiecutter-django/pull/2948)) +- Update django-allauth to 0.44.0 ([#2945](https://github.com/cookiecutter/cookiecutter-django/pull/2945)) + +## [2020-11-25] +### Changed +- Bump peter-evans/create-pull-request from v3.5.0 to v3.5.1 ([#2944](https://github.com/cookiecutter/cookiecutter-django/pull/2944)) + +## [2020-11-23] +### Updated +- Update uvicorn to 0.12.3 ([#2943](https://github.com/cookiecutter/cookiecutter-django/pull/2943)) +- Update pre-commit to 2.9.0 ([#2942](https://github.com/cookiecutter/cookiecutter-django/pull/2942)) + +## [2020-11-21] +### Changed +- Fix after uvicorn 0.12.0 - Ship extra dependencies ([#2939](https://github.com/cookiecutter/cookiecutter-django/pull/2939)) + +## [2020-11-20] +### Updated +- Update sentry-sdk to 0.19.4 ([#2938](https://github.com/cookiecutter/cookiecutter-django/pull/2938)) + +## [2020-11-19] +### Updated +- Update django-crispy-forms to 1.10.0 ([#2937](https://github.com/cookiecutter/cookiecutter-django/pull/2937)) + +## [2020-11-17] +### Changed +- Bump peter-evans/create-pull-request from v2 to v3.5.0 ([#2936](https://github.com/cookiecutter/cookiecutter-django/pull/2936)) + +## [2020-11-15] +### Changed +- Fix formatting in docs ([#2935](https://github.com/cookiecutter/cookiecutter-django/pull/2935)) + +## [2020-11-13] +### Changed +- Upgrade factory-boy to 3.1.0 ([#2932](https://github.com/cookiecutter/cookiecutter-django/pull/2932)) +### Updated +- Update sentry-sdk to 0.19.3 ([#2933](https://github.com/cookiecutter/cookiecutter-django/pull/2933)) +- Update sphinx to 3.3.1 ([#2934](https://github.com/cookiecutter/cookiecutter-django/pull/2934)) + +## [2020-11-12] +### Changed +- Migrate CI to Github Actions ([#2931](https://github.com/cookiecutter/cookiecutter-django/pull/2931)) + +## [2020-11-06] +### Updated +- Update djangorestframework to 3.12.2 ([#2930](https://github.com/cookiecutter/cookiecutter-django/pull/2930)) + +## [2020-11-04] +### Changed +- Fix docs service and add RTD support ([#2920](https://github.com/cookiecutter/cookiecutter-django/pull/2920)) +- Bump stefanzweifel/git-auto-commit-action from v4.6.0 to v4.7.2 ([#2914](https://github.com/cookiecutter/cookiecutter-django/pull/2914)) +### Updated +- Auto-update pre-commit hooks ([#2908](https://github.com/cookiecutter/cookiecutter-django/pull/2908)) +- Update mypy to 0.790 ([#2886](https://github.com/cookiecutter/cookiecutter-django/pull/2886)) +- Update django-stubs to 1.7.0 ([#2916](https://github.com/cookiecutter/cookiecutter-django/pull/2916)) + +## [2020-11-03] +### Updated +- Update sentry-sdk to 0.19.2 ([#2926](https://github.com/cookiecutter/cookiecutter-django/pull/2926)) +- Update sphinx to 3.3.0 ([#2925](https://github.com/cookiecutter/cookiecutter-django/pull/2925)) +- Update django to 3.0.11 ([#2924](https://github.com/cookiecutter/cookiecutter-django/pull/2924)) +- Update pytz to 2020.4 ([#2923](https://github.com/cookiecutter/cookiecutter-django/pull/2923)) +- Update pre-commit to 2.8.2 ([#2919](https://github.com/cookiecutter/cookiecutter-django/pull/2919)) +- Update pytest to 6.1.2 ([#2917](https://github.com/cookiecutter/cookiecutter-django/pull/2917)) +- Update sh to 1.14.1 ([#2912](https://github.com/cookiecutter/cookiecutter-django/pull/2912)) +- Update pytest-django to 4.1.0 ([#2911](https://github.com/cookiecutter/cookiecutter-django/pull/2911)) +- Update pillow to 8.0.1 ([#2910](https://github.com/cookiecutter/cookiecutter-django/pull/2910)) +- Update django-celery-beat to 2.1.0 ([#2907](https://github.com/cookiecutter/cookiecutter-django/pull/2907)) +- Update uvicorn to 0.12.2 ([#2906](https://github.com/cookiecutter/cookiecutter-django/pull/2906)) + +## [2020-10-19] +### Updated +- Update sentry-sdk to 0.19.1 ([#2905](https://github.com/cookiecutter/cookiecutter-django/pull/2905)) + +## [2020-10-17] +### Updated +- Update django-allauth to 0.43.0 ([#2901](https://github.com/cookiecutter/cookiecutter-django/pull/2901)) +- Update pytest-django to 4.0.0 ([#2903](https://github.com/cookiecutter/cookiecutter-django/pull/2903)) + +## [2020-10-15] +### Updated +- Update pillow to 8.0.0 ([#2898](https://github.com/cookiecutter/cookiecutter-django/pull/2898)) + +## [2020-10-14] +### Updated +- Auto-update pre-commit hooks ([#2897](https://github.com/cookiecutter/cookiecutter-django/pull/2897)) +- Update sentry-sdk to 0.19.0 ([#2896](https://github.com/cookiecutter/cookiecutter-django/pull/2896)) + +## [2020-10-13] +### Updated +- Update isort to 5.6.4 ([#2895](https://github.com/cookiecutter/cookiecutter-django/pull/2895)) + +## [2020-10-12] +### Changed +- Bump stefanzweifel/git-auto-commit-action from v4.5.1 to v4.6.0 ([#2893](https://github.com/cookiecutter/cookiecutter-django/pull/2893)) +### Updated +- Auto-update pre-commit hooks ([#2892](https://github.com/cookiecutter/cookiecutter-django/pull/2892)) + +## [2020-10-11] +### Updated +- Auto-update pre-commit hooks ([#2890](https://github.com/cookiecutter/cookiecutter-django/pull/2890)) +- Update isort to 5.6.3 ([#2891](https://github.com/cookiecutter/cookiecutter-django/pull/2891)) +- Update django-anymail to 8.1 ([#2887](https://github.com/cookiecutter/cookiecutter-django/pull/2887)) +- Update tox to 3.20.1 ([#2885](https://github.com/cookiecutter/cookiecutter-django/pull/2885)) + +## [2020-10-09] +### Updated +- Auto-update pre-commit hooks ([#2884](https://github.com/cookiecutter/cookiecutter-django/pull/2884)) +- Update isort to 5.6.1 ([#2883](https://github.com/cookiecutter/cookiecutter-django/pull/2883)) + +## [2020-10-08] +### Changed +- Add dedicated websockets package ([#2881](https://github.com/cookiecutter/cookiecutter-django/pull/2881)) +### Updated +- Update isort to 5.6.0 ([#2882](https://github.com/cookiecutter/cookiecutter-django/pull/2882)) + +## [2020-10-04] +### Updated +- Update pytest to 6.1.1 ([#2880](https://github.com/cookiecutter/cookiecutter-django/pull/2880)) +- Update mypy and django-stubs ([#2874](https://github.com/cookiecutter/cookiecutter-django/pull/2874)) +- Auto-update pre-commit hooks ([#2876](https://github.com/cookiecutter/cookiecutter-django/pull/2876)) +- Update flake8 to 3.8.4 ([#2877](https://github.com/cookiecutter/cookiecutter-django/pull/2877)) + +## [2020-10-01] +### Changed +- Bump actions/setup-python from v2.1.2 to v2.1.3 ([#2869](https://github.com/cookiecutter/cookiecutter-django/pull/2869)) +### Updated +- Update ipdb to 0.13.4 ([#2873](https://github.com/cookiecutter/cookiecutter-django/pull/2873)) +- Auto-update pre-commit hooks ([#2867](https://github.com/cookiecutter/cookiecutter-django/pull/2867)) +- Update uvicorn to 0.12.1 ([#2866](https://github.com/cookiecutter/cookiecutter-django/pull/2866)) +- Update isort to 5.5.4 ([#2864](https://github.com/cookiecutter/cookiecutter-django/pull/2864)) +- Update sentry-sdk to 0.18.0 ([#2863](https://github.com/cookiecutter/cookiecutter-django/pull/2863)) +- Update djangorestframework to 3.12.1 ([#2862](https://github.com/cookiecutter/cookiecutter-django/pull/2862)) +- Update pytest to 6.1.0 ([#2859](https://github.com/cookiecutter/cookiecutter-django/pull/2859)) +- Update django-debug-toolbar to 3.1.1 ([#2855](https://github.com/cookiecutter/cookiecutter-django/pull/2855)) + +## [2020-09-23] +### Updated +- Update sentry-sdk to 0.17.7 ([#2847](https://github.com/cookiecutter/cookiecutter-django/pull/2847)) +- Update django-debug-toolbar to 3.1 ([#2846](https://github.com/cookiecutter/cookiecutter-django/pull/2846)) + +## [2020-09-21] +### Changed +- Adding GitHub-Action CI Option ([#2837](https://github.com/cookiecutter/cookiecutter-django/pull/2837)) +### Updated +- Update django-debug-toolbar to 3.0 ([#2842](https://github.com/cookiecutter/cookiecutter-django/pull/2842)) +- Auto-update pre-commit hooks ([#2843](https://github.com/cookiecutter/cookiecutter-django/pull/2843)) +- Update isort to 5.5.3 ([#2844](https://github.com/cookiecutter/cookiecutter-django/pull/2844)) + +## [2020-09-18] +### Updated +- Update django-extensions to 3.0.9 ([#2839](https://github.com/cookiecutter/cookiecutter-django/pull/2839)) + +## [2020-09-16] +### Updated +- Update sentry-sdk to 0.17.6 ([#2833](https://github.com/cookiecutter/cookiecutter-django/pull/2833)) +- Update pytest-django to 3.10.0 ([#2832](https://github.com/cookiecutter/cookiecutter-django/pull/2832)) + +## [2020-09-14] +### Fixed +- Downgrade Celery to 4.4.6 ([#2829](https://github.com/cookiecutter/cookiecutter-django/pull/2829)) +### Updated +- Update sentry-sdk to 0.17.5 ([#2828](https://github.com/cookiecutter/cookiecutter-django/pull/2828)) +- Update coverage to 5.3 ([#2826](https://github.com/cookiecutter/cookiecutter-django/pull/2826)) +- Update django-storages to 1.10.1 ([#2825](https://github.com/cookiecutter/cookiecutter-django/pull/2825)) + +## [2020-09-12] +### Updated +- Updating Traefik version from 2.0 to 2.2.11 ([#2814](https://github.com/cookiecutter/cookiecutter-django/pull/2814)) +- Update pytest to 6.0.2 ([#2819](https://github.com/cookiecutter/cookiecutter-django/pull/2819)) +- Update django-anymail to 8.0 ([#2818](https://github.com/cookiecutter/cookiecutter-django/pull/2818)) + +## [2020-09-11] +### Updated +- Auto-update pre-commit hooks ([#2809](https://github.com/cookiecutter/cookiecutter-django/pull/2809)) + +## [2020-09-10] +### Updated +- Update isort to 5.5.2 ([#2807](https://github.com/cookiecutter/cookiecutter-django/pull/2807)) +- Update sentry-sdk to 0.17.4 ([#2805](https://github.com/cookiecutter/cookiecutter-django/pull/2805)) + +## [2020-09-09] +### Changed +- Update actions/setup-python requirement to v2.1.2 ([#2804](https://github.com/cookiecutter/cookiecutter-django/pull/2804)) +- Clean up nested venv files from `.gitignore` ([#2800](https://github.com/cookiecutter/cookiecutter-django/pull/2800)) + +## [2020-09-08] +### Changed +- Traeffik and Django dockerfile changes ([#2801](https://github.com/cookiecutter/cookiecutter-django/pull/2801)) + +## [2020-09-07] +### Changed +- Add :z/:Z to mounted volumes in {local,production}.yml ([#2663](https://github.com/cookiecutter/cookiecutter-django/pull/2663)) +- Remove --no-binary option for psycopg2 ([#2798](https://github.com/cookiecutter/cookiecutter-django/pull/2798)) +- Updated Gitlab CI to use Python 3.8 instead of Python 3.7 ([#2794](https://github.com/cookiecutter/cookiecutter-django/pull/2794)) +### Fixed +- Fix options for sphinx-autobuild in docs Makefile ([#2799](https://github.com/cookiecutter/cookiecutter-django/pull/2799)) +### Updated +- Update psycopg2-binary to 2.8.6 ([#2797](https://github.com/cookiecutter/cookiecutter-django/pull/2797)) + +## [2020-09-05] +### Updated +- Auto-update pre-commit hooks ([#2793](https://github.com/cookiecutter/cookiecutter-django/pull/2793)) + +## [2020-09-04] +### Updated +- Update django-extensions to 3.0.8 ([#2792](https://github.com/cookiecutter/cookiecutter-django/pull/2792)) +- Update isort to 5.5.1 ([#2791](https://github.com/cookiecutter/cookiecutter-django/pull/2791)) +- Auto-update pre-commit hooks ([#2790](https://github.com/cookiecutter/cookiecutter-django/pull/2790)) +- Update isort to 5.5.0 ([#2789](https://github.com/cookiecutter/cookiecutter-django/pull/2789)) + +## [2020-09-02] +### Changed +- Add environment and traces_sample_rate keyword to sentry_sdk.init ([#2777](https://github.com/cookiecutter/cookiecutter-django/pull/2777)) +### Updated +- Update sentry-sdk to 0.17.3 ([#2788](https://github.com/cookiecutter/cookiecutter-django/pull/2788)) +- Update django-extensions to 3.0.7 ([#2787](https://github.com/cookiecutter/cookiecutter-django/pull/2787)) + +## [2020-09-01] +### Changed +- Exclude venv directory and update document link ([#2780](https://github.com/cookiecutter/cookiecutter-django/pull/2780)) +### Updated +- Update tox to 3.20.0 ([#2786](https://github.com/cookiecutter/cookiecutter-django/pull/2786)) +- Update django-storages to 1.10 ([#2781](https://github.com/cookiecutter/cookiecutter-django/pull/2781)) +- Update sentry-sdk to 0.17.2 ([#2784](https://github.com/cookiecutter/cookiecutter-django/pull/2784)) +- Update django to 3.0.10 ([#2785](https://github.com/cookiecutter/cookiecutter-django/pull/2785)) +- Update sphinx-autobuild to 2020.9.1 ([#2782](https://github.com/cookiecutter/cookiecutter-django/pull/2782)) +- Update django-extensions to 3.0.6 ([#2783](https://github.com/cookiecutter/cookiecutter-django/pull/2783)) + +## [2020-08-31] +### Updated +- Update sh to 1.14.0 ([#2779](https://github.com/cookiecutter/cookiecutter-django/pull/2779)) +- Update sentry-sdk to 0.17.1 ([#2778](https://github.com/cookiecutter/cookiecutter-django/pull/2778)) + +## [2020-04-13] +### Changed +- Updated to Python 3.8 (@codnee) +- Moved coverage config in setup.cfg (@danihodovic) + +## [2020-04-08] +### Fixed +- Internal IPs for debug toolbar (@dudanogueira) + +## [2020-04-04] +### Fixed +- Added compress command with Django compressor (@gwiskur) + +## [2020-03-23] +### Changed +- Updated project to Django 3.0 + +## [2020-03-17] +### Changed +- Handle paths using Pathlib (@jules-ch) + +### Fixed +- Pre-commit hook regex (@demestav) + +## [2020-03-16] ### Added -- Added `DJANGO_ADMIN_FORCE_ALLAUTH` environment variable to force the `admin` sign in process to go through the `django-allauth` workflow +- Support for all Anymail providers (@Andrew-Chen-Wang) +### Fixed +- Django compressor setup (@jameswilliams1) + +## [2020-01-23] +### Changed +- Fix UserFactory to set the password if provided (@BoPeng) +- Update documentation files with latest Sphinx (@howiezhao) + +## [2020-01-12] +### Changed +- Fix mypy setup and added django-stubs (@danifus) +- Add Gitlab CI as option (@ikhomutov) + +## [2020-01-11] +### Changed +- Speed up & reduce size for production Django image (@maxp) +- Bumped runtime version for Heroku (@Isaac12x) +- Added Debian 10 (Buster) OS dependencies (@ddiazpinto) +- Update Traefik to v2 (@blaxpy) +- Switched Docker images from Alpine based to Debian based (@trungdong) + +## [2019-10-06] +### Changed +- Default Python version is now 3.7 (@nicolas471) + +## [2019-10-04] +### Fixed +- Fix static files handling on GCP (@caioariede) + +## [2019-10-03] +### Fixed +- Fix incompatible combination between Whitenoise and no cloud provider (@caioariede) + +## [2019-07-09] +### Fixed +- Always use test settings in pytest (@danihodovic) +- Remove gunicorn from `INSTALLED_APPS` (@danihodovic) +- Remove `EMAIL_HOST` and `EMAIL_PORT` with locmem backend (@danihodovic) + +### Added +- Add `EMAIL_TIMEOUT` (@danihodovic) + +## [2019-06-22] +### Fixed +- Remove redundant template debug setting (@danihodovic) + +## [2019-06-19] +### Fixed +- Fix removal carriage returns in docker scripts (@timclaessens) + +## [2019-06-15] +### Fixed +- Issue with Pycharm setup for running things in Docker compose (@foarsitter) + +## [2019-06-06] +### Changed +- Update generated Travis config (@browniebroke) + +## [2019-06-03] +### Added +- Installed `django-celery-beat` to keep scheduled tasks in DB (@keyvanm) + +## [2019-05-28] +### Changed +- Use GCP acronym rather than inconsistent GCE/GCS (@tanoabeleyra) + +## [2019-05-27] +### Changed +- Made cloud provider optional (@tanoabeleyra) +- Updated to Django 2.2.1 (@browniebroke) + +### Fixed +- Celery worker-related setting names (@browniebroke) + +## [2019-05-18] +### Removed +- Remove the user list view (@browniebroke) + +### Fixed +- Static storage default ACL (@browniebroke) + +## [2019-05-17] +### Fixed +- Added `LocaleMiddleware` to the list of middlewares (@tanoabeleyra) +- Added `LOCALE_PATH` to settings (@tanoabeleyra) + +## [2019-05-16] +### Changed +- Users app to have a translated verbose name (@tanoabeleyra) +- Logging configuration for local (@browniebroke) + +## [2019-05-08] +### Changed +- Upgraded to Django 2.1 (@browniebroke) + +## [2019-04-07] +### Added +- Support for Google Cloud Storage (@ahhda) + +## [2019-04-03] +### Added +- Command to backup Db to AWS S3 (@foarsitter) + +## [2019-03-25] +### Added +- Node image to run Gulp with Docker (@browniebroke) + +## [2019-03-19] +### Changed +- Replaced Caddy with Traefik (@demestav) + +## [2019-03-11] +### Changed +- Sentry integration from Raven to Sentry-SDK (@gfabricio) +- Made Redis config conditional on Celery locally (@demestav) + +## [2019-03-11] +### Added +- Automatic migrations on Heroku (@yunti) + +## [2019-03-06] +### Fixed +- Missing script tag in Travis config (@btknu) + +## [2019-03-02] +### Changed +- Celery eager setting in local setting with Docker (@keithjeb) + +## [2019-03-01] +### Updated +- All NPM dependencies (@takkaria) + +## [2018-11-13] +### Changed +- Security settings in Dev (@carlmjohnson) + +## [2018-11-20] +### Fixed +- Passing the CSRF header from the reverse proxy to Django server for DRF (@hpbruna) + +## [2018-11-12] +### Fixed +- Initialisation of Celery app (@glasslion) + +## [2018-10-24] +### Fixed +- Persisting of iPython history between sessions (@davitovmasyan) + +### Added +- Postgres 10.5 option (@jleclanche) + +## [2018-09-18] +### Added +- Included `mypy` in dependencies and run it in tests (@apirobot) + +## [2018-09-18] +### Fixed +- Avoid `$` in environment variables to workaround a bug from django-environ (@browniebroke) + +## [2018-09-16] +### Fixed +- Bug in ordering of Middleware for production config (@ChrisPappalardo) + +## [2018-09-12] +### Fixed +- URLs for Static and Media for S3 buckets in regions other than N. Virginia (@umrashrf) + +## [2018-09-09] +### Changed +- Name of static and media storage classes (@sfdye) + +## [2018-09-01] +### Changed +- Make static and media storage fully-fledged classes (@erfaan) + +## [2018-08-28] +### Fixed +- Running tests in docker test script (@apirobot) + +## [2018-07-23] +### Changed +- Test commands to use pytest (@jcass77) + +### Removed +- Some hacks leftovers from Bootstrap v4 beta in `project.js` (@hendrikschneider) + +## [2018-07-12] +### Changed +- Upgraded to Bootstrap 4.1.1 (@mostaszewski) + +## [2018-06-25] +### Added +- Flower integration with Docker (@webyneter) + +## [2018-06-25] +### Changed +- Rewrite user app test to use a pytest style (@webyneter) + +## [2018-06-21] +### Added +- Extend & update Celery config (@webyneter & @apirobot) + +## [2018-05-25] +### Fixed +- Build issues due to incompatibility between libressl & openssl (@SassanoM) + +## [2018-05-21] +### Changed +- Updated Caddy to 0.11 and pin its version (@webyneter) + +## [2018-05-14] +### Changed +- Replace `awesome-slugify` by `python-slugify` (@hongquan) +- Migrate to Django 2.0+ URL style (@saschalalala) + +## [2018-05-05] +### Fixed +- Postgres backup & restore commands (@webyneter) + +## [2018-04-10] +### Changed +- Simplify configuration (@danidee10) + +## [2018-04-08] +### Added +- Adopt Black code style (@pydanny) + +## [2018-03-27] +### Fixed +- Simplified extra Celery config generated when opted out (@webyneter) + +## [2018-03-21] +### Removed +- Remove Opbeat support (@sfdye) + +## [2018-03-16] +### Fixed +- Install `psycopg2-binary` when using Docker locally (@browniebroke) + +## [2018-03-14] +### Fixed +- Fixed and improved Postgres backup & restore scripts (@webyneter) + +## [2018-03-10] +### Changed +- Simplify Mailgun setting (@browniebroke) + +## [2018-03-06] +### Changed +- Convert string formatting to f-strings (@sfdye) + +## [2018-03-01] +### Changed +- Celery to use JSON serialization by default (@adammsteele) +- Use Docker version from Travis to run tests (@browniebroke) ## [2018-02-16] ### Changed @@ -35,7 +3084,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Rename `MIDDLEWARE_CLASSES` to `MIDDLEWARE` to enable support to [new style middleware](https://github.com/django/deps/blob/master/final/0005-improved-middleware.rst) introduced in Django 1.10 (@luzfcb) - New setting `MAILGUN_SENDER_DOMAIN` to allow sending mail from any domain other than those registered with mailgun (@jangeador) - add `urlpatterns` configuration to django-debug-toolbar, because the automatic configuration of `urlpatterns` was removed from django-debug-toolbar (@luzfcb) -- Added Temporary workaround on `requirements/local.txt` to fix django-debug-toolbar issue: https://github.com/pydanny/cookiecutter-django/issues/827 (@luzfcb) +- Added Temporary workaround on `requirements/local.txt` to fix django-debug-toolbar issue: https://github.com/cookiecutter/cookiecutter-django/issues/827 (@luzfcb) ### Changed - Upgrade to Django 1.10.1 (@luzfcb) @@ -181,7 +3230,7 @@ d changed 'admin' url on `config/urls.py`, to stay the same as generated by djan ### [2016-05-01] ### Changed -- Restored the Pycharm project configuration files, that was accidentally removed in [15f350f](https://github.com/pydanny/cookiecutter-django/commit/15f350f05e2b49b4bdff0bdaa2b2ff260606e0f6) (@luzfcb @Newton715) +- Restored the Pycharm project configuration files, that was accidentally removed in [15f350f](https://github.com/cookiecutter/cookiecutter-django/commit/15f350f05e2b49b4bdff0bdaa2b2ff260606e0f6) (@luzfcb @Newton715) ### [2016-04-30] ### Changed @@ -305,7 +3354,7 @@ d changed 'admin' url on `config/urls.py`, to stay the same as generated by djan ## [2016-02-15] ### Changed - In `users` app adapter, fix `is_open_for_signup` missing parameter (@oryx2) -- Fixes and improvements in Hitch tests , see [#485](https://github.com/pydanny/cookiecutter-django/pull/485) (@crdoconnor) +- Fixes and improvements in Hitch tests , see [#485](https://github.com/cookiecutter/cookiecutter-django/pull/485) (@crdoconnor) ## [2016-02-12] diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..a7b21223b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +## Code of Conduct + +Everyone who interacts in the Cookiecutter project's codebase, issue trackers, chat rooms, and mailing lists is expected to follow the [PSF Code of Conduct](https://www.python.org/psf/conduct/) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..94ecbdd7d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# How to Contribute + +Always happy to get issues identified and pull requests! + +## General considerations + +1. Keep it small. The smaller the change, the more likely we are to accept. +2. Changes that fix a current issue get priority for review. +3. Check out [GitHub guide][submit-a-pr] if you've never created a pull request before. + +## Getting started + +1. Fork the repo +2. Clone your fork +3. Create a branch for your changes + +This last step is very important, don't start developing from master, it'll cause pain if you need to send another change later. + +## Testing + +You'll need to run the tests using Python 3.11. We recommend using [tox](https://tox.readthedocs.io/en/latest/) to run the tests. It will automatically create a fresh virtual environment and install our test dependencies, such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/). + +We'll also run the tests on GitHub actions when you send your pull request, but it's a good idea to run them locally before you send it. + +### Installation + +First, make sure that your version of Python is 3.11: + +```bash +$ python --version +Python 3.11.3 +``` + +Any version that starts with 3.11 will do. If you need to install it, you can get it from [python.org](https://www.python.org/downloads/). + +Then install `tox`, if not already installed: + +```bash +$ python -m pip install tox +``` + +### Run the template's test suite + +To run the tests of the template using the current Python version: + +```bash +$ tox -e py +``` + +This uses `pytest `under the hood, and you can pass options to it after a `--`. So to run a particular test: + +```bash +$ tox -e py -- -k test_default_configuration +``` + +For further information, please consult the [pytest usage docs](https://pytest.org/en/latest/how-to/usage.html#specifying-which-tests-to-run). + +### Run the generated project tests + +The template tests are checking that the generated project is fully rendered and that it passes `flake8`. We also have some test scripts which generate a specific project combination, install the dependencies, run the tests of the generated project, install FE dependencies and generate the docs. They will install the template dependencies, so make sure you create and activate a virtual environment first. + +```bash +$ python -m venv venv +$ source venv/bin/activate +``` + +These tests are slower and can be run with or without Docker: + +- Without Docker: `scripts/test_bare.sh` (for bare metal) +- With Docker: `scripts/test_docker.sh` + +All arguments to these scripts will be passed to the `cookiecutter` CLI, letting you set options, for example: + +```bash +$ scripts/test_bare.sh use_celery=y +``` + +## Submitting a pull request + +Once you're happy with your changes and they look ok locally, push and send send [a pull request][submit-a-pr] to the main repo, which will trigger the tests on GitHub actions. If they fail, try to fix them. A maintainer should take a look at your change and give you feedback or merge it. + +[submit-a-pr]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index cfe16740d..000000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,55 +0,0 @@ -How to Contribute -================= - -Always happy to get issues identified and pull requests! - -Getting your pull request merged in ------------------------------------- - -#. Keep it small. The smaller the pull request the more likely I'll pull it in. -#. Pull requests that fix a current issue get priority for review. -#. If you're not already in the `CONTRIBUTORS.rst` file, add yourself! - -Testing -------- - -Installation -~~~~~~~~~~~~ - -Please install `tox`_, which is a generic virtualenv management and test command line tool. - -`tox`_ is available for download from `PyPI`_ via `pip`_:: - - $ pip install tox - -It will automatically create a fresh virtual environment and install our test dependencies, -such as `pytest-cookies`_ and `flake8`_. - -Run the Tests -~~~~~~~~~~~~~ - -Tox uses py.test under the hood, hence it supports the same syntax for selecting tests. - -For further information please consult the `pytest usage docs`_. - -To run all tests using various versions of python in virtualenvs defined in tox.ini, just run tox.:: - - $ tox - -It is possible to test with a specific version of python. To do this, the command -is:: - - $ tox -e py36 - -This will run py.test with the python3.6 interpreter, for example. - -To run a particular test with tox for against your current Python version:: - - $ tox -e py -- -k test_default_configuration - -.. _`pytest usage docs`: https://pytest.org/latest/usage.html#specifying-tests-selecting-tests -.. _`tox`: https://tox.readthedocs.io/en/latest/ -.. _`pip`: https://pypi.python.org/pypi/pip/ -.. _`pytest-cookies`: https://pypi.python.org/pypi/pytest-cookies/ -.. _`flake8`: https://pypi.python.org/pypi/flake8/ -.. _`PyPI`: https://pypi.python.org/pypi diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 000000000..52072d8e2 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,1984 @@ +# Contributors + +## Core Developers + +These contributors have commit flags for the repository, and are able to +accept and merge pull requests. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameGithubTwitter
Daniel Roy Greenfeld + pydanny + pydanny
Audrey Roy Greenfeld + audreyr + audreyr
Fábio C. Barrionuevo da Luz + luzfcb + luzfcb
Saurabh Kumar + theskumar + _theskumar
Jannis Gebauer + jayfk +
Burhan Khalid + burhan + burhan
Shupeyko Nikita + webyneter + webyneter
Bruno Alla + browniebroke + _BrunoAlla
Wan Liuyang + sfdye + sfdye
Jelmer Draaijer + foarsitter +
+ +_Audrey is also the creator of Cookiecutter. Audrey and Daniel are on +the Cookiecutter core team._ + +## Other Contributors + +Listed in alphabetical order. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameGithubTwitter
18 + dezoito +
2O4 + 2O4 +
a7p + a7p +
Aadith PM + aadithpm +
Aaron Eikenberry + aeikenberry +
Abdul Qoyyuum + Qoyyuum + Qoyyuum
Abdullah Adeel + mabdullahadeel + abdadeel_
Abe Hanoka + abe-101 + abe__101
Adam Bogdał + bogdal +
Adam Dobrawy + ad-m +
Adam Steele + adammsteele +
Adin Hodovic + adinhodovic +
Agam Dua + +
Agustín Scaramuzza + scaramagus + scaramagus
Alberto Sanchez + alb3rto +
Alex Tsai + caffodian +
Alvaro [Andor] + andor-pierdelacabeza +
Amjith Ramanujam + amjith +
Andreas Meistad + ameistad +
Andres Gonzalez + andresgz +
Andrew Chen Wang + Andrew-Chen-Wang +
Andrew Mikhnevich + zcho +
Andy Rose + +
Anna Callahan + jazztpt +
Anna Sidwell + takkaria +
Antonia Blair + antoniablair + antoniablairart
Anuj Bansal + ahhda +
Arcuri Davide + dadokkio +
Areski Belaid + areski +
Arkadiusz Michał Ryś + arrys +
Arnav Choudhury + arnav13081994 +
Artur Barseghyan + barseghyanartur +
AsheKR + ashekr +
Ashley Camba + +
Barclay Gauld + yunti +
Bartek + btknu +
Ben Lopatin + +
Ben Warren + bwarren2 +
Benjamin Abel + +
Bert de Miranda + bertdemiranda +
Birtibu + Birtibu +
Bo Lopker + blopker +
Bo Peng + BoPeng +
Bogdan Mateescu + mateesville93 +
Bouke Haarsma + +
Brandon Rumiser + brumiser1550 +
Brent Payne + brentpayne + brentpayne
Bruce Olivier + bolivierjr +
Caio Ariede + caioariede + caioariede
Carl Johnson + carlmjohnson + carlmjohnson
Catherine Devlin + catherinedevlin +
Cebrail Yılmaz + b1sar +
Chao Yang Wu + goatwu1993 +
Charlie Macfarlane Brodie + tannart +
Charlie Smith + chuckus +
Chris Curvey + ccurvey +
Chris Franklin + +
Chris Franklin + hairychris +
Chris Pappalardo + ChrisPappalardo +
Christopher Clarke + chrisdev +
Cole Mackenzie + cmackenzie1 +
Cole Maclean + cole + cole
Collederas + Collederas +
Corey Garvey + coreygarvey +
Craig Margieson + cmargieson +
Cristian Vargas + cdvv7788 +
Cullen Rhodes + c-rhodes +
Curtis St Pierre + curtisstpierre + cstpierre1388
Cédric Gaspoz + cgaspoz +
dalrrard + dalrrard +
Dan Shultz + shultz +
Dani Hodovic + danihodovic +
Daniel Hepper + dhepper + danielhepper
Daniel Hillier + danifus +
Daniel Sears + highpost + highpost
Daniele Tricoli + eriol +
David + buckldav +
David Díaz + ddiazpinto + DavidDiazPinto
Davit Tovmasyan + davitovmasyan +
Davur Clementsen + dsclementsen + davur
Delio Castillo + jangeador + jangeador
Delphine LEMIRE + DelphineLemire +
Demetris Stavrou + demestav +
Denis Bobrov + delneg +
Denis Orehovsky + apirobot +
Denis Savran + blaxpy +
Diane Chen + purplediane + purplediane88
Diego Montes + d57montes +
Dong Huynh + trungdong +
Douglas + douglascdev +
Duda Nogueira + dudanogueira + dudanogueira
duffn + duffn +
Dónal Adams + epileptic-fish +
Emanuel Calso + bloodpet + bloodpet
enchance + enchance +
Eraldo Energy + eraldo +
Eric Groom + ericgroom +
Ernesto Cedeno + codnee +
Eyad Al Sibai + eyadsibai +
Fabian Affolter + fabaff + fabaff
Felipe Arruda + arruda +
Florian Idelberger + step21 + windrush
Floyd Hightower + fhightower +
Fuzzwah + Fuzzwah +
Gabriel Mejia + elgartoinf + elgartoinf
Garry Cairns + garry-cairns +
Garry Polley + garrypolley +
ghazi-git + ghazi-git +
Gilbishkosma + Gilbishkosma +
Glenn Wiskur + gwiskur +
Grant McLean + grantm + grantmnz
Guilherme Guy + guilherme1guy +
Hamish Durkin + durkode +
Hana Quadara + hanaquadara +
Hannah Lazarus + hanhanhan +
Harry Moreno + morenoh149 + morenoh149
Harry Percival + hjwp +
Haseeb ur Rehman + professorhaseeb + professorhaseeb
Hendrik Schneider + hendrikschneider +
Henrique G. G. Pereira + ikkebr +
Hoai-Thu Vuong + thuvh +
Howie Zhao + howiezhao +
Ian Lee + IanLee1521 +
innicoder + innicoder +
Irfan Ahmad + erfaan + erfaan
Isaac12x + Isaac12x +
Ivan Khomutov + ikhomutov +
Jakub Musko + umgelurgel +
James Williams + jameswilliams1 +
Jan Fabry + janfabry +
Jan Van Bruggen + jvanbrug +
Jens Nilsson + phiberjenz +
Jerome Caisip + jeromecaisip +
Jerome Leclanche + jleclanche + Adys
Jimmy Gitonga + Afrowave + afrowave
John + thorrak +
John Cass + jcass77 + cass_john
Jonathan Thompson + nojanath +
Jorge Valdez + jorgeavaldez +
jugglinmike + jugglinmike +
Jules Cheron + jules-ch +
Julien Almarcha + sladinji +
Julio Castillo + juliocc +
Kaido Kert + kaidokert +
kappataumu + kappataumu + kappataumu
Kaveh + ka7eh +
Keith Bailey + keithjeb +
Keith Callenberg + keithcallenberg +
Keith Webber + townie +
Kevin A. Stone + +
Kevin Ndung'u + kevgathuku +
Keyvan Mosharraf + keyvanm +
krati yadav + krati5 +
Krzysztof Szumny + noisy +
Krzysztof Żuraw + krzysztofzuraw +
Kuo Chao Cheng + wwwtony5488 +
lcd1232 + lcd1232 +
LECbg + LECbg +
Leifur Halldor Asgeirsson + leifurhauks +
Leo won + leollon +
Leo Zhou + glasslion +
Leon Kim + PilhwanKim +
Leonardo Jimenez + xpostudio4 +
Liam Brenner + SableWalnut +
Lin Xianyi + iynaix +
Luis Nell + originell +
Lukas Klein + +
Lyla Fischer + +
Malik Sulaimanov + flyudvik + flyudvik
Manjit Pardeshi + Manjit2003 +
Marcio Mazza + marciomazza + marciomazza
Martin Blech + +
Martin Saizar + msaizar +
Mateusz Ostaszewski + mostaszewski +
Matheus Jardim Bernardes + matheusjardimb +
Mathijs Hoogland + MathijsHoogland +
Matt Braymer-Hayes + mattayes + mattayes
Matt Knapper + mknapper1 +
Matt Linares + +
Matt Menzenski + menzenski +
Matt Warren + mfwarren +
Matthew Sisley + mjsisley +
Matthias Sieber + manonthemat + MatzeOne
Meghan Heintz + dot2dotseurat +
Meraj + ichbinmeraj + merajsafari
Mesut Yılmaz + myilmaz +
mfosterw + mfosterw +
Michael Gecht + mimischi + _mischi
Michael Samoylov + msamoylov +
Mike97M + Mike97M +
Min ho Kim + minho42 +
monosans + monosans +
Morten Kaae + MortenKaae +
mozillazg + mozillazg +
mpoli + mpoli +
mpsantos + mpsantos +
Naveen + naveensrinivasan + snaveen
Nico Stefani + nicolas471 + moby_dick91
Nikita Sobolev + sobolevn +
Noah H + nthall +
Oleg Russkin + rolep +
Omer-5 + Omer-5 +
Pablo + oubiga +
Pamela Fox + pamelafox + pamelafox
Parbhat Puri + parbhat +
Patrick Tran + theptrk +
Pawan Chaurasia + rjsnh1522 +
Pedro Campos + pcampos119104 +
Peter Bittner + bittner +
Peter Coles + mrcoles +
Philipp Matthies + canonnervio +
Pierre Chiquet + pchiquet +
PJ Hoberman + pjhoberman +
Raony Guimarães Corrêa + raonyguimaraes +
Raphael Pierzina + hackebrot +
Ray Besiga + raybesiga + raybesiga
Reggie Riser + reggieriser +
René Muhl + rm-- +
rguptar + rguptar +
Richard Hajdu + Tusky +
Robin + Kaffeetasse +
Roman Afanaskin + siauPatrick +
Roman Osipenko + romanosipenko +
Russell Davies + +
Ryan Fitch + ryfi +
Sam Collins + MightySCollins +
Sascha + saschalalala + saschalalala
Sebastian Reyes Espinosa + sebastian-code + sebastianreyese
Simon Rey + eqqe +
Sorasful + sorasful +
Srinivas Nyayapati + shireenrao +
stepmr + stepmr +
Steve Steiner + ssteinerX +
Sudarshan Wadkar + wadkar +
Sule Marshall + suledev +
Sławek Ehlert + slafs +
TAKAHASHI Shuuji + shuuji3 +
Tames McTigue + Tamerz +
Tano Abeleyra + tanoabeleyra +
Taylor Baldwin + +
Thibault J. + thibault + thibault
Thomas Booij + ThomasBooij95 +
Théo Segonds + show0k +
tildebox + tildebox +
Tim Claessens + timclaessens +
Tim Freund + timfreund +
Timm Simpkins + PoDuck +
Tom Atkins + knitatoms +
Tom Offermann + +
Travis McNeill + Travistock + tavistock_esq
Tubo Shi + Tubo +
Umair Ashraf + umrashrf + fabumair
Vadim Iskuchekov + Egregors + egregors
vascop + vascop +
Vicente G. Reyes + reyesvicente + highcenburg
Vikas Yadav + vik-y +
Vitaly Babiy + +
Vivian Guillen + viviangb +
Vlad Doster + vladdoster +
Wes Turner + westurner + westurner
Will Farley + goldhand + g01dhand
Will Gordon + wgordon17 +
William Archinal + archinal +
Xaver Y.R. Chen + yrchen + yrchen
Yaroslav Halchenko + +
Yotam Tal + yotamtal +
Yuchen Xie + mapx +
Zach Borboa + zachborboa +
+ +### Special Thanks + +The following haven't provided code directly, but have provided +guidance and advice. + +- Jannis Leidel +- Nate Aune +- Barry Morrison \ No newline at end of file diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst deleted file mode 100644 index e3569e78e..000000000 --- a/CONTRIBUTORS.rst +++ /dev/null @@ -1,305 +0,0 @@ -Contributors -============ - -Core Developers ---------------- - -These contributors have commit flags for the repository, -and are able to accept and merge pull requests. - -=========================== ================ =========== -Name Github Twitter -=========================== ================ =========== -Daniel Roy Greenfeld `@pydanny`_ @pydanny -Audrey Roy Greenfeld* `@audreyr`_ @audreyr -Fábio C. Barrionuevo da Luz `@luzfcb`_ @luzfcb -Saurabh Kumar `@theskumar`_ @_theskumar -Jannis Gebauer `@jayfk`_ -Burhan Khalid `@burhan`_ @burhan -Nikita Shupeyko `@webyneter`_ @webyneter -Bruno Alla               `@browniebroke`_ @_BrunoAlla -Wan Liuyang `@sfdye`_ @sfdye -=========================== ================ =========== - -*Audrey is also the creator of Cookiecutter. Audrey and -Daniel are on the Cookiecutter core team.* - -.. _@pydanny: https://github.com/pydanny -.. _@luzfcb: https://github.com/luzfcb -.. _@theskumar: https://github.com/theskumar -.. _@audreyr: https://github.com/audreyr -.. _@jayfk: https://github.com/jayfk -.. _@webyneter: https://github.com/webyneter -.. _@browniebroke: https://github.com/browniebroke -.. _@sfdye: https://github.com/sfdye - -Other Contributors ------------------- - -Listed in alphabetical order. - -========================== ============================ ============== - Name Github Twitter -========================== ============================ ============== - 18 `@dezoito`_ - a7p `@a7p`_ - Aaron Eikenberry `@aeikenberry`_ - Adam Bogdał `@bogdal`_ - Adam Dobrawy `@ad-m`_ - Adam Steele `@adammsteele` - Agam Dua - Alberto Sanchez `@alb3rto`_ - Alex Tsai `@caffodian`_ - Alvaro [Andor] `@andor-pierdelacabeza`_ - Amjith Ramanujam `@amjith`_ - Andreas Meistad `@ameistad`_ - Andres Gonzalez `@andresgz`_ - Andrew Mikhnevich `@zcho`_ - Andy Rose - Anna Callahan `@jazztpt`_ - Antonia Blair `@antoniablair`_ @antoniablairart - Anuj Bansal `@ahhda`_ - Arcuri Davide `@dadokkio`_ - Areski Belaid `@areski`_ - Ashley Camba - Barclay Gauld `@yunti`_ - Ben Warren `@bwarren2` - Ben Lopatin - Benjamin Abel - Bert de Miranda `@bertdemiranda`_ - Bo Lopker `@blopker`_ - Bouke Haarsma - Brent Payne `@brentpayne`_ @brentpayne - Burhan Khalid            `@burhan`_                   @burhan - Carl Johnson `@carlmjohnson`_ @carlmjohnson - Catherine Devlin `@catherinedevlin`_ - Cédric Gaspoz `@cgaspoz`_ - Charlie Smith `@chuckus`_ - Chris Curvey `@ccurvey`_ - Chris Franklin - Chris Franklin `@hairychris`_ - Chris Pappalardo `@ChrisPappalardo`_ - Christopher Clarke `@chrisdev`_ - Cole Mackenzie `@cmackenzie1`_ - Collederas `@Collederas`_ - Cristian Vargas `@cdvv7788`_ - Cullen Rhodes `@c-rhodes`_ - Dan Shultz `@shultz`_ - Daniel Hepper `@dhepper`_ @danielhepper - Daniele Tricoli `@eriol`_ - David Díaz `@ddiazpinto`_ @DavidDiazPinto - Davit Tovmasyan `@davitovmasyan`_ - Davur Clementsen `@dsclementsen`_ @davur - Delio Castillo `@jangeador`_ @jangeador - Denis Orehovsky `@apirobot`_ - Dónal Adams `@epileptic-fish`_ - Diane Chen `@purplediane`_ @purplediane88 - Dong Huynh `@trungdong`_ - Emanuel Calso `@bloodpet`_ @bloodpet - Eraldo Energy `@eraldo`_ - Eric Groom `@ericgroom`_ - Eyad Al Sibai `@eyadsibai`_ - Felipe Arruda `@arruda`_ - Garry Cairns `@garry-cairns`_ - Garry Polley `@garrypolley`_ - Hamish Durkin `@durkode`_ - Harry Percival `@hjwp`_ - Hendrik Schneider `@hendrikschneider`_ - Henrique G. G. Pereira `@ikkebr`_ - Ian Lee `@IanLee1521`_ - Irfan Ahmad `@erfaan`_ @erfaan - Jan Van Bruggen `@jvanbrug`_ - Jens Nilsson `@phiberjenz`_ - Jerome Leclanche `@jleclanche`_ @Adys - Jimmy Gitonga `@afrowave`_ @afrowave - John Cass `@jcass77`_ @cass_john - Julien Almarcha `@sladinji`_ - Julio Castillo `@juliocc`_ - Kaido Kert `@kaidokert`_ - kappataumu `@kappataumu`_ @kappataumu - Kaveh `@ka7eh`_ - Kevin A. Stone - Kevin Ndung'u `@kevgathuku`_ - Keith Webber `@townie`_ - Krzysztof Szumny `@noisy`_ - Krzysztof Żuraw `@krzysztofzuraw`_ - Leonardo Jimenez `@xpostudio4`_ - Leo Zhou `@glasslion`_ - Lin Xianyi `@iynaix`_ - Luis Nell `@originell`_ - Lukas Klein - Lyla Fischer - Malik Sulaimanov `@flyudvik`_ @flyudvik - Martin Blech - Martin Saizar `@msaizar`_ - Mateusz Ostaszewski `@mostaszewski`_ - Mathijs Hoogland `@MathijsHoogland`_ - Matt Braymer-Hayes `@mattayes`_ @mattayes - Matt Linares - Matt Menzenski `@menzenski`_ - Matt Warren `@mfwarren`_ - Matthew Sisley `@mjsisley`_ - Meghan Heintz `@dot2dotseurat`_ - Mesut Yılmaz `@myilmaz`_ - Michael Gecht `@mimischi`_ @_mischi - mozillazg `@mozillazg`_ - Pablo `@oubiga`_ - Parbhat Puri `@parbhat`_ - Peter Bittner `@bittner`_ - Peter Coles `@mrcoles`_ - Pierre Chiquet `@pchiquet`_ - Raphael Pierzina `@hackebrot`_ - Raony Guimarães Corrêa `@raonyguimaraes`_ - Reggie Riser `@reggieriser`_ - René Muhl `@rm--`_ - Roman Afanaskin `@siauPatrick`_ - Roman Osipenko `@romanosipenko`_ - Russell Davies - Sascha `@saschalalala` @saschalalala - Sam Collins `@MightySCollins`_ - Shupeyko Nikita `@webyneter`_ - Sławek Ehlert `@slafs`_ - Srinivas Nyayapati `@shireenrao`_ - stepmr `@stepmr`_ - Steve Steiner `@ssteinerX`_ - Sule Marshall `@suledev`_ - Taylor Baldwin - Théo Segonds `@show0k`_ - Tim Freund `@timfreund`_ - Tom Atkins `@knitatoms`_ - Tom Offermann - Travis McNeill `@Travistock`_ @tavistock_esq - Tubo Shi `@Tubo`_ - Umair Ashraf `@umrashrf`_ @fabumair - Vitaly Babiy - Vivian Guillen `@viviangb`_ - Will Farley `@goldhand`_ @g01dhand - William Archinal `@archinal`_ - Yaroslav Halchenko - Denis Bobrov `@delneg`_ - Philipp Matthies `@canonnervio`_ - Vadim Iskuchekov `@Egregors`_ @egregors -========================== ============================ ============== - -.. _@a7p: https://github.com/a7p -.. _@ad-m: https://github.com/ad-m -.. _@adammsteele: https://github.com/adammsteele -.. _@aeikenberry: https://github.com/aeikenberry -.. _@alb3rto: https://github.com/alb3rto -.. _@ameistad: https://github.com/ameistad -.. _@amjith: https://github.com/amjith -.. _@andor-pierdelacabeza: https://github.com/andor-pierdelacabeza -.. _@antoniablair: https://github.com/antoniablair -.. _@apirobot: https://github.com/apirobot -.. _@archinal: https://github.com/archinal -.. _@areski: https://github.com/areski -.. _@arruda: https://github.com/arruda -.. _@bittner: https://github.com/bittner -.. _@bloodpet: https://github.com/bloodpet -.. _@blopker: https://github.com/blopker -.. _@bogdal: https://github.com/bogdal -.. _@burhan: https://github.com/burhan -.. _@c-rhodes: https://github.com/c-rhodes -.. _@caffodian: https://github.com/caffodian -.. _@carlmjohnson: https://github.com/carlmjohnson -.. _@catherinedevlin: https://github.com/catherinedevlin -.. _@ccurvey: https://github.com/ccurvey -.. _@cdvv7788: https://github.com/cdvv7788 -.. _@cgaspoz: https://github.com/cgaspoz -.. _@chrisdev: https://github.com/chrisdev -.. _@ChrisPappalardo: https://github.com/ChrisPappalardo -.. _@chuckus: https://github.com/chuckus -.. _@cmackenzie1: https://github.com/cmackenzie1 -.. _@Collederas: https://github.com/Collederas -.. _@davitovmasyan: https://github.com/davitovmasyan -.. _@ddiazpinto: https://github.com/ddiazpinto -.. _@dezoito: https://github.com/dezoito -.. _@dhepper: https://github.com/dhepper -.. _@dot2dotseurat: https://github.com/dot2dotseurat -.. _@dsclementsen: https://github.com/dsclementsen -.. _@durkode: https://github.com/durkode -.. _@epileptic-fish: https://gihub.com/epileptic-fish -.. _@eraldo: https://github.com/eraldo -.. _@erfaan: https://github.com/erfaan -.. _@eriol: https://github.com/eriol -.. _@eyadsibai: https://github.com/eyadsibai -.. _@flyudvik: https://github.com/flyudvik -.. _@garry-cairns: https://github.com/garry-cairns -.. _@garrypolley: https://github.com/garrypolley -.. _@goldhand: https://github.com/goldhand -.. _@glasslion: https://github.com/glasslion -.. _@hackebrot: https://github.com/hackebrot -.. _@hairychris: https://github.com/hairychris -.. _@hendrikschneider: https://github.com/hendrikschneider -.. _@hjwp: https://github.com/hjwp -.. _@IanLee1521: https://github.com/IanLee1521 -.. _@ikkebr: https://github.com/ikkebr -.. _@iynaix: https://github.com/iynaix -.. _@jazztpt: https://github.com/jazztpt -.. _@jleclanche: https://github.com/jleclanche -.. _@juliocc: https://github.com/juliocc -.. _@jvanbrug: https://github.com/jvanbrug -.. _@ka7eh: https://github.com/ka7eh -.. _@kaidokert: https://github.com/kaidokert -.. _@kappataumu: https://github.com/kappataumu -.. _@kevgathuku: https://github.com/kevgathuku -.. _@knitatoms: https://github.com/knitatoms -.. _@krzysztofzuraw: https://github.com/krzysztofzuraw -.. _@msaizar: https://github.com/msaizar -.. _@MathijsHoogland: https://github.com/MathijsHoogland -.. _@mattayes: https://github.com/mattayes -.. _@menzenski: https://github.com/menzenski -.. _@mostaszewski: https://github.com/mostaszewski -.. _@mfwarren: https://github.com/mfwarren -.. _@mimischi: https://github.com/mimischi -.. _@mjsisley: https://github.com/mjsisley -.. _@myilmaz: https://github.com/myilmaz -.. _@mozillazg: https://github.com/mozillazg -.. _@noisy: https://github.com/noisy -.. _@originell: https://github.com/originell -.. _@oubiga: https://github.com/oubiga -.. _@parbhat: https://github.com/parbhat -.. _@raonyguimaraes: https://github.com/raonyguimaraes -.. _@reggieriser: https://github.com/reggieriser -.. _@rm--: https://github.com/rm-- -.. _@romanosipenko: https://github.com/romanosipenko -.. _@shireenrao: https://github.com/shireenrao -.. _@show0k: https://github.com/show0k -.. _@shultz: https://github.com/shultz -.. _@siauPatrick: https://github.com/siauPatrick -.. _@slafs: https://github.com/slafs -.. _@ssteinerX: https://github.com/ssteinerx -.. _@stepmr: https://github.com/stepmr -.. _@suledev: https://github.com/suledev -.. _@timfreund: https://github.com/timfreund -.. _@Travistock: https://github.com/Tavistock -.. _@trungdong: https://github.com/trungdong -.. _@Tubo: https://github.com/tubo -.. _@viviangb: https://github.com/viviangb -.. _@xpostudio4: https://github.com/xpostudio4 -.. _@yunti: https://github.com/yunti -.. _@zcho: https://github.com/zcho -.. _@phiberjenz: https://github.com/phiberjenz -.. _@sladinji: https://github.com/sladinji -.. _@andresgz: https://github.com/andresgz -.. _@jangeador: https://github.com/jangeador -.. _@townie: https://github.com/townie -.. _@MightySCollins: https://github.com/MightySCollins -.. _@dadokkio: https://github.com/dadokkio -.. _@bwarren2: https://github.com/bwarren2 -.. _@bertdemiranda: https://github.com/bertdemiranda -.. _@brentpayne: https://github.com/brentpayne -.. _@afrowave: https://github.com/afrowave -.. _@pchiquet: https://github.com/pchiquet -.. _@delneg: https://github.com/delneg -.. _@purplediane: https://github.com/purplediane -.. _@umrashrf: https://github.com/umrashrf -.. _@ahhda: https://github.com/ahhda -Special Thanks -~~~~~~~~~~~~~~ - -The following haven't provided code directly, but have provided guidance and advice. - -* Jannis Leidel -* Nate Aune -* Barry Morrison diff --git a/LICENSE b/LICENSE index 28466d40f..a67e4da21 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2018, Daniel Roy Greenfeld +Copyright (c) 2013-2020, Daniel Roy Greenfeld All rights reserved. Redistribution and use in source and binary forms, with or without modification, diff --git a/README.md b/README.md new file mode 100644 index 000000000..1a60f8ec6 --- /dev/null +++ b/README.md @@ -0,0 +1,258 @@ +# Cookiecutter Django + +[![Build Status](https://img.shields.io/github/actions/workflow/status/cookiecutter/cookiecutter-django/ci.yml?branch=master)](https://github.com/cookiecutter/cookiecutter-django/actions/workflows/ci.yml?query=branch%3Amaster) +[![Documentation Status](https://readthedocs.org/projects/cookiecutter-django/badge/?version=latest)](https://cookiecutter-django.readthedocs.io/en/latest/?badge=latest) +[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/cookiecutter/cookiecutter-django/master.svg)](https://results.pre-commit.ci/latest/github/cookiecutter/cookiecutter-django/master) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) + +[![Updates](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/shield.svg)](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/) +[![Join our Discord](https://img.shields.io/badge/Discord-cookiecutter-5865F2?style=flat&logo=discord&logoColor=white)](https://discord.gg/uFXweDQc5a) +[![Code Helpers Badge](https://www.codetriage.com/cookiecutter/cookiecutter-django/badges/users.svg)](https://www.codetriage.com/cookiecutter/cookiecutter-django) + +Powered by [Cookiecutter](https://github.com/cookiecutter/cookiecutter), Cookiecutter Django is a framework for jumpstarting +production-ready Django projects quickly. + +- Documentation: +- See [Troubleshooting](https://cookiecutter-django.readthedocs.io/en/latest/troubleshooting.html) for common errors and obstacles +- If you have problems with Cookiecutter Django, please open [issues](https://github.com/cookiecutter/cookiecutter-django/issues/new) don't send + emails to the maintainers. + +## Features + +- For Django 4.2 +- Works with Python 3.11 +- Renders Django projects with 100% starting test coverage +- Twitter [Bootstrap](https://github.com/twbs/bootstrap) v5 +- [12-Factor](http://12factor.net/) based settings via [django-environ](https://github.com/joke2k/django-environ) +- Secure by default. We believe in SSL. +- Optimized development and production settings +- Registration via [django-allauth](https://github.com/pennersr/django-allauth) +- Comes with custom user model ready to go +- Optional basic ASGI setup for Websockets +- Optional custom static build using Gulp or Webpack +- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable) +- Media storage using Amazon S3, Google Cloud Storage, Azure Storage or nginx +- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support) +- [Procfile](https://devcenter.heroku.com/articles/procfile) for deploying to Heroku +- Instructions for deploying to [PythonAnywhere](https://www.pythonanywhere.com/) +- Run tests with unittest or pytest +- Customizable PostgreSQL version +- Default integration with [pre-commit](https://github.com/pre-commit/pre-commit) for identifying simple issues before submission to code review + +## Optional Integrations + +_These features can be enabled during initial project setup._ + +- Serve static files from Amazon S3, Google Cloud Storage, Azure Storage or [Whitenoise](https://whitenoise.readthedocs.io/) +- Configuration for [Celery](https://docs.celeryq.dev) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only) +- Integration with [MailHog](https://github.com/mailhog/MailHog) for local email testing +- Integration with [Sentry](https://sentry.io/welcome/) for error logging + +## Constraints + +- Only maintained 3rd party libraries are used. +- Uses PostgreSQL everywhere: 10.19 - 14.1 ([MySQL fork](https://github.com/mabdullahadeel/cookiecutter-django-mysql) also available). +- Environment variables for configuration (This won't work with Apache/mod_wsgi). + +## Support this Project! + +This project is an open source project run by volunteers. You can sponsor us via [OpenCollective](https://opencollective.com/cookiecutter-django) or individually via GitHub Sponsors: + +- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB. +- Fabio C. Barrionuevo, Core Developer ([GitHub](https://github.com/luzfcb)): expertise in Python/Django, hands-on DevOps and frontend experience. +- Bruno Alla, Core Developer ([GitHub](https://github.com/browniebroke)): expertise in Python/Django and DevOps. +- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience. + +Projects that provide financial support to the maintainers: + +--- + +

+ +

+ +Two Scoops of Django 3.x is the best ice cream-themed Django reference in the universe! + +### PyUp + +

+ +

+ +PyUp brings you automated security and dependency updates used by Google and other organizations. Free for open source projects! + +## Usage + +Let's pretend you want to create a Django project called "redditclone". Rather than using `startproject` +and then editing the results to include your name, email, and various configuration issues that always get forgotten until the worst possible moment, get [cookiecutter](https://github.com/cookiecutter/cookiecutter) to do all the work. + +First, get Cookiecutter. Trust me, it's awesome: + + $ pip install "cookiecutter>=1.7.0" + +Now run it against this repo: + + $ cookiecutter https://github.com/cookiecutter/cookiecutter-django + +You'll be prompted for some values. Provide them, then a Django project will be created for you. + +**Warning**: After this point, change 'Daniel Greenfeld', 'pydanny', etc to your own information. + +Answer the prompts with your own desired [options](http://cookiecutter-django.readthedocs.io/en/latest/project-generation-options.html). For example: + + Cloning into 'cookiecutter-django'... + remote: Counting objects: 550, done. + remote: Compressing objects: 100% (310/310), done. + remote: Total 550 (delta 283), reused 479 (delta 222) + Receiving objects: 100% (550/550), 127.66 KiB | 58 KiB/s, done. + Resolving deltas: 100% (283/283), done. + project_name [My Awesome Project]: Reddit Clone + project_slug [reddit_clone]: reddit + description [Behold My Awesome Project!]: A reddit clone. + author_name [Daniel Roy Greenfeld]: Daniel Greenfeld + domain_name [example.com]: myreddit.com + email [daniel-greenfeld@example.com]: pydanny@gmail.com + version [0.1.0]: 0.0.1 + Select open_source_license: + 1 - MIT + 2 - BSD + 3 - GPLv3 + 4 - Apache Software License 2.0 + 5 - Not open source + Choose from 1, 2, 3, 4, 5 [1]: 1 + Select username_type: + 1 - username + 2 - email + Choose from 1, 2 [1]: 1 + timezone [UTC]: America/Los_Angeles + windows [n]: n + use_pycharm [n]: y + use_docker [n]: n + Select postgresql_version: + 1 - 14 + 2 - 13 + 3 - 12 + 4 - 11 + 5 - 10 + Choose from 1, 2, 3, 4, 5 [1]: 1 + Select cloud_provider: + 1 - AWS + 2 - GCP + 3 - None + Choose from 1, 2, 3 [1]: 1 + Select mail_service: + 1 - Mailgun + 2 - Amazon SES + 3 - Mailjet + 4 - Mandrill + 5 - Postmark + 6 - Sendgrid + 7 - SendinBlue + 8 - SparkPost + 9 - Other SMTP + Choose from 1, 2, 3, 4, 5, 6, 7, 8, 9 [1]: 1 + use_async [n]: n + use_drf [n]: y + Select frontend_pipeline: + 1 - None + 2 - Django Compressor + 3 - Gulp + 4 - Webpack + Choose from 1, 2, 3, 4 [1]: 1 + use_celery [n]: y + use_mailhog [n]: n + use_sentry [n]: y + use_whitenoise [n]: n + use_heroku [n]: y + Select ci_tool: + 1 - None + 2 - Travis + 3 - Gitlab + 4 - Github + Choose from 1, 2, 3, 4 [1]: 4 + keep_local_envs_in_vcs [y]: y + debug [n]: n + +Enter the project and take a look around: + + $ cd reddit/ + $ ls + +Create a git repo and push it there: + + $ git init + $ git add . + $ git commit -m "first awesome commit" + $ git remote add origin git@github.com:pydanny/redditclone.git + $ git push -u origin master + +Now take a look at your repo. Don't forget to carefully look at the generated README. Awesome, right? + +For local development, see the following: + +- [Developing locally](http://cookiecutter-django.readthedocs.io/en/latest/developing-locally.html) +- [Developing locally using docker](http://cookiecutter-django.readthedocs.io/en/latest/developing-locally-docker.html) + +## Community + +- Have questions? **Before you ask questions anywhere else**, please post your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/cookiecutter-django) under the _cookiecutter-django_ tag. We check there periodically for questions. +- If you think you found a bug or want to request a feature, please open an [issue](https://github.com/cookiecutter/cookiecutter-django/issues). +- For anything else, you can chat with us on [Discord](https://discord.gg/uFXweDQc5a). + +## For Readers of Two Scoops of Django + +You may notice that some elements of this project do not exactly match what we describe in chapter 3. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored. + +## For PyUp Users + +If you are using [PyUp](https://pyup.io) to keep your dependencies updated and secure, use the code _cookiecutter_ during checkout to get 15% off every month. + +## "Your Stuff" + +Scattered throughout the Python and HTML of this project are places marked with "your stuff". This is where third-party libraries are to be integrated with your project. + +## For MySQL users + +To get full MySQL support in addition to the default Postgresql, you can use this fork of the cookiecutter-django: +https://github.com/mabdullahadeel/cookiecutter-django-mysql + +## Releases + +Need a stable release? You can find them at + +## Not Exactly What You Want? + +This is what I want. _It might not be what you want._ Don't worry, you have options: + +### Fork This + +If you have differences in your preferred setup, I encourage you to fork this to create your own version. +Once you have your fork working, let me know and I'll add it to a '_Similar Cookiecutter Templates_' list here. +It's up to you whether to rename your fork. + +If you do rename your fork, I encourage you to submit it to the following places: + +- [cookiecutter](https://github.com/cookiecutter/cookiecutter) so it gets listed in the README as a template. +- The cookiecutter [grid](https://www.djangopackages.com/grids/g/cookiecutters/) on Django Packages. + +### Submit a Pull Request + +We accept pull requests if they're small, atomic, and make our own project development +experience better. + +## Articles + +- [Cookiecutter Django With Amazon RDS](https://haseeburrehman.com/posts/cookiecutter-django-with-amazon-rds/) - Apr, 2, 2021 +- [Complete Walkthrough: Blue/Green Deployment to AWS ECS using GitHub actions](https://github.com/Andrew-Chen-Wang/cookiecutter-django-ecs-github) - June 10, 2020 +- [Using cookiecutter-django with Google Cloud Storage](https://ahhda.github.io/cloud/gce/django/2019/03/12/using-django-cookiecutter-cloud-storage.html) - Mar. 12, 2019 +- [cookiecutter-django with Nginx, Route 53 and ELB](https://msaizar.com/blog/cookiecutter-django-nginx-route-53-and-elb/) - Feb. 12, 2018 +- [cookiecutter-django and Amazon RDS](https://msaizar.com/blog/cookiecutter-django-and-amazon-rds/) - Feb. 7, 2018 +- [Using Cookiecutter to Jumpstart a Django Project on Windows with PyCharm](https://joshuahunter.com/posts/using-cookiecutter-to-jumpstart-a-django-project-on-windows-with-pycharm/) - May 19, 2017 +- [Exploring with Cookiecutter](http://www.snowboardingcoder.com/django/2016/12/03/exploring-with-cookiecutter/) - Dec. 3, 2016 +- [Introduction to Cookiecutter-Django](http://krzysztofzuraw.com/blog/2016/django-cookiecutter.html) - Feb. 19, 2016 +- [Django and GitLab - Running Continuous Integration and tests with your FREE account](http://dezoito.github.io/2016/05/11/django-gitlab-continuous-integration-phantomjs.html) - May. 11, 2016 +- [Development and Deployment of Cookiecutter-Django on Fedora](https://realpython.com/blog/python/development-and-deployment-of-cookiecutter-django-on-fedora/) - Jan. 18, 2016 +- [Development and Deployment of Cookiecutter-Django via Docker](https://realpython.com/blog/python/development-and-deployment-of-cookiecutter-django-via-docker/) - Dec. 29, 2015 +- [How to create a Django Application using Cookiecutter and Django 1.8](https://www.swapps.io/blog/how-to-create-a-django-application-using-cookiecutter-and-django-1-8/) - Sept. 12, 2015 + +Have a blog or online publication? Write about your cookiecutter-django tips and tricks, then send us a pull request with the link. diff --git a/README.rst b/README.rst deleted file mode 100644 index b9e71ace2..000000000 --- a/README.rst +++ /dev/null @@ -1,314 +0,0 @@ -Cookiecutter Django -======================= - -.. image:: https://travis-ci.org/pydanny/cookiecutter-django.svg?branch=master - :target: https://travis-ci.org/pydanny/cookiecutter-django?branch=master - :alt: Build Status - -.. image:: https://pyup.io/repos/github/pydanny/cookiecutter-django/shield.svg - :target: https://pyup.io/repos/github/pydanny/cookiecutter-django/ - :alt: Updates - -.. image:: https://badges.gitter.im/Join Chat.svg - :target: https://gitter.im/pydanny/cookiecutter-django?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - -.. image:: https://www.codetriage.com/pydanny/cookiecutter-django/badges/users.svg - :target: https://www.codetriage.com/pydanny/cookiecutter-django - :alt: Code Helpers Badge - -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/ambv/black - :alt: Code style: black - -Powered by Cookiecutter_, Cookiecutter Django is a framework for jumpstarting -production-ready Django projects quickly. - -* Documentation: https://cookiecutter-django.readthedocs.io/en/latest/ -* See Troubleshooting_ for common errors and obstacles -* If you have problems with Cookiecutter Django, please open issues_ don't send - emails to the maintainers. - -.. _Troubleshooting: https://cookiecutter-django.readthedocs.io/en/latest/troubleshooting.html - -.. _528: https://github.com/pydanny/cookiecutter-django/issues/528#issuecomment-212650373 -.. _issues: https://github.com/pydanny/cookiecutter-django/issues/new - -Features ---------- - -* For Django 2.0 -* Works with Python 3.6 -* Renders Django projects with 100% starting test coverage -* Twitter Bootstrap_ v4.1.1 (`maintained Foundation fork`_ also available) -* 12-Factor_ based settings via django-environ_ -* Secure by default. We believe in SSL. -* Optimized development and production settings -* Registration via django-allauth_ -* Comes with custom user model ready to go -* Optional custom static build using Gulp and livereload -* Send emails via Anymail_ (using Mailgun_ by default, but switchable) -* Media storage using Amazon S3 -* Docker support using docker-compose_ for development and production (using Caddy_ with LetsEncrypt_ support) -* Procfile_ for deploying to Heroku -* Instructions for deploying to PythonAnywhere_ -* Run tests with unittest or py.test -* Customizable PostgreSQL version - -.. _`maintained Foundation fork`: https://github.com/Parbhat/cookiecutter-django-foundation - - -Optional Integrations ---------------------- - -*These features can be enabled during initial project setup.* - -* Serve static files from Amazon S3 or Whitenoise_ -* Configuration for Celery_ and Flower_ (the latter in Docker setup only) -* Integration with MailHog_ for local email testing -* Integration with Sentry_ for error logging - -.. _Bootstrap: https://github.com/twbs/bootstrap -.. _django-environ: https://github.com/joke2k/django-environ -.. _12-Factor: http://12factor.net/ -.. _django-allauth: https://github.com/pennersr/django-allauth -.. _django-avatar: https://github.com/grantmcconnaughey/django-avatar -.. _Procfile: https://devcenter.heroku.com/articles/procfile -.. _Mailgun: http://www.mailgun.com/ -.. _Whitenoise: https://whitenoise.readthedocs.io/ -.. _Celery: http://www.celeryproject.org/ -.. _Flower: https://github.com/mher/flower -.. _Anymail: https://github.com/anymail/django-anymail -.. _MailHog: https://github.com/mailhog/MailHog -.. _Sentry: https://sentry.io/welcome/ -.. _docker-compose: https://github.com/docker/compose -.. _PythonAnywhere: https://www.pythonanywhere.com/ -.. _Caddy: https://caddyserver.com/ -.. _LetsEncrypt: https://letsencrypt.org/ - -Constraints ------------ - -* Only maintained 3rd party libraries are used. -* Uses PostgreSQL everywhere (9.2+) -* Environment variables for configuration (This won't work with Apache/mod_wsgi except on AWS ELB). - -Support this Project! ----------------------- - -This project is run by volunteers. Please support them in their efforts to maintain and improve Cookiecutter Django: - -* Daniel Roy Greenfeld, Project Lead (`GitHub `_, `Patreon `_): expertise in Django and AWS ELB. - -* Nikita Shupeyko, Core Developer (`GitHub `_): expertise in Python/Django, hands-on DevOps and frontend experience. - -Projects that provide financial support to the maintainers: - -Two Scoops of Django 1.11 -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. image:: https://cdn.shopify.com/s/files/1/0304/6901/products/tsd-111-alpha_medium.jpg?v=1499531513 - :name: Two Scoops of Django 1.11 Cover - :align: center - :alt: Two Scoops of Django - :target: http://twoscoopspress.com/products/two-scoops-of-django-1-11 - -Two Scoops of Django is the best dessert-themed Django reference in the universe - -pyup -~~~~~~~~~~~~~~~~~~ - -.. image:: https://pyup.io/static/images/logo.png - :name: pyup - :align: center - :alt: pyup - :target: https://pyup.io/ - -Pyup brings you automated security and dependency updates used by Google and other organizations. Free for open source projects! - -Usage ------- - -Let's pretend you want to create a Django project called "redditclone". Rather than using ``startproject`` -and then editing the results to include your name, email, and various configuration issues that always get forgotten until the worst possible moment, get cookiecutter_ to do all the work. - -First, get Cookiecutter. Trust me, it's awesome:: - - $ pip install "cookiecutter>=1.4.0" - -Now run it against this repo:: - - $ cookiecutter https://github.com/pydanny/cookiecutter-django - -You'll be prompted for some values. Provide them, then a Django project will be created for you. - -**Warning**: After this point, change 'Daniel Greenfeld', 'pydanny', etc to your own information. - -Answer the prompts with your own desired options_. For example:: - - Cloning into 'cookiecutter-django'... - remote: Counting objects: 550, done. - remote: Compressing objects: 100% (310/310), done. - remote: Total 550 (delta 283), reused 479 (delta 222) - Receiving objects: 100% (550/550), 127.66 KiB | 58 KiB/s, done. - Resolving deltas: 100% (283/283), done. - project_name [Project Name]: Reddit Clone - project_slug [reddit_clone]: reddit - author_name [Daniel Roy Greenfeld]: Daniel Greenfeld - email [you@example.com]: pydanny@gmail.com - description [A short description of the project.]: A reddit clone. - domain_name [example.com]: myreddit.com - version [0.1.0]: 0.0.1 - timezone [UTC]: America/Los_Angeles - use_whitenoise [n]: n - use_celery [n]: y - use_mailhog [n]: n - use_sentry [n]: y - use_pycharm [n]: y - windows [n]: n - use_docker [n]: n - use_heroku [n]: y - use_compressor [n]: y - Select postgresql_version: - 1 - 10.3 - 2 - 10.2 - 3 - 10.1 - 4 - 9.6 - 5 - 9.5 - 6 - 9.4 - 7 - 9.3 - Choose from 1, 2, 3, 4 [1]: 1 - Select js_task_runner: - 1 - None - 2 - Gulp - Choose from 1, 2 [1]: 1 - custom_bootstrap_compilation [n]: n - Select open_source_license: - 1 - MIT - 2 - BSD - 3 - GPLv3 - 4 - Apache Software License 2.0 - 5 - Not open source - Choose from 1, 2, 3, 4, 5 [1]: 1 - keep_local_envs_in_vcs [y]: y - debug[n]: n - -Enter the project and take a look around:: - - $ cd reddit/ - $ ls - -Create a git repo and push it there:: - - $ git init - $ git add . - $ git commit -m "first awesome commit" - $ git remote add origin git@github.com:pydanny/redditclone.git - $ git push -u origin master - -Now take a look at your repo. Don't forget to carefully look at the generated README. Awesome, right? - -For local development, see the following: - -* `Developing locally`_ -* `Developing locally using docker`_ - -.. _options: http://cookiecutter-django.readthedocs.io/en/latest/project-generation-options.html -.. _`Developing locally`: http://cookiecutter-django.readthedocs.io/en/latest/developing-locally.html -.. _`Developing locally using docker`: http://cookiecutter-django.readthedocs.io/en/latest/developing-locally-docker.html - -Community ------------ - -* Have questions? **Before you ask questions anywhere else**, please post your question on `Stack Overflow`_ under the *cookiecutter-django* tag. We check there periodically for questions. -* If you think you found a bug or want to request a feature, please open an issue_. -* For anything else, you can chat with us on `Gitter`_. - -.. _`Stack Overflow`: http://stackoverflow.com/questions/tagged/cookiecutter-django -.. _`issue`: https://github.com/pydanny/cookiecutter-django/issues -.. _`Gitter`: https://gitter.im/pydanny/cookiecutter-django?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - -For Readers of Two Scoops of Django --------------------------------------------- - -You may notice that some elements of this project do not exactly match what we describe in chapter 3. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored. - -For pyup.io Users ------------------ - -If you are using `pyup.io`_ to keep your dependencies updated and secure, use the code *cookiecutter* during checkout to get 15% off every month. - -.. _`pyup.io`: https://pyup.io - -"Your Stuff" -------------- - -Scattered throughout the Python and HTML of this project are places marked with "your stuff". This is where third-party libraries are to be integrated with your project. - -Releases --------- - -Need a stable release? You can find them at https://github.com/pydanny/cookiecutter-django/releases - - -Not Exactly What You Want? ---------------------------- - -This is what I want. *It might not be what you want.* Don't worry, you have options: - -Fork This -~~~~~~~~~~ - -If you have differences in your preferred setup, I encourage you to fork this to create your own version. -Once you have your fork working, let me know and I'll add it to a '*Similar Cookiecutter Templates*' list here. -It's up to you whether or not to rename your fork. - -If you do rename your fork, I encourage you to submit it to the following places: - -* cookiecutter_ so it gets listed in the README as a template. -* The cookiecutter grid_ on Django Packages. - -.. _cookiecutter: https://github.com/audreyr/cookiecutter -.. _grid: https://www.djangopackages.com/grids/g/cookiecutters/ - -Submit a Pull Request -~~~~~~~~~~~~~~~~~~~~~~ - -We accept pull requests if they're small, atomic, and make our own project development -experience better. - -Articles ---------- - -* `cookiecutter-django with Nginx, Route 53 and ELB`_ - Feb. 12, 2018 -* `cookiecutter-django and Amazon RDS`_ - Feb. 7, 2018 -* `Deploying Cookiecutter-Django with Docker-Compose`_ - Oct. 19, 2017 -* `Using Cookiecutter to Jumpstart a Django Project on Windows with PyCharm`_ - May 19, 2017 -* `Exploring with Cookiecutter`_ - Dec. 3, 2016 -* `Introduction to Cookiecutter-Django`_ - Feb. 19, 2016 -* `Django and GitLab - Running Continuous Integration and tests with your FREE account`_ - May. 11, 2016 -* `Development and Deployment of Cookiecutter-Django on Fedora`_ - Jan. 18, 2016 -* `Development and Deployment of Cookiecutter-Django via Docker`_ - Dec. 29, 2015 -* `How to create a Django Application using Cookiecutter and Django 1.8`_ - Sept. 12, 2015 - -Have a blog or online publication? Write about your cookiecutter-django tips and tricks, then send us a pull request with the link. - -.. _`cookiecutter-django with Nginx, Route 53 and ELB`: https://msaizar.com/blog/cookiecutter-django-nginx-route-53-and-elb/ -.. _`cookiecutter-django and Amazon RDS`: https://msaizar.com/blog/cookiecutter-django-and-amazon-rds/ -.. _`Deploying Cookiecutter-Django with Docker-Compose`: http://adamantine.me/2017/10/19/deploying-cookiecutter-django-with-docker-compose/ -.. _`Exploring with Cookiecutter`: http://www.snowboardingcoder.com/django/2016/12/03/exploring-with-cookiecutter/ -.. _`Using Cookiecutter to Jumpstart a Django Project on Windows with PyCharm`: https://joshuahunter.com/posts/using-cookiecutter-to-jumpstart-a-django-project-on-windows-with-pycharm/ - -.. _`Development and Deployment of Cookiecutter-Django via Docker`: https://realpython.com/blog/python/development-and-deployment-of-cookiecutter-django-via-docker/ -.. _`Development and Deployment of Cookiecutter-Django on Fedora`: https://realpython.com/blog/python/development-and-deployment-of-cookiecutter-django-on-fedora/ -.. _`How to create a Django Application using Cookiecutter and Django 1.8`: https://www.swapps.io/blog/how-to-create-a-django-application-using-cookiecutter-and-django-1-8/ -.. _`Introduction to Cookiecutter-Django`: http://krzysztofzuraw.com/blog/2016/django-cookiecutter.html -.. _`Django and GitLab - Running Continuous Integration and tests with your FREE account`: http://dezoito.github.io/2016/05/11/django-gitlab-continuous-integration-phantomjs.html - -Code of Conduct ---------------- - -Everyone interacting in the Cookiecutter project's codebases, issue trackers, chat -rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. - - -.. _`PyPA Code of Conduct`: https://www.pypa.io/en/latest/code-of-conduct/ diff --git a/cookiecutter.json b/cookiecutter.json index b5dda0c70..970a53795 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -4,7 +4,7 @@ "description": "Behold My Awesome Project!", "author_name": "Daniel Roy Greenfeld", "domain_name": "example.com", - "email": "{{ cookiecutter.author_name.lower()|replace(' ', '-') }}@example.com", + "email": "{{ cookiecutter.author_name.lower() | trim() |replace(' ', '-') }}@{{ cookiecutter.domain_name.lower() | trim() }}", "version": "0.1.0", "open_source_license": [ "MIT", @@ -13,34 +13,33 @@ "Apache Software License 2.0", "Not open source" ], + "username_type": ["username", "email"], "timezone": "UTC", "windows": "n", "use_pycharm": "n", "use_docker": "n", - "postgresql_version": [ - "10.5", - "10.4", - "10.3", - "10.2", - "10.1", - "9.6", - "9.5", - "9.4", - "9.3" + "postgresql_version": ["14", "13", "12", "11", "10"], + "cloud_provider": ["AWS", "GCP", "Azure", "None"], + "mail_service": [ + "Mailgun", + "Amazon SES", + "Mailjet", + "Mandrill", + "Postmark", + "Sendgrid", + "SendinBlue", + "SparkPost", + "Other SMTP" ], - "js_task_runner": [ - "None", - "Gulp" - ], - "custom_bootstrap_compilation": "n", - "use_compressor": "n", + "use_async": "n", + "use_drf": "n", + "frontend_pipeline": ["None", "Django Compressor", "Gulp", "Webpack"], "use_celery": "n", "use_mailhog": "n", "use_sentry": "n", "use_whitenoise": "n", "use_heroku": "n", - "use_travisci": "n", + "ci_tool": ["None", "Travis", "Gitlab", "Github"], "keep_local_envs_in_vcs": "y", - "debug": "n" } diff --git a/docs/conf.py b/docs/conf.py index e3ddae9a6..22e73e5db 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -7,10 +7,7 @@ # # All configuration values have a default; values that are commented out # serve to show the default. - from datetime import datetime -import os -import sys now = datetime.now() @@ -26,13 +23,13 @@ now = datetime.now() # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [] +extensions = ["myst_parser"] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = ".rst" +source_suffix = [".rst", ".md"] # The encoding of source files. # source_encoding = 'utf-8-sig' @@ -42,7 +39,7 @@ master_doc = "index" # General information about the project. project = "Cookiecutter Django" -copyright = "2013-2018, Daniel Roy Greenfeld".format(now.year) +copyright = f"2013-{now.year}, Daniel Roy Greenfeld" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -92,7 +89,7 @@ pygments_style = "sphinx" # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = "default" +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -242,7 +239,7 @@ texinfo_documents = [ "Cookiecutter Django documentation", "Daniel Roy Greenfeld", "Cookiecutter Django", - "A Cookiecutter template for creating production-ready Django projects quickly.", + "A Cookiecutter template for creating production-ready " "Django projects quickly.", "Miscellaneous", ) ] diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 000000000..66c1f98d3 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,3 @@ +```{include} ../CONTRIBUTING.md + +``` diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst index f753aa5a4..71c6e11b2 100644 --- a/docs/deployment-on-heroku.rst +++ b/docs/deployment-on-heroku.rst @@ -3,54 +3,126 @@ Deployment on Heroku .. index:: Heroku +Script +------ + Run these commands to deploy the project to Heroku: .. code-block:: bash - heroku create --buildpack https://github.com/heroku/heroku-buildpack-python + heroku create --buildpack heroku/python - heroku addons:create heroku-postgresql:hobby-dev + heroku addons:create heroku-postgresql:mini # On Windows use double quotes for the time zone, e.g. # heroku pg:backups schedule --at "02:00 America/Los_Angeles" DATABASE_URL heroku pg:backups schedule --at '02:00 America/Los_Angeles' DATABASE_URL heroku pg:promote DATABASE_URL - heroku addons:create heroku-redis:hobby-dev + heroku addons:create heroku-redis:mini - # If using mailgun: + # Assuming you chose Mailgun as mail service (see below for others) heroku addons:create mailgun:starter - heroku addons:create sentry:f1 - heroku config:set PYTHONHASHSEED=random - + heroku config:set WEB_CONCURRENCY=4 - + heroku config:set DJANGO_DEBUG=False heroku config:set DJANGO_SETTINGS_MODULE=config.settings.production heroku config:set DJANGO_SECRET_KEY="$(openssl rand -base64 64)" - - # Generating a 32 character-long random string without any of the visually similiar characters "IOl01": + + # Generating a 32 character-long random string without any of the visually similar characters "IOl01": heroku config:set DJANGO_ADMIN_URL="$(openssl rand -base64 4096 | tr -dc 'A-HJ-NP-Za-km-z2-9' | head -c 32)/" - + # Set this to your Heroku app url, e.g. 'bionic-beaver-28392.herokuapp.com' heroku config:set DJANGO_ALLOWED_HOSTS= - + # Assign with AWS_ACCESS_KEY_ID heroku config:set DJANGO_AWS_ACCESS_KEY_ID= - + # Assign with AWS_SECRET_ACCESS_KEY heroku config:set DJANGO_AWS_SECRET_ACCESS_KEY= - + # Assign with AWS_STORAGE_BUCKET_NAME heroku config:set DJANGO_AWS_STORAGE_BUCKET_NAME= git push heroku master - heroku run python manage.py migrate heroku run python manage.py createsuperuser - heroku run python manage.py collectstatic --no-input heroku run python manage.py check --deploy heroku open + +Notes +----- + +Email Service ++++++++++++++ + +The script above assumes that you've chose Mailgun as email service. If you want to use another one, check the `documentation for django-anymail `_ to know which environment variables to set. Heroku provides other `add-ons for emails `_ (e.g. Sendgrid) which can be configured with a similar one line command. + +.. warning:: + + .. include:: mailgun.rst + +Heroku & Docker ++++++++++++++++ + +Although Heroku has some sort of `Docker support`_, it's not supported by cookiecutter-django. +We invite you to follow Heroku documentation about it. + +.. _Docker support: https://devcenter.heroku.com/articles/build-docker-images-heroku-yml + +Optional actions +---------------- + +Celery +++++++ + +Celery requires a few extra environment variables to be ready operational. Also, the worker is created, +it's in the ``Procfile``, but is turned off by default: + +.. code-block:: bash + + # Set the broker URL to Redis + heroku config:set CELERY_BROKER_URL=`heroku config:get REDIS_URL` + # Scale dyno to 1 instance + heroku ps:scale worker=1 + +Sentry +++++++ + +If you're opted for Sentry error tracking, you can either install it through the `Sentry add-on`_: + +.. code-block:: bash + + heroku addons:create sentry:f1 + + +Or add the DSN for your account, if you already have one: + +.. code-block:: bash + + heroku config:set SENTRY_DSN=https://xxxx@sentry.io/12345 + +.. _Sentry add-on: https://elements.heroku.com/addons/sentry + + +Gulp or Webpack ++++++++++++++++ + +If you've opted for Gulp or Webpack as frontend pipeline, you'll most likely need to setup +your app to use `multiple buildpacks`_: one for Python & one for Node.js: + +.. code-block:: bash + + heroku buildpacks:add --index 1 heroku/nodejs + +At time of writing, this should do the trick: during deployment, +the Heroku should run ``npm install`` and then ``npm build``, +which run the SASS compilation & JS bundling. + +If things don't work, please refer to the Heroku docs. + +.. _multiple buildpacks: https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst index ea25b3ae5..2fa6a960c 100644 --- a/docs/deployment-on-pythonanywhere.rst +++ b/docs/deployment-on-pythonanywhere.rst @@ -15,7 +15,7 @@ Full instructions follow, but here's a high-level view. 2. Set your config variables in the *postactivate* script -3. Run the *manage.py* ``migrate`` and ``collectstatic`` commands +3. Run the *manage.py* ``migrate`` and ``collectstatic`` commands. If you've opted for django-compressor, also run ``compress`` 4. Add an entry to the PythonAnywhere *Web tab* @@ -25,20 +25,19 @@ Full instructions follow, but here's a high-level view. Once you've been through this one-off config, future deployments are much simpler: just ``git pull`` and then hit the "Reload" button :) - Getting your code and dependencies installed on PythonAnywhere -------------------------------------------------------------- -Make sure your project is fully commited and pushed up to Bitbucket or Github or wherever it may be. Then, log into your PythonAnywhere account, open up a **Bash** console, clone your repo, and create a virtualenv: +Make sure your project is fully committed and pushed up to Bitbucket or Github or wherever it may be. Then, log into your PythonAnywhere account, open up a **Bash** console, clone your repo, and create a virtualenv: .. code-block:: bash git clone # you can also use hg cd my-project-name - mkvirtualenv --python=/usr/bin/python3.6 my-project-name + mkvirtualenv --python=/usr/bin/python3.10 my-project-name pip install -r requirements/production.txt # may take a few minutes - +.. note:: We're creating the virtualenv using Python 3.10 (``--python=/usr/bin/python3.10```), although Cookiecutter Django generates a project for Python 3.11. This is because, at time of writing, PythonAnywhere only supports Python 3.10. It shouldn't be a problem, but if is, you may try changing the Python version to 3.11 and see if it works. If it does, please let us know, or even better, submit a pull request to update this section. Setting environment variables in the console -------------------------------------------- @@ -57,7 +56,7 @@ Set environment variables via the virtualenv "postactivate" script (this will se vi $VIRTUAL_ENV/bin/postactivate -**TIP:** *If you don't like vi, you can also edit this file via the PythonAnywhere "Files" menu; look in the ".virtualenvs" folder*. +.. note:: If you don't like vi, you can also edit this file via the PythonAnywhere "Files" menu; look in the ".virtualenvs" folder. Add these exports @@ -73,13 +72,14 @@ Add these exports export DJANGO_AWS_ACCESS_KEY_ID= export DJANGO_AWS_SECRET_ACCESS_KEY= export DJANGO_AWS_STORAGE_BUCKET_NAME= - export DATABASE_URL='' + export DATABASE_URL='' + export REDIS_URL='' -**NOTE:** *The AWS details are not required if you're using whitenoise or the built-in pythonanywhere static files service, but you do need to set them to blank, as above.* +.. note:: The AWS details are not required if you're using whitenoise or the built-in pythonanywhere static files service, but you do need to set them to blank, as above. -Database setup: ---------------- +Database setup +-------------- Go to the PythonAnywhere **Databases tab** and configure your database. @@ -109,17 +109,26 @@ Now run the migration, and collectstatic: source $VIRTUAL_ENV/bin/postactivate python manage.py migrate python manage.py collectstatic + # if using django-compressor: + python manage.py compress # and, optionally python manage.py createsuperuser +Redis +----- + +PythonAnywhere does NOT `offer a built-in solution `_ for Redis, however the production setup from Cookiecutter Django uses Redis as cache and requires one. + +We recommend to signup to a separate service offering hosted Redis (e.g. `Redislab `_) and use the URL they provide. + Configure the PythonAnywhere Web Tab ------------------------------------ Go to the PythonAnywhere **Web tab**, hit **Add new web app**, and choose **Manual Config**, and then the version of Python you used for your virtualenv. -**NOTE:** *If you're using a custom domain (not on \*.pythonanywhere.com), then you'll need to set up a CNAME with your domain registrar.* +.. note:: If you're using a custom domain (not on \*.pythonanywhere.com), then you'll need to set up a CNAME with your domain registrar. When you're redirected back to the web app config screen, set the **path to your virtualenv**. If you used virtualenvwrapper as above, you can just enter its name. @@ -152,15 +161,14 @@ Click through to the **WSGI configuration file** link (near the top) and edit th Back on the Web tab, hit **Reload**, and your app should be live! -**NOTE:** *you may see security warnings until you set up your SSL certificates. If you -want to supress them temporarily, set DJANGO_SECURE_SSL_REDIRECT to blank. Follow -the instructions here to get SSL set up: https://help.pythonanywhere.com/pages/SSLOwnDomains/* +.. note:: You may see security warnings until you set up your SSL certificates. If you want to suppress them temporarily, set ``DJANGO_SECURE_SSL_REDIRECT`` to blank. Follow `these instructions `_ to get SSL set up. + Optional: static files ---------------------- -If you want to use the PythonAnywhere static files service instead of using whitenoise or S3, you'll find its configuration section on the Web tab. Essentially you'll need an entry to match your ``STATIC_URL`` and ``STATIC_ROOT`` settings. There's more info here: https://help.pythonanywhere.com/pages/DjangoStaticFiles +If you want to use the PythonAnywhere static files service instead of using whitenoise or S3, you'll find its configuration section on the Web tab. Essentially you'll need an entry to match your ``STATIC_URL`` and ``STATIC_ROOT`` settings. There's more info `in this article `_. Future deployments @@ -175,7 +183,9 @@ For subsequent deployments, the procedure is much simpler. In a Bash console: git pull python manage.py migrate python manage.py collectstatic + # if using django-compressor: + python manage.py compress And then go to the Web tab and hit **Reload** -**TIP:** *if you're really keen, you can set up git-push based deployments: https://blog.pythonanywhere.com/87/* +.. note:: If you're really keen, you can set up git-push based deployments: https://blog.pythonanywhere.com/87/ diff --git a/docs/deployment-with-docker.rst b/docs/deployment-with-docker.rst index f6e21e828..c1b8c6d7b 100644 --- a/docs/deployment-with-docker.rst +++ b/docs/deployment-with-docker.rst @@ -7,8 +7,8 @@ Deployment with Docker Prerequisites ------------- -* Docker 1.10+. -* Docker Compose 1.6+ +* Docker 17.05+. +* Docker Compose 1.17+ Understanding the Docker Compose Setup @@ -19,13 +19,15 @@ Before you begin, check out the ``production.yml`` file in the root of this proj * ``django``: your application running behind ``Gunicorn``; * ``postgres``: PostgreSQL database with the application's relational data; * ``redis``: Redis instance for caching; -* ``caddy``: Caddy web server with HTTPS on by default. +* ``traefik``: Traefik reverse proxy with HTTPS on by default. Provided you have opted for Celery (via setting ``use_celery`` to ``y``) there are three more services: * ``celeryworker`` running a Celery worker process; * ``celerybeat`` running a Celery beat process; -* ``flower`` running Flower_ (for more info, check out :ref:`CeleryFlower` instructions for local environment). +* ``flower`` running Flower_. + +The ``flower`` service is served by Traefik over HTTPS, through the port ``5555``. For more information about Flower and its login credentials, check out :ref:`CeleryFlower` instructions for local environment. .. _`Flower`: https://github.com/mher/flower @@ -35,7 +37,15 @@ Configuring the Stack The majority of services above are configured through the use of environment variables. Just check out :ref:`envs` and you will know the drill. -To obtain logs and information about crashes in a production setup, make sure that you have access to an external Sentry instance (e.g. by creating an account with `sentry.io`_), and set the ``SENTRY_DSN`` variable. +To obtain logs and information about crashes in a production setup, make sure that you have access to an external Sentry instance (e.g. by creating an account with `sentry.io`_), and set the ``SENTRY_DSN`` variable. Logs of level `logging.ERROR` are sent as Sentry events. Therefore, in order to send a Sentry event use: + +.. code-block:: python + + import logging + logging.error("This event is sent to Sentry", extra={"": ""}) + +The `extra` parameter allows you to send additional information about the context of this error. + You will probably also need to setup the Mail backend, for example by adding a `Mailgun`_ API key and a `Mailgun`_ sender domain, otherwise, the account creation view will crash and result in a 500 error when the backend attempts to send an email to the account owner. @@ -43,6 +53,11 @@ You will probably also need to setup the Mail backend, for example by adding a ` .. _Mailgun: https://mailgun.com +.. warning:: + + .. include:: mailgun.rst + + Optional: Use AWS IAM Role for EC2 instance ------------------------------------------- @@ -63,12 +78,38 @@ It is always better to deploy a site behind HTTPS and will become crucial as the * Access to the Django admin is set up by default to require HTTPS in production or once *live*. -The Caddy web server used in the default configuration will get you a valid certificate from Lets Encrypt and update it automatically. All you need to do to enable this is to make sure that your DNS records are pointing to the server Caddy runs on. +The Traefik reverse proxy used in the default configuration will get you a valid certificate from Lets Encrypt and update it automatically. All you need to do to enable this is to make sure that your DNS records are pointing to the server Traefik runs on. -You can read more about this here at `Automatic HTTPS`_ in the Caddy docs. +You can read more about this feature and how to configure it, at `Automatic HTTPS`_ in the Traefik docs. -.. _Automatic HTTPS: https://caddyserver.com/docs/automatic-https +.. _Automatic HTTPS: https://docs.traefik.io/https/acme/ +.. _webpack-whitenoise-limitation: + +Webpack without Whitenoise limitation +------------------------------------- + +If you opt for Webpack without Whitenoise, Webpack needs to know the static URL at build time, when running ``docker-compose build`` (See ``webpack/prod.config.js``). Depending on your setup, this URL may come from the following environment variables: + +- ``AWS_STORAGE_BUCKET_NAME`` +- ``DJANGO_AWS_S3_CUSTOM_DOMAIN`` +- ``DJANGO_GCP_STORAGE_BUCKET_NAME`` +- ``DJANGO_AZURE_CONTAINER_NAME`` + +The Django settings are getting these values at runtime via the ``.envs/.production/.django`` file , but Docker does not read this file at build time, it only look for a ``.env`` in the root of the project. Failing to pass the values correctly will result in a page without CSS styles nor javascript. + +To solve this, you can either: + +1. merge all the env files into ``.env`` by running:: + + merge_production_dotenvs_in_dotenv.py + +2. create a ``.env`` file in the root of the project with just variables you need. You'll need to also define them in ``.envs/.production/.django`` (hence duplicating them). +3. set these variables when running the build command:: + + DJANGO_AWS_S3_CUSTOM_DOMAIN=example.com docker-compose -f production.yml build``. + +None of these options are ideal, we're open to suggestions on how to improve this. If you think you have one, please open an issue or a pull request. (Optional) Postgres Data Volume Modifications --------------------------------------------- @@ -109,10 +150,10 @@ To check the logs out, run:: If you want to scale your application, run:: - docker-compose -f production.yml scale django=4 - docker-compose -f production.yml scale celeryworker=2 + docker-compose -f production.yml up --scale django=4 + docker-compose -f production.yml up --scale celeryworker=2 -.. warning:: don't try to scale ``postgres``, ``celerybeat``, or ``caddy``. +.. warning:: don't try to scale ``postgres``, ``celerybeat``, or ``traefik``. To see how your containers are doing run:: @@ -139,8 +180,14 @@ If you are using ``supervisor``, you can use this file as a starting point:: Move it to ``/etc/supervisor/conf.d/{{cookiecutter.project_slug}}.conf`` and run:: supervisorctl reread + supervisorctl update supervisorctl start {{cookiecutter.project_slug}} For status check, run:: supervisorctl status + +Media files without cloud provider +---------------------------------- + +If you chose no cloud provider and Docker, the media files will be served by an nginx service, from a ``production_django_media`` volume. Make sure to keep this around to avoid losing any media files. diff --git a/docs/developing-locally-docker.rst b/docs/developing-locally-docker.rst index 08b25f3bc..3dbe6e47d 100644 --- a/docs/developing-locally-docker.rst +++ b/docs/developing-locally-docker.rst @@ -3,8 +3,11 @@ Getting Up and Running Locally With Docker .. index:: Docker -The steps below will get you up and running with a local development environment. -All of these commands assume you are in the root of your generated project. +.. note:: + + If you're new to Docker, please be aware that some resources are cached system-wide + and might reappear if you generate a project multiple times with the same name (e.g. + :ref:`this issue with Postgres `). Prerequisites @@ -12,21 +15,17 @@ Prerequisites * Docker; if you don't have it yet, follow the `installation instructions`_; * Docker Compose; refer to the official documentation for the `installation guide`_. +* Pre-commit; refer to the official documentation for the `pre-commit`_. +* Cookiecutter; refer to the official GitHub repository of `Cookiecutter`_ .. _`installation instructions`: https://docs.docker.com/install/#supported-platforms .. _`installation guide`: https://docs.docker.com/compose/install/ +.. _`pre-commit`: https://pre-commit.com/#install +.. _`Cookiecutter`: https://github.com/cookiecutter/cookiecutter - -Attention, Windows Users ------------------------- - -Currently PostgreSQL (``psycopg2`` python package) is not installed inside Docker containers for Windows users, while it is required by the generated Django project. To fix this, add ``psycopg2`` to the list of requirements inside ``requirements/base.txt``:: - - # Python-PostgreSQL Database Adapter - psycopg2==2.6.2 - -Doing this will prevent the project from being installed in an Windows-only environment (thus without usage of Docker). If you want to use this project without Docker, make sure to remove ``psycopg2`` from the requirements again. - +Before Getting Started +---------------------- +.. include:: generate-project-block.rst Build the Stack --------------- @@ -37,6 +36,13 @@ This can take a while, especially the first time you run this particular command Generally, if you want to emulate production environment use ``production.yml`` instead. And this is true for any other actions you might need to perform: whenever a switch is required, just do it! +Before doing any git commit, `pre-commit`_ should be installed globally on your local machine, and then:: + + $ git init + $ pre-commit install + +Failing to do so will result with a bunch of CI and Linter errors that can be avoided with pre-commit. + Run the Stack ------------- @@ -105,7 +111,6 @@ The most important thing for us here now is ``env_file`` section enlisting ``./. │   ├── .django │   └── .postgres └── .production - ├── .caddy ├── .django └── .postgres @@ -120,9 +125,9 @@ Consider the aforementioned ``.envs/.local/.postgres``: :: POSTGRES_USER=XgOWtQtJecsAbaIyslwGvFvPawftNaqO POSTGRES_PASSWORD=jSljDz4whHuwO3aJIgVBrqEml5Ycbghorep4uVJ4xjDYQu0LfuTZdctj7y0YcCLu -The three envs we are presented with here are ``POSTGRES_DB``, ``POSTGRES_USER``, and ``POSTGRES_PASSWORD`` (by the way, their values have also been generated for you). You might have figured out already where these definitions will end up; it's all the same with ``django`` and ``caddy`` service container envs. +The three envs we are presented with here are ``POSTGRES_DB``, ``POSTGRES_USER``, and ``POSTGRES_PASSWORD`` (by the way, their values have also been generated for you). You might have figured out already where these definitions will end up; it's all the same with ``django`` service container envs. -One final touch: should you ever need to merge ``.envs/production/*`` in a single ``.env`` run the ``merge_production_dotenvs_in_dotenv.py``: :: +One final touch: should you ever need to merge ``.envs/.production/*`` in a single ``.env`` run the ``merge_production_dotenvs_in_dotenv.py``: :: $ python merge_production_dotenvs_in_dotenv.py @@ -139,6 +144,19 @@ This tells our computer that all future commands are specifically for the dev1 m $ eval "$(docker-machine env dev1)" +Add 3rd party python packages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To install a new 3rd party python package, you cannot use ``pip install ``, that would only add the package to the container. The container is ephemeral, so that new library won't be persisted if you run another container. Instead, you should modify the Docker image: +You have to modify the relevant requirement file: base, local or production by adding: :: + + == + +To get this change picked up, you'll need to rebuild the image(s) and restart the running container: :: + + docker-compose -f local.yml build + docker-compose -f local.yml up + Debugging ~~~~~~~~~ @@ -160,17 +178,37 @@ django-debug-toolbar In order for ``django-debug-toolbar`` to work designate your Docker Machine IP with ``INTERNAL_IPS`` in ``local.py``. +docker +"""""" + +The ``container_name`` from the yml file can be used to check on containers with docker commands, for example: :: + + $ docker logs _local_celeryworker + $ docker top _local_celeryworker + + +Notice that the ``container_name`` is generated dynamically using your project slug as a prefix + Mailhog ~~~~~~~ When developing locally you can go with MailHog_ for email testing provided ``use_mailhog`` was set to ``y`` on setup. To proceed, -#. make sure ``mailhog`` container is up and running; +#. make sure ``_local_mailhog`` container is up and running; #. open up ``http://127.0.0.1:8025``. .. _Mailhog: https://github.com/mailhog/MailHog/ +.. _`CeleryTasks`: + +Celery tasks in local development +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When not using docker Celery tasks are set to run in Eager mode, so that a full stack is not needed. When using docker the task scheduler will be used by default. + +If you need tasks to be executed on the main thread during development set ``CELERY_TASK_ALWAYS_EAGER = True`` in ``config/settings/local.py``. + +Possible uses could be for testing, or ease of profiling with DJDT. .. _`CeleryFlower`: @@ -187,3 +225,101 @@ Prerequisites: By default, it's enabled both in local and production environments (``local.yml`` and ``production.yml`` Docker Compose configs, respectively) through a ``flower`` service. For added security, ``flower`` requires its clients to provide authentication credentials specified as the corresponding environments' ``.envs/.local/.django`` and ``.envs/.production/.django`` ``CELERY_FLOWER_USER`` and ``CELERY_FLOWER_PASSWORD`` environment variables. Check out ``localhost:5555`` and see for yourself. .. _`Flower`: https://github.com/mher/flower + +Using Webpack or Gulp +~~~~~~~~~~~~~~~~~~~~~ + +When using Webpack or Gulp as the ``frontend_pipeline`` option, you should access your application at the address of the ``node`` service in order to see your correct styles. This is http://localhost:3000 by default. When using any of the other ``frontend_pipeline`` options, you should use the address of the ``django`` service, http://localhost:8000. + +Developing locally with HTTPS +----------------------------- + +Increasingly it is becoming necessary to develop software in a secure environment in order that there are very few changes when deploying to production. Recently Facebook changed their policies for apps/sites that use Facebook login which requires the use of an HTTPS URL for the OAuth redirect URL. So if you want to use the ``users`` application with a OAuth provider such as Facebook, securing your communication to the local development environment will be necessary. + +In order to create a secure environment, we need to have a trusted SSL certificate installed in our Docker application. + +#. **Let's Encrypt** + + The official line from Let’s Encrypt is: + + [For local development section] ... The best option: Generate your own certificate, either self-signed or signed by a local root, and trust it in your operating system’s trust store. Then use that certificate in your local web server. See below for details. + + See `letsencrypt.org - certificates-for-localhost`_ + + .. _`letsencrypt.org - certificates-for-localhost`: https://letsencrypt.org/docs/certificates-for-localhost/ + +#. **mkcert: Valid Https Certificates For Localhost** + + `mkcert`_ is a simple by design tool that hides all the arcane knowledge required to generate valid TLS certificates. It works for any hostname or IP, including localhost. It supports macOS, Linux, and Windows, and Firefox, Chrome and Java. It even works on mobile devices with a couple manual steps. + + See https://blog.filippo.io/mkcert-valid-https-certificates-for-localhost/ + + .. _`mkcert`: https://github.com/FiloSottile/mkcert/blob/master/README.md#supported-root-stores + +After installing a trusted TLS certificate, configure your docker installation. We are going to configure an ``nginx`` reverse-proxy server. This makes sure that it does not interfere with our ``traefik`` configuration that is reserved for production environments. + +These are the places that you should configure to secure your local environment. + +certs +~~~~~ + +Take the certificates that you generated and place them in a folder called ``certs`` in the project's root folder. Assuming that you registered your local hostname as ``my-dev-env.local``, the certificates you will put in the folder should have the names ``my-dev-env.local.crt`` and ``my-dev-env.local.key``. + +local.yml +~~~~~~~~~ + +#. Add the ``nginx-proxy`` service. :: + + ... + + nginx-proxy: + image: jwilder/nginx-proxy:alpine + container_name: nginx-proxy + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./certs:/etc/nginx/certs + restart: always + depends_on: + - django + + ... + +#. Link the ``nginx-proxy`` to ``django`` through environment variables. + + ``django`` already has an ``.env`` file connected to it. Add the following variables. You should do this especially if you are working with a team and you want to keep your local environment details to yourself. + + :: + + # HTTPS + # ------------------------------------------------------------------------------ + VIRTUAL_HOST=my-dev-env.local + VIRTUAL_PORT=8000 + + The services run behind the reverse proxy. + +config/settings/local.py +~~~~~~~~~~~~~~~~~~~~~~~~ + +You should allow the new hostname. :: + + ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1", "my-dev-env.local"] + +Rebuild your ``docker`` application. :: + + $ docker-compose -f local.yml up -d --build + +Go to your browser and type in your URL bar ``https://my-dev-env.local`` + +See `https with nginx`_ for more information on this configuration. + + .. _`https with nginx`: https://codewithhugo.com/docker-compose-local-https/ + +.gitignore +~~~~~~~~~~ + +Add ``certs/*`` to the ``.gitignore`` file. This allows the folder to be included in the repo but its contents to be ignored. + +*This configuration is for local development environments only. Do not use this for production since you might expose your local* ``rootCA-key.pem``. diff --git a/docs/developing-locally.rst b/docs/developing-locally.rst index 09c5db396..b79033aaa 100644 --- a/docs/developing-locally.rst +++ b/docs/developing-locally.rst @@ -9,27 +9,41 @@ Setting Up Development Environment Make sure to have the following on your host: -* Python 3.6 +* Python 3.11 * PostgreSQL_. * Redis_, if using Celery +* Cookiecutter_ First things first. #. Create a virtualenv: :: - $ python3.6 -m venv + $ python3.11 -m venv #. Activate the virtualenv you have just created: :: $ source /bin/activate +#. + .. include:: generate-project-block.rst + #. Install development requirements: :: + $ cd $ pip install -r requirements/local.txt + $ git init # A git repo is required for pre-commit to install + $ pre-commit install + + .. note:: + + the `pre-commit` hook exists in the generated project as default. + For the details of `pre-commit`, follow the `pre-commit`_ site. #. Create a new PostgreSQL database using createdb_: :: - $ createdb -U postgres --password + $ createdb --username=postgres + + ``project_slug`` is what you have entered as the project_slug at the setup stage. .. note:: @@ -62,15 +76,21 @@ First things first. $ python manage.py migrate -#. See the application being served through Django development server: :: +#. If you're running synchronously, see the application being served through Django development server: :: $ python manage.py runserver 0.0.0.0:8000 +or if you're running asynchronously: :: + + $ uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html' + .. _PostgreSQL: https://www.postgresql.org/download/ .. _Redis: https://redis.io/download +.. _CookieCutter: https://github.com/cookiecutter/cookiecutter .. _createdb: https://www.postgresql.org/docs/current/static/app-createdb.html -.. _initial PostgreSQL set up: http://suite.opengeo.org/docs/latest/dataadmin/pgGettingStarted/firstconnect.html +.. _initial PostgreSQL set up: https://web.archive.org/web/20190303010033/http://suite.opengeo.org/docs/latest/dataadmin/pgGettingStarted/firstconnect.html .. _postgres documentation: https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html +.. _pre-commit: https://pre-commit.com/ .. _direnv: https://direnv.net/ @@ -118,11 +138,58 @@ In production, we have Mailgun_ configured to have your back! .. _Mailgun: https://www.mailgun.com/ +Celery +------ + +If the project is configured to use Celery as a task scheduler then, by default, tasks are set to run on the main thread when developing locally instead of getting sent to a broker. However, if you have Redis setup on your local machine, you can set the following in ``config/settings/local.py``:: + + CELERY_TASK_ALWAYS_EAGER = False + +Next, make sure `redis-server` is installed (per the `Getting started with Redis`_ guide) and run the server in one terminal:: + + $ redis-server + +Start the Celery worker by running the following command in another terminal:: + + $ celery -A config.celery_app worker --loglevel=info + +That Celery worker should be running whenever your app is running, typically as a background process, +so that it can pick up any tasks that get queued. Learn more from the `Celery Workers Guide`_. + +The project comes with a simple task for manual testing purposes, inside `/users/tasks.py`. To queue that task locally, start the Django shell, import the task, and call `delay()` on it:: + + $ python manage.py shell + >> from .users.tasks import get_users_count + >> get_users_count.delay() + +You can also use Django admin to queue up tasks, thanks to the `django-celerybeat`_ package. + +.. _Getting started with Redis guide: https://redis.io/docs/getting-started/ +.. _Celery Workers Guide: https://docs.celeryq.dev/en/stable/userguide/workers.html +.. _django-celerybeat: https://django-celery-beat.readthedocs.io/en/latest/ + + Sass Compilation & Live Reloading --------------------------------- -If you’d like to take advantage of live reloading and Sass compilation you can do so with a little -bit of preparation, see :ref:`sass-compilation-live-reload`. +If you've opted for Gulp or Webpack as front-end pipeline, the project comes configured with `Sass`_ compilation and `live reloading`_. As you change you Sass/JS source files, the task runner will automatically rebuild the corresponding CSS and JS assets and reload them in your browser without refreshing the page. + +#. Make sure that `Node.js`_ v18 is installed on your machine. +#. In the project root, install the JS dependencies with:: + + $ npm install + +#. Now - with your virtualenv activated - start the application by running:: + + $ npm run dev + + The app will now run with live reloading enabled, applying front-end changes dynamically. + +.. note:: The task will start 2 processes in parallel: the static assets build loop on one side, and the Django server on the other. You do NOT need to run Django as your would normally with ``manage.py runserver``. + +.. _Node.js: http://nodejs.org/download/ +.. _Sass: https://sass-lang.com/ +.. _live reloading: https://browsersync.io Summary ------- diff --git a/docs/docker-postgres-backups.rst b/docs/docker-postgres-backups.rst index c1a8a5e0c..875d737eb 100644 --- a/docs/docker-postgres-backups.rst +++ b/docs/docker-postgres-backups.rst @@ -55,8 +55,11 @@ With a single backup file copied to ``.`` that would be :: $ docker cp 9c5c3f055843:/backups/backup_2018_03_13T09_05_07.sql.gz . -.. _`command`: https://docs.docker.com/engine/reference/commandline/cp/ +You can also get the container ID using ``docker-compose -f local.yml ps -q postgres`` so if you want to automate your backups, you don't have to check the container ID manually every time. Here is the full command :: + $ docker cp $(docker-compose -f local.yml ps -q postgres):/backups ./backups + +.. _`command`: https://docs.docker.com/engine/reference/commandline/cp/ Restoring from the Existing Backup ---------------------------------- @@ -85,3 +88,11 @@ You will see something like :: # ... ALTER TABLE SUCCESS: The 'my_project' database has been restored from the '/backups/backup_2018_03_13T09_05_07.sql.gz' backup. + + +Backup to Amazon S3 +---------------------------------- +For uploading your backups to Amazon S3 you can use the aws cli container. There is an upload command for uploading the postgres /backups directory recursively and there is a download command for downloading a specific backup. The default S3 environment variables are used. :: + + $ docker-compose -f production.yml run --rm awscli upload + $ docker-compose -f production.yml run --rm awscli download backup_2018_03_13T09_05_07.sql.gz diff --git a/docs/document.rst b/docs/document.rst new file mode 100644 index 000000000..974c66c69 --- /dev/null +++ b/docs/document.rst @@ -0,0 +1,44 @@ +.. _document: + +Document +========= + +This project uses Sphinx_ documentation generator. + +After you have set up to `develop locally`_, run the following command from the project directory to build and serve HTML documentation: :: + + $ make -C docs livehtml + +If you set up your project to `develop locally with docker`_, run the following command: :: + + $ docker-compose -f local.yml up docs + +Navigate to port 9000 on your host to see the documentation. This will be opened automatically at `localhost`_ for local, non-docker development. + +Note: using Docker for documentation sets up a temporary SQLite file by setting the environment variable ``DATABASE_URL=sqlite:///readthedocs.db`` in ``docs/conf.py`` to avoid a dependency on PostgreSQL. + +Generate API documentation +---------------------------- + +Edit the ``docs`` files and project application docstrings to create your documentation. + +Sphinx can automatically include class and function signatures and docstrings in generated documentation. +See the generated project documentation for more examples. + +Setting up ReadTheDocs +---------------------- + +To setup your documentation on `ReadTheDocs`_, you must + +1. Go to `ReadTheDocs`_ and login/create an account +2. Add your GitHub repository +3. Trigger a build + +Additionally, you can auto-build Pull Request previews, but `you must enable it`_. + +.. _localhost: http://localhost:9000/ +.. _Sphinx: https://www.sphinx-doc.org/en/master/index.html +.. _develop locally: ./developing-locally.html +.. _develop locally with docker: ./developing-locally-docker.html +.. _ReadTheDocs: https://readthedocs.org/ +.. _you must enable it: https://docs.readthedocs.io/en/latest/guides/autobuild-docs-for-pull-requests.html#autobuild-documentation-for-pull-requests diff --git a/docs/faq.rst b/docs/faq.rst index 1481a8bac..52a99467c 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -6,11 +6,11 @@ FAQ Why is there a django.contrib.sites directory in Cookiecutter Django? --------------------------------------------------------------------- -It is there to add a migration so you don't have to manually change the ``sites.Site`` record from ``example.com`` to whatever your domain is. Instead, your ``{{cookiecutter.domain_name}}`` and {{cookiecutter.project_name}} value is placed by **Cookiecutter** in the domain and name fields respectively. +It is there to add a migration so you don't have to manually change the ``sites.Site`` record from ``example.com`` to whatever your domain is. Instead, your ``{{cookiecutter.domain_name}}`` and ``{{cookiecutter.project_name}}`` value is placed by **Cookiecutter** in the domain and name fields respectively. See `0003_set_site_domain_and_name.py`_. -.. _`0003_set_site_domain_and_name.py`: https://github.com/pydanny/cookiecutter-django/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/%7B%7Bcookiecutter.project_slug%7D%7D/contrib/sites/migrations/0003_set_site_domain_and_name.py +.. _`0003_set_site_domain_and_name.py`: https://github.com/cookiecutter/cookiecutter-django/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/%7B%7Bcookiecutter.project_slug%7D%7D/contrib/sites/migrations/0003_set_site_domain_and_name.py Why aren't you using just one configuration file (12-Factor App) @@ -24,4 +24,4 @@ Why doesn't this follow the layout from Two Scoops of Django? You may notice that some elements of this project do not exactly match what we describe in chapter 3 of `Two Scoops of Django 1.11`_. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored. -.. _Two Scoops of Django 1.11: https://www.twoscoopspress.com/collections/django/products/two-scoops-of-django-1-11 +.. _Two Scoops of Django 1.11: https://www.feldroy.com/collections/django/products/two-scoops-of-django-1-11 diff --git a/docs/generate-project-block.rst b/docs/generate-project-block.rst new file mode 100644 index 000000000..fca3fe1a8 --- /dev/null +++ b/docs/generate-project-block.rst @@ -0,0 +1,6 @@ +Generate a new cookiecutter-django project: :: + + $ cookiecutter gh:cookiecutter/cookiecutter-django + +For more information refer to +:ref:`Project Generation Options `. diff --git a/docs/index.rst b/docs/index.rst index 5cb07b4b0..da5186487 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,13 +1,14 @@ .. cookiecutter-django documentation master file. Welcome to Cookiecutter Django's documentation! -==================================================================== +=============================================== -A Cookiecutter_ template for Django. +Powered by Cookiecutter_, Cookiecutter Django is a project template for jumpstarting production-ready Django projects. The template offers a number of generation options, we invite you to check the :ref:`dedicated page ` to learn more about each of them. -.. _cookiecutter: https://github.com/audreyr/cookiecutter +.. _cookiecutter: https://github.com/cookiecutter/cookiecutter -Contents: +Contents +-------- .. toctree:: :maxdepth: 2 @@ -18,15 +19,18 @@ Contents: settings linters testing + document deployment-on-pythonanywhere deployment-on-heroku deployment-with-docker docker-postgres-backups + websocket faq troubleshooting + contributing Indices and tables -================== +------------------ * :ref:`genindex` * :ref:`search` diff --git a/docs/linters.rst b/docs/linters.rst index e59ff0df7..a4f60cc8d 100644 --- a/docs/linters.rst +++ b/docs/linters.rst @@ -19,13 +19,13 @@ The config for flake8 is located in setup.cfg. It specifies: pylint ------ -This is included in flake8's checks, but you can also run it separately to see a more detailed report: :: +To run pylint: :: $ pylint The config for pylint is located in .pylintrc. It specifies: -* Use the pylint_common and pylint_django plugins. If using Celery, also use pylint_celery. +* Use the pylint_django plugin. If using Celery, also use pylint_celery. * Set max line length to 120 chars * Disable linting messages for missing docstring and invalid name * max-parents=13 diff --git a/docs/live-reloading-and-sass-compilation.rst b/docs/live-reloading-and-sass-compilation.rst deleted file mode 100644 index a55b4fd8c..000000000 --- a/docs/live-reloading-and-sass-compilation.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. _sass-compilation-live-reload: - -Sass Compilation & Live Reloading -================================= - -If you'd like to take advantage of `live reload`_ and Sass compilation: - -- Make sure that nodejs_ is installed. Then in the project root run:: - - $ npm install - -.. _nodejs: http://nodejs.org/download/ - -- Now you just need:: - - $ npm run dev - -The base app will now run as it would with the usual ``manage.py runserver`` but with live reloading and Sass compilation enabled. -When changing your Sass files, they will be automatically recompiled and change will be reflected in your browser without refreshing. - -To get live reloading to work you'll probably need to install an `appropriate browser extension`_ - -.. _live reload: http://livereload.com/ -.. _appropriate browser extension: http://livereload.com/extensions/ diff --git a/docs/mailgun.rst b/docs/mailgun.rst new file mode 100644 index 000000000..b5f49b625 --- /dev/null +++ b/docs/mailgun.rst @@ -0,0 +1,13 @@ +If your email server used to send email isn't configured properly (Mailgun by default), +attempting to send an email will cause an Internal Server Error. + +By default, ``django-allauth`` is setup to `have emails verifications mandatory`_, +which means it'll send a verification email when an unverified user tries to +log-in or when someone tries to sign-up. + +This may happen just after you've setup your Mailgun account, which is running in a +sandbox subdomain by default. Either add your email to the list of authorized recipients +or verify your domain. + + +.. _have emails verifications mandatory: https://django-allauth.readthedocs.io/en/latest/configuration.html?highlight=ACCOUNT_EMAIL_VERIFICATION diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index a54837979..a1d788173 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -1,6 +1,12 @@ +.. _template-options: + Project Generation Options ========================== +This page describes all the template options that will be prompted by the `cookiecutter CLI`_ prior to generating your project. + +.. _cookiecutter CLI: https://github.com/cookiecutter/cookiecutter + project_name: Your project's human-readable name, capitals and spaces allowed. @@ -18,6 +24,13 @@ author_name: email: The email address you want to identify yourself in the project. +username_type: + The type of username you want to use in the project. This can be either + ``username`` or ``email``. If you choose ``username``, the ``email`` field + will be included. If you choose ``email``, the ``username`` field will be + excluded. It is best practice to always include an email field, so there is + no option for having just the ``username`` field. + domain_name: The domain name you plan to use for your project once it goes live. Note that it can be safely changed later on whenever you need to. @@ -49,27 +62,50 @@ use_docker: postgresql_version: Select a PostgreSQL_ version to use. The choices are: - 1. 10.3 - 2. 10.2 - 3. 10.1 - 4. 9.6 - 5. 9.5 - 6. 9.4 - 7. 9.3 + 1. 14 + 2. 13 + 3. 12 + 4. 11 + 5. 10 -js_task_runner: - Select a JavaScript task runner. The choices are: +cloud_provider: + Select a cloud provider for static & media files. The choices are: + + 1. AWS_ + 2. GCP_ + 3. Azure_ + 4. None + + If you choose no cloud provider and docker, the production stack will serve the media files via an nginx Docker service. Without Docker, the media files won't work. + +mail_service: + Select an email service that Django-Anymail provides + + 1. Mailgun_ + 2. `Amazon SES`_ + 3. Mailjet_ + 4. Mandrill_ + 5. Postmark_ + 6. SendGrid_ + 7. SendinBlue_ + 8. SparkPost_ + 9. `Other SMTP`_ + +use_async: + Indicates whether the project should use web sockets with Uvicorn + Gunicorn. + +use_drf: + Indicates whether the project should be configured to use `Django Rest Framework`_. + +frontend_pipeline: + Select a pipeline to compile and optimise frontend assets (JS, CSS, ...): 1. None - 2. Gulp_ + 2. `Django Compressor`_ + 3. `Gulp`_ + 4. `Webpack`_ -custom_bootstrap_compilation: - Indicates whether the project should support Bootstrap recompilation - via the selected JavaScript task runner's task. This can be useful - for real-time Bootstrap variable alteration. - -use_compressor: - Indicates whether the project should be configured to use `Django Compressor`_. +Both Gulp and Webpack support Bootstrap recompilation with real-time variables alteration. use_celery: Indicates whether the project should be configured to use Celery_. @@ -87,13 +123,18 @@ use_heroku: Indicates whether the project should be configured so as to be deployable to Heroku_. -use_travisci: - Indicates whether the project should be configured to use `Travis CI`_. +ci_tool: + Select a CI tool for running tests. The choices are: + + 1. None + 2. `Travis CI`_ + 3. `Gitlab CI`_ + 4. `Github Actions`_ keep_local_envs_in_vcs: Indicates whether the project's ``.envs/.local/`` should be kept in VCS (comes in handy when working in teams where local environment reproducibility - is strongly encouraged). + is strongly encouraged). Note: .env(s) are only utilized when Docker Compose and/or Heroku support is enabled. debug: @@ -114,6 +155,23 @@ debug: .. _PostgreSQL: https://www.postgresql.org/docs/ .. _Gulp: https://github.com/gulpjs/gulp +.. _Webpack: https://webpack.js.org + +.. _AWS: https://aws.amazon.com/s3/ +.. _GCP: https://cloud.google.com/storage/ +.. _Azure: https://azure.microsoft.com/en-us/products/storage/blobs/ + +.. _Amazon SES: https://aws.amazon.com/ses/ +.. _Mailgun: https://www.mailgun.com +.. _Mailjet: https://www.mailjet.com +.. _Mandrill: http://mandrill.com +.. _Postmark: https://postmarkapp.com +.. _SendGrid: https://sendgrid.com +.. _SendinBlue: https://www.sendinblue.com +.. _SparkPost: https://www.sparkpost.com +.. _Other SMTP: https://anymail.readthedocs.io/en/stable/ + +.. _Django Rest Framework: https://github.com/encode/django-rest-framework/ .. _Django Compressor: https://github.com/django-compressor/django-compressor @@ -128,3 +186,7 @@ debug: .. _Heroku: https://github.com/heroku/heroku-buildpack-python .. _Travis CI: https://travis-ci.org/ + +.. _GitLab CI: https://docs.gitlab.com/ee/ci/ + +.. _Github Actions: https://docs.github.com/en/actions diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..d06b651b3 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,3 @@ +sphinx==6.2.1 +sphinx-rtd-theme==1.2.2 +myst-parser==2.0.0 diff --git a/docs/settings.rst b/docs/settings.rst index 8c0f5431c..0880bce95 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -22,7 +22,6 @@ DATABASE_URL DATABASES auto w/ Dock DJANGO_ADMIN_URL n/a 'admin/' raises error DJANGO_DEBUG DEBUG True False DJANGO_SECRET_KEY SECRET_KEY auto-generated raises error -DJANGO_SECURE_BROWSER_XSS_FILTER SECURE_BROWSER_XSS_FILTER n/a True DJANGO_SECURE_SSL_REDIRECT SECURE_SSL_REDIRECT n/a True DJANGO_SECURE_CONTENT_TYPE_NOSNIFF SECURE_CONTENT_TYPE_NOSNIFF n/a True DJANGO_SECURE_FRAME_DENY SECURE_FRAME_DENY n/a True @@ -44,11 +43,36 @@ CELERY_BROKER_URL CELERY_BROKER_URL auto w/ Dock DJANGO_AWS_ACCESS_KEY_ID AWS_ACCESS_KEY_ID n/a raises error DJANGO_AWS_SECRET_ACCESS_KEY AWS_SECRET_ACCESS_KEY n/a raises error DJANGO_AWS_STORAGE_BUCKET_NAME AWS_STORAGE_BUCKET_NAME n/a raises error +DJANGO_AWS_S3_REGION_NAME AWS_S3_REGION_NAME n/a None +DJANGO_AWS_S3_CUSTOM_DOMAIN AWS_S3_CUSTOM_DOMAIN n/a None +DJANGO_AWS_S3_MAX_MEMORY_SIZE AWS_S3_MAX_MEMORY_SIZE n/a 100_000_000 +DJANGO_GCP_STORAGE_BUCKET_NAME GS_BUCKET_NAME n/a raises error +GOOGLE_APPLICATION_CREDENTIALS n/a n/a raises error +DJANGO_AZURE_ACCOUNT_KEY AZURE_ACCOUNT_KEY n/a raises error +DJANGO_AZURE_ACCOUNT_NAME AZURE_ACCOUNT_NAME n/a raises error +DJANGO_AZURE_CONTAINER_NAME AZURE_CONTAINER n/a raises error SENTRY_DSN SENTRY_DSN n/a raises error -DJANGO_SENTRY_CLIENT SENTRY_CLIENT n/a raven.contrib.django.raven_compat.DjangoClient +SENTRY_ENVIRONMENT n/a n/a production +SENTRY_TRACES_SAMPLE_RATE n/a n/a 0.0 DJANGO_SENTRY_LOG_LEVEL SENTRY_LOG_LEVEL n/a logging.INFO -MAILGUN_API_KEY MAILGUN_ACCESS_KEY n/a raises error +MAILGUN_API_KEY MAILGUN_API_KEY n/a raises error MAILGUN_DOMAIN MAILGUN_SENDER_DOMAIN n/a raises error +MAILGUN_API_URL n/a n/a "https://api.mailgun.net/v3" +MAILJET_API_KEY MAILJET_API_KEY n/a raises error +MAILJET_SECRET_KEY MAILJET_SECRET_KEY n/a raises error +MAILJET_API_URL n/a n/a "https://api.mailjet.com/v3" +MANDRILL_API_KEY MANDRILL_API_KEY n/a raises error +MANDRILL_API_URL n/a n/a "https://mandrillapp.com/api/1.0" +POSTMARK_SERVER_TOKEN POSTMARK_SERVER_TOKEN n/a raises error +POSTMARK_API_URL n/a n/a "https://api.postmarkapp.com/" +SENDGRID_API_KEY SENDGRID_API_KEY n/a raises error +SENDGRID_GENERATE_MESSAGE_ID True n/a raises error +SENDGRID_MERGE_FIELD_FORMAT None n/a raises error +SENDGRID_API_URL n/a n/a "https://api.sendgrid.com/v3/" +SENDINBLUE_API_KEY SENDINBLUE_API_KEY n/a raises error +SENDINBLUE_API_URL n/a n/a "https://api.sendinblue.com/v3/" +SPARKPOST_API_KEY SPARKPOST_API_KEY n/a raises error +SPARKPOST_API_URL n/a n/a "https://api.sparkpost.com/api/v1" ======================================= =========================== ============================================== ====================================================================== -------------------------- diff --git a/docs/testing.rst b/docs/testing.rst index 6ca213883..bea45c6dd 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -19,26 +19,31 @@ You will get a readout of the `users` app that has already been set up with test If you set up your project to `develop locally with docker`_, run the following command: :: - $ docker-compose -f local.yml run django pytest + $ docker-compose -f local.yml run --rm django pytest -Targetting particular apps for testing in ``docker`` follows a similar pattern as previously shown above. +Targeting particular apps for testing in ``docker`` follows a similar pattern as previously shown above. Coverage -------- You should build your tests to provide the highest level of **code coverage**. You can run the ``pytest`` with code ``coverage`` by typing in the following command: :: - $ docker-compose -f local.yml run django coverage run -m pytest + $ coverage run -m pytest Once the tests are complete, in order to see the code coverage, run the following command: :: - $ docker-compose -f local.yml run django coverage report + $ coverage report + +If you're running the project locally with Docker, use these commands instead: :: + + $ docker-compose -f local.yml run --rm django coverage run -m pytest + $ docker-compose -f local.yml run --rm django coverage report .. note:: - At the root of the project folder, you will find the `pytest.ini` file. You can use this to customize_ the ``pytest`` to your liking. + At the root of the project folder, you will find the `pytest.ini` file. You can use this to customize_ the ``pytest`` to your liking. - There is also the `.coveragerc`. This is the configuration file for the ``coverage`` tool. You can find out more about `configuring`_ ``coverage``. + There is also the `.coveragerc`. This is the configuration file for the ``coverage`` tool. You can find out more about `configuring`_ ``coverage``. .. seealso:: @@ -49,8 +54,8 @@ Once the tests are complete, in order to see the code coverage, run the followin Since this is a fresh install, and there are no tests built using the Python `unittest`_ library yet, you should get feedback that says there were no tests carried out. .. _Pytest: https://docs.pytest.org/en/latest/example/simple.html -.. _develop locally: ../developing-locally.rst -.. _develop locally with docker: ..../developing-locally-docker.rst +.. _develop locally: ./developing-locally.html +.. _develop locally with docker: ./developing-locally-docker.html .. _customize: https://docs.pytest.org/en/latest/customize.html .. _unittest: https://docs.python.org/3/library/unittest.html#module-unittest -.. _configuring: https://coverage.readthedocs.io/en/v4.5.x/config.html \ No newline at end of file +.. _configuring: https://coverage.readthedocs.io/en/latest/config.html diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index d0c0ba434..293e9b652 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -1,15 +1,61 @@ Troubleshooting -===================================== +=============== This page contains some advice about errors and problems commonly encountered during the development of Cookiecutter Django applications. +Server Error on sign-up/log-in +------------------------------ + +Make sure you have configured the mail backend (e.g. Mailgun) by adding the API key and sender domain + +.. include:: mailgun.rst + +.. _docker-postgres-auth-failed: + +Docker: Postgres authentication failed +-------------------------------------- + +Examples of logs:: + + postgres_1 | 2018-06-07 19:11:23.963 UTC [81] FATAL: password authentication failed for user "pydanny" + postgres_1 | 2018-06-07 19:11:23.963 UTC [81] DETAIL: Password does not match for user "pydanny". + postgres_1 | Connection matched pg_hba.conf line 95: "host all all all md5" + +If you recreate the project multiple times with the same name, Docker would preserve the volumes for the postgres container between projects. Here is what happens: + +#. You generate the project the first time. The .env postgres file is populated with the random password +#. You run the docker-compose and the containers are created. The postgres container creates the database based on the .env file credentials +#. You "regenerate" the project with the same name, so the postgres .env file is populated with a new random password +#. You run docker-compose. Since the names of the containers are the same, docker will try to start them (not create them from scratch i.e. it won't execute the Dockerfile to recreate the database). When this happens, it tries to start the database based on the new credentials which do not match the ones that the database was created with, and you get the error message above. + +To fix this, you can either: + +- Clear your project-related Docker cache with ``docker-compose -f local.yml down --volumes --rmi all``. +- Use the Docker volume sub-commands to find volumes (`ls`_) and remove them (`rm`_). +- Use the `prune`_ command to clear system-wide (use with care!). + +.. _ls: https://docs.docker.com/engine/reference/commandline/volume_ls/ +.. _rm: https://docs.docker.com/engine/reference/commandline/volume_rm/ +.. _prune: https://docs.docker.com/v17.09/engine/reference/commandline/system_prune/ + +Variable is not set. Defaulting to a blank string +------------------------------------------------- + +Example:: + + WARN[0000] The "DJANGO_AWS_STORAGE_BUCKET_NAME" variable is not set. Defaulting to a blank string. + WARN[0000] The "DJANGO_AWS_S3_CUSTOM_DOMAIN" variable is not set. Defaulting to a blank string. + +You have probably opted for Docker + Webpack without Whitenoise. This is a know limitation of the combination, which needs a little bit of manual intervention. See the :ref:`dedicated section about it `. + +Others +------ + #. ``project_slug`` must be a valid Python module name or you will have issues on imports. #. ``jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag 'now'.``: please upgrade your cookiecutter version to >= 1.4 (see `#528`_) -#. Internal server error on user registration: make sure you have configured the mail backend (e.g. Mailgun) by adding the API key and sender domain - #. New apps not getting created in project root: This is the expected behavior, because cookiecutter-django does not change the way that django startapp works, you'll have to fix this manually (see `#1725`_) -.. _#528: https://github.com/pydanny/cookiecutter-django/issues/528#issuecomment-212650373 -.. _#1725: https://github.com/pydanny/cookiecutter-django/issues/1725#issuecomment-407493176 +.. _#528: https://github.com/cookiecutter/cookiecutter-django/issues/528#issuecomment-212650373 +.. _#1725: https://github.com/cookiecutter/cookiecutter-django/issues/1725#issuecomment-407493176 diff --git a/docs/websocket.rst b/docs/websocket.rst new file mode 100644 index 000000000..9d2e3264a --- /dev/null +++ b/docs/websocket.rst @@ -0,0 +1,25 @@ +.. _websocket: + +========= +Websocket +========= + +You can enable web sockets if you select ``use_async`` option when creating a project. That indicates whether the project can use web sockets with Uvicorn + Gunicorn. + +Usage +----- + +JavaScript example: :: + + > ws = new WebSocket('ws://localhost:8000/') // or 'wss:///' in prod + WebSocket {url: "ws://localhost:8000/", readyState: 0, bufferedAmount: 0, onopen: null, onerror: null, …} + > ws.onmessage = event => console.log(event.data) + event => console.log(event.data) + > ws.send("ping") + undefined + pong! + + +If you don't use Traefik, you might have to configure your reverse proxy accordingly (example with Nginx_). + +.. _Nginx: https://www.nginx.com/blog/websocket-nginx/ diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 45435dd02..11f165b78 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -5,10 +5,12 @@ NOTE: can potentially be run in Python 2.x environment (at least so we presume in `pre_gen_project.py`). -TODO: ? restrict Cookiecutter Django project initialization to Python 3.x environments only +TODO: restrict Cookiecutter Django project initialization to + Python 3.x environments only """ from __future__ import print_function +import json import os import random import shutil @@ -32,10 +34,7 @@ DEBUG_VALUE = "debug" def remove_open_source_files(): - file_names = [ - "CONTRIBUTORS.txt", - "LICENSE", - ] + file_names = ["CONTRIBUTORS.txt", "LICENSE"] for file_name in file_names: os.remove(file_name) @@ -46,6 +45,24 @@ def remove_gplv3_files(): os.remove(file_name) +def remove_custom_user_manager_files(): + os.remove( + os.path.join( + "{{cookiecutter.project_slug}}", + "users", + "managers.py", + ) + ) + os.remove( + os.path.join( + "{{cookiecutter.project_slug}}", + "users", + "tests", + "test_managers.py", + ) + ) + + def remove_pycharm_files(): idea_dir_path = ".idea" if os.path.exists(idea_dir_path): @@ -62,6 +79,10 @@ def remove_docker_files(): file_names = ["local.yml", "production.yml", ".dockerignore"] for file_name in file_names: os.remove(file_name) + if "{{ cookiecutter.use_pycharm }}".lower() == "y": + file_names = ["docker_compose_up_django.xml", "docker_compose_up_docs.xml"] + for file_name in file_names: + os.remove(os.path.join(".idea", "runConfigurations", file_name)) def remove_utility_files(): @@ -71,10 +92,15 @@ def remove_utility_files(): def remove_heroku_files(): file_names = ["Procfile", "runtime.txt", "requirements.txt"] for file_name in file_names: - if file_name == "requirements.txt" and "{{ cookiecutter.use_travisci }}".lower() == "y": + if file_name == "requirements.txt" and "{{ cookiecutter.ci_tool }}".lower() == "travis": # don't remove the file if we are using travisci but not using heroku continue os.remove(file_name) + shutil.rmtree("bin") + + +def remove_sass_files(): + shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "static", "sass")) def remove_gulp_files(): @@ -83,30 +109,135 @@ def remove_gulp_files(): os.remove(file_name) +def remove_webpack_files(): + shutil.rmtree("webpack") + remove_vendors_js() + + +def remove_vendors_js(): + vendors_js_path = os.path.join( + "{{ cookiecutter.project_slug }}", + "static", + "js", + "vendors.js", + ) + if os.path.exists(vendors_js_path): + os.remove(vendors_js_path) + + def remove_packagejson_file(): file_names = ["package.json"] for file_name in file_names: os.remove(file_name) -def remove_celery_app(): - shutil.rmtree(os.path.join("{{ cookiecutter.project_slug }}", "taskapp")) +def update_package_json(remove_dev_deps=None, remove_keys=None, scripts=None): + remove_dev_deps = remove_dev_deps or [] + remove_keys = remove_keys or [] + scripts = scripts or {} + with open("package.json", mode="r") as fd: + content = json.load(fd) + for package_name in remove_dev_deps: + content["devDependencies"].pop(package_name) + for key in remove_keys: + content.pop(key) + content["scripts"].update(scripts) + with open("package.json", mode="w") as fd: + json.dump(content, fd, ensure_ascii=False, indent=2) + fd.write("\n") + + +def handle_js_runner(choice, use_docker, use_async): + if choice == "Gulp": + update_package_json( + remove_dev_deps=[ + "@babel/core", + "@babel/preset-env", + "babel-loader", + "concurrently", + "css-loader", + "mini-css-extract-plugin", + "postcss-loader", + "postcss-preset-env", + "sass-loader", + "webpack", + "webpack-bundle-tracker", + "webpack-cli", + "webpack-dev-server", + "webpack-merge", + ], + remove_keys=["babel"], + scripts={ + "dev": "gulp", + "build": "gulp generate-assets", + }, + ) + remove_webpack_files() + elif choice == "Webpack": + scripts = { + "dev": "webpack serve --config webpack/dev.config.js", + "build": "webpack --config webpack/prod.config.js", + } + remove_dev_deps = [ + "browser-sync", + "cssnano", + "gulp", + "gulp-imagemin", + "gulp-plumber", + "gulp-postcss", + "gulp-rename", + "gulp-sass", + "gulp-uglify-es", + ] + if not use_docker: + dev_django_cmd = ( + "uvicorn config.asgi:application --reload" if use_async else "python manage.py runserver_plus" + ) + scripts.update( + { + "dev": "concurrently npm:dev:*", + "dev:webpack": "webpack serve --config webpack/dev.config.js", + "dev:django": dev_django_cmd, + } + ) + else: + remove_dev_deps.append("concurrently") + update_package_json(remove_dev_deps=remove_dev_deps, scripts=scripts) + remove_gulp_files() + + +def remove_celery_files(): + file_names = [ + os.path.join("config", "celery_app.py"), + os.path.join("{{ cookiecutter.project_slug }}", "users", "tasks.py"), + os.path.join("{{ cookiecutter.project_slug }}", "users", "tests", "test_tasks.py"), + ] + for file_name in file_names: + os.remove(file_name) + + +def remove_async_files(): + file_names = [ + os.path.join("config", "asgi.py"), + os.path.join("config", "websocket.py"), + ] + for file_name in file_names: + os.remove(file_name) def remove_dottravisyml_file(): os.remove(".travis.yml") -def append_to_project_gitignore(path): - gitignore_file_path = ".gitignore" - with open(gitignore_file_path, "a") as gitignore_file: - gitignore_file.write(path) - gitignore_file.write(os.linesep) +def remove_dotgitlabciyml_file(): + os.remove(".gitlab-ci.yml") -def generate_random_string( - length, using_digits=False, using_ascii_letters=False, using_punctuation=False -): +def remove_dotgithub_folder(): + shutil.rmtree(".github") + + +def generate_random_string(length, using_digits=False, using_ascii_letters=False, using_punctuation=False): """ Example: opting out for 50 symbol-long, [a-z][A-Z][0-9] string @@ -134,8 +265,8 @@ def set_flag(file_path, flag, value=None, formatted=None, *args, **kwargs): random_string = generate_random_string(*args, **kwargs) if random_string is None: print( - "We couldn't find a secure pseudo-random number generator on your system. " - "Please, make sure to manually {} later.".format(flag) + "We couldn't find a secure pseudo-random number generator on your " + "system. Please, make sure to manually {} later.".format(flag) ) random_string = flag if formatted is not None: @@ -183,11 +314,7 @@ def generate_postgres_user(debug=False): def set_postgres_user(file_path, value): - postgres_user = set_flag( - file_path, - "!!!SET POSTGRES_USER!!!", - value=value, - ) + postgres_user = set_flag(file_path, "!!!SET POSTGRES_USER!!!", value=value) return postgres_user @@ -204,11 +331,7 @@ def set_postgres_password(file_path, value=None): def set_celery_flower_user(file_path, value): - celery_flower_user = set_flag( - file_path, - "!!!SET CELERY_FLOWER_USER!!!", - value=value, - ) + celery_flower_user = set_flag(file_path, "!!!SET CELERY_FLOWER_USER!!!", value=value) return celery_flower_user @@ -224,17 +347,13 @@ def set_celery_flower_password(file_path, value=None): return celery_flower_password -def append_to_gitignore_file(s): +def append_to_gitignore_file(ignored_line): with open(".gitignore", "a") as gitignore_file: - gitignore_file.write(s) - gitignore_file.write(os.linesep) + gitignore_file.write(ignored_line) + gitignore_file.write("\n") -def set_flags_in_envs( - postgres_user, - celery_flower_user, - debug=False, -): +def set_flags_in_envs(postgres_user, celery_flower_user, debug=False): local_django_envs_path = os.path.join(".envs", ".local", ".django") production_django_envs_path = os.path.join(".envs", ".production", ".django") local_postgres_envs_path = os.path.join(".envs", ".local", ".postgres") @@ -262,6 +381,7 @@ def set_flags_in_settings_files(): def remove_envs_and_associated_files(): shutil.rmtree(".envs") os.remove("merge_production_dotenvs_in_dotenv.py") + shutil.rmtree("tests") def remove_celery_compose_dirs(): @@ -269,6 +389,26 @@ def remove_celery_compose_dirs(): shutil.rmtree(os.path.join("compose", "production", "django", "celery")) +def remove_node_dockerfile(): + shutil.rmtree(os.path.join("compose", "local", "node")) + + +def remove_aws_dockerfile(): + shutil.rmtree(os.path.join("compose", "production", "aws")) + + +def remove_drf_starter_files(): + os.remove(os.path.join("config", "api_router.py")) + shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "users", "api")) + os.remove(os.path.join("{{cookiecutter.project_slug}}", "users", "tests", "test_drf_urls.py")) + os.remove(os.path.join("{{cookiecutter.project_slug}}", "users", "tests", "test_drf_views.py")) + os.remove(os.path.join("{{cookiecutter.project_slug}}", "users", "tests", "test_swagger.py")) + + +def remove_storages_module(): + os.remove(os.path.join("{{cookiecutter.project_slug}}", "utils", "storages.py")) + + def main(): debug = "{{ cookiecutter.debug }}".lower() == "y" @@ -284,6 +424,9 @@ def main(): if "{{ cookiecutter.open_source_license}}" != "GPLv3": remove_gplv3_files() + if "{{ cookiecutter.username_type }}" == "username": + remove_custom_user_manager_files() + if "{{ cookiecutter.use_pycharm }}".lower() == "n": remove_pycharm_files() @@ -292,18 +435,18 @@ def main(): else: remove_docker_files() + if "{{ cookiecutter.use_docker }}".lower() == "y" and "{{ cookiecutter.cloud_provider}}" != "AWS": + remove_aws_dockerfile() + if "{{ cookiecutter.use_heroku }}".lower() == "n": remove_heroku_files() - if ( - "{{ cookiecutter.use_docker }}".lower() == "n" - and "{{ cookiecutter.use_heroku }}".lower() == "n" - ): + if "{{ cookiecutter.use_docker }}".lower() == "n" and "{{ cookiecutter.use_heroku }}".lower() == "n": if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y": print( INFO + ".env(s) are only utilized when Docker Compose and/or " - "Heroku support is enabled so keeping them does not " - "make sense given your current setup." + TERMINATOR + "Heroku support is enabled so keeping them does not " + "make sense given your current setup." + TERMINATOR ) remove_envs_and_associated_files() else: @@ -312,33 +455,47 @@ def main(): if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y": append_to_gitignore_file("!.envs/.local/") - if "{{ cookiecutter.js_task_runner}}".lower() == "none": + if "{{ cookiecutter.frontend_pipeline }}" in ["None", "Django Compressor"]: remove_gulp_files() + remove_webpack_files() + remove_sass_files() remove_packagejson_file() - if ( - "{{ cookiecutter.js_task_runner }}".lower() != "none" - and "{{ cookiecutter.use_docker }}".lower() == "y" - ): - print( - WARNING - + "Docker and {} JS task runner ".format( - "{{ cookiecutter.js_task_runner }}".lower().capitalize() - ) - + "working together not supported yet. " - "You can continue using the generated project like you " - "normally would, however you would need to add a JS " - "task runner service to your Docker Compose configuration " - "manually." + TERMINATOR + if "{{ cookiecutter.use_docker }}".lower() == "y": + remove_node_dockerfile() + else: + handle_js_runner( + "{{ cookiecutter.frontend_pipeline }}", + use_docker=("{{ cookiecutter.use_docker }}".lower() == "y"), + use_async=("{{ cookiecutter.use_async }}".lower() == "y"), ) + if "{{ cookiecutter.cloud_provider }}" == "None" and "{{ cookiecutter.use_docker }}".lower() == "n": + print( + WARNING + "You chose to not use any cloud providers nor Docker, " + "media files won't be served in production." + TERMINATOR + ) + remove_storages_module() + if "{{ cookiecutter.use_celery }}".lower() == "n": - remove_celery_app() + remove_celery_files() if "{{ cookiecutter.use_docker }}".lower() == "y": remove_celery_compose_dirs() - if "{{ cookiecutter.use_travisci }}".lower() == "n": + if "{{ cookiecutter.ci_tool }}" != "Travis": remove_dottravisyml_file() + if "{{ cookiecutter.ci_tool }}" != "Gitlab": + remove_dotgitlabciyml_file() + + if "{{ cookiecutter.ci_tool }}" != "Github": + remove_dotgithub_folder() + + if "{{ cookiecutter.use_drf }}".lower() == "n": + remove_drf_starter_files() + + if "{{ cookiecutter.use_async }}".lower() == "n": + remove_async_files() + print(SUCCESS + "Project initialized, keep up the good work!" + TERMINATOR) diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index b7f4dfbbb..33dc2e834 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -4,7 +4,8 @@ NOTE: as the whole Cookiecutter Django project initialization can potentially be run in Python 2.x environment. -TODO: ? restrict Cookiecutter Django project initialization to Python 3.x environments only +TODO: restrict Cookiecutter Django project initialization + to Python 3.x environments only """ from __future__ import print_function @@ -16,11 +17,19 @@ INFO = "\x1b[1;33m [INFO]: " HINT = "\x1b[3;33m" SUCCESS = "\x1b[1;32m [SUCCESS]: " +# The content of this string is evaluated by Jinja, and plays an important role. +# It updates the cookiecutter context to trim leading and trailing spaces +# from domain/email values +""" +{{ cookiecutter.update({ "domain_name": cookiecutter.domain_name | trim }) }} +{{ cookiecutter.update({ "email": cookiecutter.email | trim }) }} +""" + project_slug = "{{ cookiecutter.project_slug }}" if hasattr(project_slug, "isidentifier"): - assert project_slug.isidentifier(), "'{}' project slug is not a valid Python identifier.".format( - project_slug - ) + assert project_slug.isidentifier(), "'{}' project slug is not a valid Python identifier.".format(project_slug) + +assert project_slug == project_slug.lower(), "'{}' project slug should be all lowercase".format(project_slug) assert "\\" not in "{{ cookiecutter.author_name }}", "Don't include backslashes in author name." @@ -28,13 +37,12 @@ if "{{ cookiecutter.use_docker }}".lower() == "n": python_major_version = sys.version_info[0] if python_major_version == 2: print( - WARNING + "Cookiecutter Django does not support Python 2. " - "Stability is guaranteed with Python 3.6+ only, " - "are you sure you want to proceed (y/n)? " + TERMINATOR + WARNING + "You're running cookiecutter under Python 2, but the generated " + "project requires Python 3.11+. Do you want to proceed (y/n)? " + TERMINATOR ) yes_options, no_options = frozenset(["y"]), frozenset(["n"]) while True: - choice = raw_input().lower() + choice = raw_input().lower() # noqa: F821 if choice in yes_options: break @@ -45,12 +53,16 @@ if "{{ cookiecutter.use_docker }}".lower() == "n": print( HINT + "Please respond with {} or {}: ".format( - ", ".join( - ["'{}'".format(o) for o in yes_options if not o == ""] - ), - ", ".join( - ["'{}'".format(o) for o in no_options if not o == ""] - ), + ", ".join(["'{}'".format(o) for o in yes_options if not o == ""]), + ", ".join(["'{}'".format(o) for o in no_options if not o == ""]), ) + TERMINATOR ) + +if "{{ cookiecutter.use_whitenoise }}".lower() == "n" and "{{ cookiecutter.cloud_provider }}" == "None": + print("You should either use Whitenoise or select a " "Cloud Provider to serve static files") + sys.exit(1) + +if "{{ cookiecutter.mail_service }}" == "Amazon SES" and "{{ cookiecutter.cloud_provider }}" != "AWS": + print("You should either use AWS or select a different " "Mail Service for sending emails.") + sys.exit(1) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..2a9f00b29 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,50 @@ +# ==== pytest ==== +[tool.pytest.ini_options] +addopts = "-v --tb=short" +norecursedirs = [ + ".tox", + ".git", + "*/migrations/*", + "*/static/*", + "docs", + "venv", + "*/{{cookiecutter.project_slug}}/*", +] + + +# ==== black ==== +[tool.black] +line-length = 119 +target-version = ['py311'] + + +# ==== isort ==== +[tool.isort] +profile = "black" +line_length = 119 +known_first_party = [ + "tests", + "scripts", + "hooks", +] + + +# ==== djLint ==== +[tool.djlint] +blank_line_after_tag = "load,extends" +close_void_tags = true +format_css = true +format_js = true +# TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687 +ignore = "H006,H030,H031,T002,T028" +ignore_blocks = "raw" +include = "H017,H035" +indent = 2 +max_line_length = 119 +profile = "jinja" + +[tool.djlint.css] +indent_size = 2 + +[tool.djlint.js] +indent_size = 2 diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index c5b301991..000000000 --- a/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -python_paths = . -norecursedirs = .tox .git */migrations/* */static/* docs venv */{{cookiecutter.project_slug}}/* diff --git a/requirements.txt b/requirements.txt index 90870656e..d6d0ca754 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,28 @@ -cookiecutter==1.6.0 -sh==1.12.14 +cookiecutter==2.1.1 +sh==2.0.4; sys_platform != "win32" binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -flake8==3.6.0 +black==23.3.0 +isort==5.12.0 +flake8==6.0.0 +django-upgrade==1.14.0 +djlint==1.31.1 +pre-commit==3.3.3 # Testing # ------------------------------------------------------------------------------ -tox==3.6.1 -pytest==4.1.1 -pytest-cookies==0.3.0 +tox==4.6.3 +pytest==7.4.0 +pytest-xdist==3.3.1 +pytest-cookies==0.7.0 +pytest-instafail==0.5.0 +pyyaml==6.0 + +# Scripting +# ------------------------------------------------------------------------------ +PyGithub==1.59.0 +gitpython==3.1.31 +jinja2==3.1.2 +requests==2.31.0 diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/__init__.py b/scripts/__init__.py similarity index 100% rename from {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/taskapp/__init__.py rename to scripts/__init__.py diff --git a/scripts/create_django_issue.py b/scripts/create_django_issue.py new file mode 100644 index 000000000..d3b3c3792 --- /dev/null +++ b/scripts/create_django_issue.py @@ -0,0 +1,298 @@ +""" +Creates an issue that generates a table for dependency checking whether +all packages support the latest Django version. "Latest" does not include +patches, only comparing major and minor version numbers. + +This script handles when there are multiple Django versions that need +to keep up to date. +""" +from __future__ import annotations + +import os +import re +import sys +from collections.abc import Iterable +from pathlib import Path +from typing import TYPE_CHECKING, Any, NamedTuple + +import requests +from github import Github + +if TYPE_CHECKING: + from github.Issue import Issue + +CURRENT_FILE = Path(__file__) +ROOT = CURRENT_FILE.parents[1] +REQUIREMENTS_DIR = ROOT / "{{cookiecutter.project_slug}}" / "requirements" +GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", None) +GITHUB_REPO = os.getenv("GITHUB_REPOSITORY", None) + + +class DjVersion(NamedTuple): + """ + Wrapper to parse, compare and render Django versions. + + Only keeps track on (major, minor) versions, excluding patches and pre-releases. + """ + + major: int + minor: int + + def __str__(self) -> str: + """To render as string.""" + return f"{self.major}.{self.minor}" + + @classmethod + def parse(cls, version_str: str) -> DjVersion: + """Parse interesting values from the version string.""" + major, minor, *_ = version_str.split(".") + return cls(major=int(major), minor=int(minor)) + + @classmethod + def parse_to_tuple(cls, version_str: str): + version = cls.parse(version_str=version_str) + return version.major, version.minor + + +def get_package_info(package: str) -> dict: + """Get package metadata using PyPI API.""" + # "django" converts to "Django" on redirect + r = requests.get(f"https://pypi.org/pypi/{package}/json", allow_redirects=True) + if not r.ok: + print(f"Couldn't find package: {package}") + sys.exit(1) + return r.json() + + +def get_django_versions() -> Iterable[DjVersion]: + """List all django versions.""" + django_package_info: dict[str, Any] = get_package_info("django") + releases = django_package_info["releases"].keys() + for release_str in releases: + if release_str.replace(".", "").isdigit(): + # Exclude pre-releases with non-numeric characters in version + yield DjVersion.parse(release_str) + + +def get_name_and_version(requirements_line: str) -> tuple[str, ...]: + """Get the name a version of a package from a line in the requirement file.""" + full_name, version = requirements_line.split(" ", 1)[0].split("==") + name_without_extras = full_name.split("[", 1)[0] + return name_without_extras, version + + +def get_all_latest_django_versions( + django_max_version: tuple[DjVersion] = None, +) -> tuple[DjVersion, list[DjVersion]]: + """ + Grabs all Django versions that are worthy of a GitHub issue. + Depends on Django versions having higher major version or minor version. + """ + _django_max_version = (99, 99) + if django_max_version: + _django_max_version = django_max_version + + print("Fetching all Django versions from PyPI") + base_txt = REQUIREMENTS_DIR / "base.txt" + with base_txt.open() as f: + for line in f.readlines(): + if "django==" in line.lower(): + break + else: + print(f"django not found in {base_txt}") # Huh...? + sys.exit(1) + + # Begin parsing and verification + _, current_version_str = get_name_and_version(line) + # Get a tuple of (major, minor) - ignoring patch version + current_minor_version = DjVersion.parse(current_version_str) + newer_versions: set[DjVersion] = set() + for django_version in get_django_versions(): + if current_minor_version < django_version <= _django_max_version: + newer_versions.add(django_version) + + return current_minor_version, sorted(newer_versions, reverse=True) + + +_TABLE_HEADER = """ + +## {file}.txt + +| Name | Version in Master | {dj_version} Compatible Version | OK | +| ---- | :---------------: | :-----------------------------: | :-: | +""" +VITAL_BUT_UNKNOWN = [ + "django-environ", # not updated often +] + + +class GitHubManager: + def __init__(self, base_dj_version: DjVersion, needed_dj_versions: list[DjVersion]): + self.github = Github(GITHUB_TOKEN) + self.repo = self.github.get_repo(GITHUB_REPO) + + self.base_dj_version = base_dj_version + self.needed_dj_versions = needed_dj_versions + # (major+minor) Version and description + self.existing_issues: dict[DjVersion, Issue] = {} + + # Load all requirements from our requirements files and preload their + # package information like a cache: + self.requirements_files = ["base", "local", "production"] + # Format: + # requirement file name: {package name: (master_version, package_info)} + self.requirements: dict[str, dict[str, tuple[str, dict]]] = {x: {} for x in self.requirements_files} + + def setup(self) -> None: + self.load_requirements() + self.load_existing_issues() + + def load_requirements(self): + print("Reading requirements") + for requirements_file in self.requirements_files: + with (REQUIREMENTS_DIR / f"{requirements_file}.txt").open() as f: + for line in f.readlines(): + if ( + "==" in line + and not line.startswith("{%") + and not line.startswith(" #") + and not line.startswith("#") + and not line.startswith(" ") + ): + name, version = get_name_and_version(line) + self.requirements[requirements_file][name] = ( + version, + get_package_info(name), + ) + + def load_existing_issues(self): + """Closes the issue if the base Django version is greater than needed""" + print("Load existing issues from GitHub") + qualifiers = { + "repo": GITHUB_REPO, + "author": "app/github-actions", + "state": "open", + "is": "issue", + "in": "title", + } + issues = list(self.github.search_issues("[Django Update]", "created", "desc", **qualifiers)) + print(f"Found {len(issues)} issues matching search") + for issue in issues: + matches = re.match(r"\[Update Django] Django (\d+.\d+)$", issue.title) + if not matches: + continue + issue_version = DjVersion.parse(matches.group(1)) + if self.base_dj_version > issue_version: + issue.edit(state="closed") + print(f"Closed issue {issue.title} (ID: [{issue.id}]({issue.url}))") + else: + self.existing_issues[issue_version] = issue + + def get_compatibility(self, package_name: str, package_info: dict, needed_dj_version: DjVersion): + """ + Verify compatibility via setup.py classifiers. If Django is not in the + classifiers, then default compatibility is n/a and OK is ✅. + + If it's a package that's vital but known to not be updated often, we give it + a ❓. If a package has ❓ or 🕒, then we allow manual update. Automatic updates + only include ❌ and ✅. + """ + # If issue previously existed, find package and skip any gtg, manually + # updated packages, or known releases that will happen but haven't yet + if issue := self.existing_issues.get(needed_dj_version): + if index := issue.body.find(package_name): + name, _current, prev_compat, ok = (s.strip() for s in issue.body[index:].split("|", 4)[:4]) + if ok in ("✅", "❓", "🕒"): + return prev_compat, ok + + if package_name in VITAL_BUT_UNKNOWN: + return "", "❓" + + # Check classifiers if it includes Django + supported_dj_versions: list[DjVersion] = [] + for classifier in package_info["info"]["classifiers"]: + # Usually in the form of "Framework :: Django :: 3.2" + tokens = classifier.split(" ") + if len(tokens) >= 5 and tokens[2].lower() == "django": + version = DjVersion.parse(tokens[4]) + if len(version) == 2: + supported_dj_versions.append(version) + + if supported_dj_versions: + if any(v >= needed_dj_version for v in supported_dj_versions): + return package_info["info"]["version"], "✅" + else: + return "", "❌" + + # Django classifier DNE; assume it isn't a Django lib + # Great exceptions include pylint-django, where we need to do this manually... + return "n/a", "✅" + + HOME_PAGE_URL_KEYS = [ + "home_page", + "project_url", + "docs_url", + "package_url", + "release_url", + "bugtrack_url", + ] + + def _get_md_home_page_url(self, package_info: dict): + urls = [package_info["info"].get(url_key) for url_key in self.HOME_PAGE_URL_KEYS] + try: + return f"[{{}}]({next(item for item in urls if item)})" + except StopIteration: + return "{}" + + def generate_markdown(self, needed_dj_version: DjVersion): + requirements = f"{needed_dj_version} requirements tables\n\n" + for _file in self.requirements_files: + requirements += _TABLE_HEADER.format_map({"file": _file, "dj_version": needed_dj_version}) + for package_name, (version, info) in self.requirements[_file].items(): + compat_version, icon = self.get_compatibility(package_name, info, needed_dj_version) + requirements += ( + f"| {self._get_md_home_page_url(info).format(package_name)} " + f"| {version.strip()} " + f"| {compat_version.strip()} " + f"| {icon} " + f"|\n" + ) + + return requirements + + def create_or_edit_issue(self, needed_dj_version: DjVersion, description: str): + if issue := self.existing_issues.get(needed_dj_version): + print(f"Editing issue #{issue.number} for Django {needed_dj_version}") + issue.edit(body=description) + else: + print(f"Creating new issue for Django {needed_dj_version}") + issue = self.repo.create_issue(f"[Update Django] Django {needed_dj_version}", description) + issue.add_to_labels(f"django{needed_dj_version}") + + def generate(self): + for version in self.needed_dj_versions: + print(f"Handling GitHub issue for Django {version}") + md_content = self.generate_markdown(version) + print(f"Generated markdown:\n\n{md_content}") + self.create_or_edit_issue(version, md_content) + + +def main(django_max_version=None) -> None: + # Check if there are any djs + current_dj, latest_djs = get_all_latest_django_versions(django_max_version=django_max_version) + if not latest_djs: + sys.exit(0) + manager = GitHubManager(current_dj, latest_djs) + manager.setup() + manager.generate() + + +if __name__ == "__main__": + if GITHUB_REPO is None: + raise RuntimeError("No github repo, please set the environment variable GITHUB_REPOSITORY") + max_version = None + last_arg = sys.argv[-1] + if CURRENT_FILE.name not in last_arg: + max_version = DjVersion.parse_to_tuple(version_str=last_arg) + + main(django_max_version=max_version) diff --git a/scripts/update_changelog.py b/scripts/update_changelog.py new file mode 100644 index 000000000..7d43a0b57 --- /dev/null +++ b/scripts/update_changelog.py @@ -0,0 +1,160 @@ +import datetime as dt +import os +import re +from collections.abc import Iterable +from pathlib import Path + +import git +import github.PullRequest +import github.Repository +from github import Github +from jinja2 import Template + +CURRENT_FILE = Path(__file__) +ROOT = CURRENT_FILE.parents[1] +GITHUB_TOKEN = os.getenv("GITHUB_TOKEN") +GITHUB_REPO = os.getenv("GITHUB_REPOSITORY") +GIT_BRANCH = os.getenv("GITHUB_REF_NAME") + + +def main() -> None: + """ + Script entry point. + """ + # Generate changelog for PRs merged yesterday + merged_date = dt.date.today() - dt.timedelta(days=1) + repo = Github(login_or_token=GITHUB_TOKEN).get_repo(GITHUB_REPO) + merged_pulls = list(iter_pulls(repo, merged_date)) + print(f"Merged pull requests: {merged_pulls}") + if not merged_pulls: + print("Nothing was merged, existing.") + return + + # Group pull requests by type of change + grouped_pulls = group_pulls_by_change_type(merged_pulls) + + # Generate portion of markdown + release_changes_summary = generate_md(grouped_pulls) + print(f"Summary of changes: {release_changes_summary}") + + # Update CHANGELOG.md file + release = f"{merged_date:%Y.%m.%d}" + changelog_path = ROOT / "CHANGELOG.md" + write_changelog(changelog_path, release, release_changes_summary) + print(f"Wrote {changelog_path}") + + # Update version + setup_py_path = ROOT / "setup.py" + update_version(setup_py_path, release) + print(f"Updated version in {setup_py_path}") + + # Commit changes, create tag and push + update_git_repo([changelog_path, setup_py_path], release) + + # Create GitHub release + github_release = repo.create_git_release( + tag=release, + name=release, + message=release_changes_summary, + ) + print(f"Created release on GitHub {github_release}") + + +def iter_pulls( + repo: github.Repository.Repository, + merged_date: dt.date, +) -> Iterable[github.PullRequest.PullRequest]: + """Fetch merged pull requests at the date we're interested in.""" + recent_pulls = repo.get_pulls( + state="closed", + sort="updated", + direction="desc", + ).get_page(0) + for pull in recent_pulls: + if pull.merged and pull.merged_at.date() == merged_date: + yield pull + + +def group_pulls_by_change_type( + pull_requests_list: list[github.PullRequest.PullRequest], +) -> dict[str, list[github.PullRequest.PullRequest]]: + """Group pull request by change type.""" + grouped_pulls = { + "Changed": [], + "Fixed": [], + "Documentation": [], + "Updated": [], + } + for pull in pull_requests_list: + label_names = {label.name for label in pull.labels} + if "project infrastructure" in label_names: + # Don't mention it in the changelog + continue + if "update" in label_names: + group_name = "Updated" + elif "bug" in label_names: + group_name = "Fixed" + elif "docs" in label_names: + group_name = "Documentation" + else: + group_name = "Changed" + grouped_pulls[group_name].append(pull) + return grouped_pulls + + +def generate_md(grouped_pulls: dict[str, list[github.PullRequest.PullRequest]]) -> str: + """Generate markdown file from Jinja template.""" + changelog_template = ROOT / ".github" / "changelog-template.md" + template = Template(changelog_template.read_text(), autoescape=True) + return template.render(grouped_pulls=grouped_pulls) + + +def write_changelog(file_path: Path, release: str, content: str) -> None: + """Write Release details to the changelog file.""" + content = f"## {release}\n{content}" + old_content = file_path.read_text() + updated_content = old_content.replace( + "", + f"\n\n{content}", + ) + file_path.write_text(updated_content) + + +def update_version(file_path: Path, release: str) -> None: + """Update template version in setup.py.""" + old_content = file_path.read_text() + updated_content = re.sub( + r'\nversion = "\d+\.\d+\.\d+"\n', + f'\nversion = "{release}"\n', + old_content, + ) + file_path.write_text(updated_content) + + +def update_git_repo(paths: list[Path], release: str) -> None: + """Commit, tag changes in git repo and push to origin.""" + repo = git.Repo(ROOT) + for path in paths: + repo.git.add(path) + message = f"Release {release}" + + user = repo.git.config("--get", "user.name") + email = repo.git.config("--get", "user.email") + + repo.git.commit( + m=message, + author=f"{user} <{email}>", + ) + repo.git.tag("-a", release, m=message) + server = f"https://{GITHUB_TOKEN}@github.com/{GITHUB_REPO}.git" + print(f"Pushing changes to {GIT_BRANCH} branch of {GITHUB_REPO}") + repo.git.push(server, GIT_BRANCH) + repo.git.push("--tags", server, GIT_BRANCH) + + +if __name__ == "__main__": + if GITHUB_REPO is None: + raise RuntimeError("No github repo, please set the environment variable GITHUB_REPOSITORY") + if GIT_BRANCH is None: + raise RuntimeError("No git branch set, please set the GITHUB_REF_NAME environment variable") + main() diff --git a/scripts/update_contributors.py b/scripts/update_contributors.py new file mode 100644 index 000000000..09a7082c0 --- /dev/null +++ b/scripts/update_contributors.py @@ -0,0 +1,102 @@ +import json +import os +from pathlib import Path + +from github import Github +from github.NamedUser import NamedUser +from jinja2 import Template + +CURRENT_FILE = Path(__file__) +ROOT = CURRENT_FILE.parents[1] +BOT_LOGINS = ["pyup-bot"] +GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", None) +GITHUB_REPO = os.getenv("GITHUB_REPOSITORY", None) + + +def main() -> None: + """ + Script entry point. + + 1. Fetch recent contributors from the Github API + 2. Add missing ones to the JSON file + 3. Generate Markdown from JSON file + """ + recent_authors = set(iter_recent_authors()) + + # Add missing users to the JSON file + contrib_file = ContributorsJSONFile() + for author in recent_authors: + print(f"Checking if {author.login} should be added") + if author.login not in contrib_file: + contrib_file.add_contributor(author) + print(f"Added {author.login} to contributors") + contrib_file.save() + + # Generate MD file from JSON file + write_md_file(contrib_file.content) + + +def iter_recent_authors(): + """ + Fetch users who opened recently merged pull requests. + + Use Github API to fetch recent authors rather than + git CLI to work with Github usernames. + """ + repo = Github(login_or_token=GITHUB_TOKEN, per_page=5).get_repo(GITHUB_REPO) + recent_pulls = repo.get_pulls(state="closed", sort="updated", direction="desc").get_page(0) + for pull in recent_pulls: + if pull.merged and pull.user.type == "User" and pull.user.login not in BOT_LOGINS: + yield pull.user + + +class ContributorsJSONFile: + """Helper to interact with the JSON file.""" + + file_path = ROOT / ".github" / "contributors.json" + content = None + + def __init__(self) -> None: + """Read initial content.""" + self.content = json.loads(self.file_path.read_text()) + + def __contains__(self, github_login: str): + """Provide a nice API to do: `username in file`.""" + return any( + # Github usernames are case insensitive + github_login.lower() == contrib["github_login"].lower() + for contrib in self.content + ) + + def add_contributor(self, user: NamedUser): + """Append the contributor data we care about at the end.""" + contributor_data = { + "name": user.name or user.login, + "github_login": user.login, + "twitter_username": user.twitter_username or "", + } + self.content.append(contributor_data) + + def save(self): + """Write the file to disk with indentation.""" + text_content = json.dumps(self.content, indent=2, ensure_ascii=False) + self.file_path.write_text(text_content) + + +def write_md_file(contributors): + """Generate markdown file from Jinja template.""" + contributors_template = ROOT / ".github" / "CONTRIBUTORS-template.md" + template = Template(contributors_template.read_text(), autoescape=True) + core_contributors = [c for c in contributors if c.get("is_core", False)] + other_contributors = (c for c in contributors if not c.get("is_core", False)) + other_contributors = sorted(other_contributors, key=lambda c: c["name"].lower()) + content = template.render(core_contributors=core_contributors, other_contributors=other_contributors) + + file_path = ROOT / "CONTRIBUTORS.md" + file_path.write_text(content) + + +if __name__ == "__main__": + if GITHUB_REPO is None: + raise RuntimeError("No github repo, please set the environment variable GITHUB_REPOSITORY") + main() diff --git a/setup.py b/setup.py index 65bcd8fcf..660847550 100644 --- a/setup.py +++ b/setup.py @@ -1,21 +1,11 @@ #!/usr/bin/env python - -import os -import sys - try: from setuptools import setup except ImportError: from distutils.core import setup -# Our version ALWAYS matches the version of Django we support -# If Django has a new release, we branch, tag, then update this setting after the tag. -version = "2.0.2" - -if sys.argv[-1] == "tag": - os.system('git tag -a %s -m "version %s"' % (version, version)) - os.system("git push --tags") - sys.exit() +# We use calendar versioning +version = "2023.06.27" with open("README.rst") as readme_file: long_description = readme_file.read() @@ -23,24 +13,24 @@ with open("README.rst") as readme_file: setup( name="cookiecutter-django", version=version, - description="A Cookiecutter template for creating production-ready Django projects quickly.", + description=("A Cookiecutter template for creating production-ready " "Django projects quickly."), long_description=long_description, author="Daniel Roy Greenfeld", author_email="pydanny@gmail.com", - url="https://github.com/pydanny/cookiecutter-django", + url="https://github.com/cookiecutter/cookiecutter-django", packages=[], license="BSD", zip_safe=False, classifiers=[ "Development Status :: 4 - Beta", "Environment :: Console", - "Framework :: Django :: 2.0", + "Framework :: Django :: 4.2", "Intended Audience :: Developers", "Natural Language :: English", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development", ], diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_bare.sh b/tests/test_bare.sh new file mode 100755 index 000000000..5dc175ebd --- /dev/null +++ b/tests/test_bare.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# this is a very simple script that tests the docker configuration for cookiecutter-django +# it is meant to be run from the root directory of the repository, eg: +# sh tests/test_bare.sh + +set -o errexit +set -x + +# create a cache directory +mkdir -p .cache/bare +cd .cache/bare + +# create the project using the default settings in cookiecutter.json +cookiecutter ../../ --no-input --overwrite-if-exists use_docker=n "$@" +cd my_awesome_project + +# Install OS deps +sudo utility/install_os_dependencies.sh install + +# Install Python deps +pip install -r requirements/local.txt + +# run the project's tests +pytest + +# Make sure the check doesn't raise any warnings +python manage.py check --fail-level WARNING + +# Run npm build script if package.json is present +if [ -f "package.json" ] +then + npm install + npm run build +fi + +# Generate the HTML for the documentation +cd docs && make html diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index cf173576b..bb3ce479c 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -1,13 +1,32 @@ +import glob import os import re -import sh +import sys import pytest -from binaryornot.check import is_binary -PATTERN = "{{(\s?cookiecutter)[.](.*?)}}" +try: + import sh +except (ImportError, ModuleNotFoundError): + sh = None # sh doesn't support Windows +import yaml +from binaryornot.check import is_binary +from cookiecutter.exceptions import FailedHookException + +PATTERN = r"{{(\s?cookiecutter)[.](.*?)}}" RE_OBJ = re.compile(PATTERN) +if sys.platform.startswith("win"): + pytest.skip("sh doesn't support windows", allow_module_level=True) +elif sys.platform.startswith("darwin") and os.getenv("CI"): + pytest.skip("skipping slow macOS tests on CI", allow_module_level=True) + +# Run auto-fixable styles checks - skipped on CI by default. These can be fixed +# automatically by running pre-commit after generation however they are tedious +# to fix in the template, so we don't insist too much in fixing them. +AUTOFIXABLE_STYLES = os.getenv("AUTOFIXABLE_STYLES") == "1" +auto_fixable = pytest.mark.skipif(not AUTOFIXABLE_STYLES, reason="auto-fixable") + @pytest.fixture def context(): @@ -23,65 +42,367 @@ def context(): } -def build_files_list(root_dir): +SUPPORTED_COMBINATIONS = [ + {"username_type": "username"}, + {"username_type": "email"}, + {"open_source_license": "MIT"}, + {"open_source_license": "BSD"}, + {"open_source_license": "GPLv3"}, + {"open_source_license": "Apache Software License 2.0"}, + {"open_source_license": "Not open source"}, + {"windows": "y"}, + {"windows": "n"}, + {"use_pycharm": "y"}, + {"use_pycharm": "n"}, + {"use_docker": "y"}, + {"use_docker": "n"}, + {"postgresql_version": "14"}, + {"postgresql_version": "13"}, + {"postgresql_version": "12"}, + {"postgresql_version": "11"}, + {"postgresql_version": "10"}, + {"cloud_provider": "AWS", "use_whitenoise": "y"}, + {"cloud_provider": "AWS", "use_whitenoise": "n"}, + {"cloud_provider": "GCP", "use_whitenoise": "y"}, + {"cloud_provider": "GCP", "use_whitenoise": "n"}, + {"cloud_provider": "Azure", "use_whitenoise": "y"}, + {"cloud_provider": "Azure", "use_whitenoise": "n"}, + {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mailgun"}, + {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mailjet"}, + {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mandrill"}, + {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Postmark"}, + {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Sendgrid"}, + {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "SendinBlue"}, + {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "SparkPost"}, + {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Other SMTP"}, + # Note: cloud_provider=None AND use_whitenoise=n is not supported + {"cloud_provider": "AWS", "mail_service": "Mailgun"}, + {"cloud_provider": "AWS", "mail_service": "Amazon SES"}, + {"cloud_provider": "AWS", "mail_service": "Mailjet"}, + {"cloud_provider": "AWS", "mail_service": "Mandrill"}, + {"cloud_provider": "AWS", "mail_service": "Postmark"}, + {"cloud_provider": "AWS", "mail_service": "Sendgrid"}, + {"cloud_provider": "AWS", "mail_service": "SendinBlue"}, + {"cloud_provider": "AWS", "mail_service": "SparkPost"}, + {"cloud_provider": "AWS", "mail_service": "Other SMTP"}, + {"cloud_provider": "GCP", "mail_service": "Mailgun"}, + {"cloud_provider": "GCP", "mail_service": "Mailjet"}, + {"cloud_provider": "GCP", "mail_service": "Mandrill"}, + {"cloud_provider": "GCP", "mail_service": "Postmark"}, + {"cloud_provider": "GCP", "mail_service": "Sendgrid"}, + {"cloud_provider": "GCP", "mail_service": "SendinBlue"}, + {"cloud_provider": "GCP", "mail_service": "SparkPost"}, + {"cloud_provider": "GCP", "mail_service": "Other SMTP"}, + {"cloud_provider": "Azure", "mail_service": "Mailgun"}, + {"cloud_provider": "Azure", "mail_service": "Mailjet"}, + {"cloud_provider": "Azure", "mail_service": "Mandrill"}, + {"cloud_provider": "Azure", "mail_service": "Postmark"}, + {"cloud_provider": "Azure", "mail_service": "Sendgrid"}, + {"cloud_provider": "Azure", "mail_service": "SendinBlue"}, + {"cloud_provider": "Azure", "mail_service": "SparkPost"}, + {"cloud_provider": "Azure", "mail_service": "Other SMTP"}, + # Note: cloud_providers GCP, Azure, and None + # with mail_service Amazon SES is not supported + {"use_async": "y"}, + {"use_async": "n"}, + {"use_drf": "y"}, + {"use_drf": "n"}, + {"frontend_pipeline": "None"}, + {"frontend_pipeline": "Django Compressor"}, + {"frontend_pipeline": "Gulp"}, + {"frontend_pipeline": "Webpack"}, + {"use_celery": "y"}, + {"use_celery": "n"}, + {"use_mailhog": "y"}, + {"use_mailhog": "n"}, + {"use_sentry": "y"}, + {"use_sentry": "n"}, + {"use_whitenoise": "y"}, + {"use_whitenoise": "n"}, + {"use_heroku": "y"}, + {"use_heroku": "n"}, + {"ci_tool": "None"}, + {"ci_tool": "Travis"}, + {"ci_tool": "Gitlab"}, + {"ci_tool": "Github"}, + {"keep_local_envs_in_vcs": "y"}, + {"keep_local_envs_in_vcs": "n"}, + {"debug": "y"}, + {"debug": "n"}, +] + +UNSUPPORTED_COMBINATIONS = [ + {"cloud_provider": "None", "use_whitenoise": "n"}, + {"cloud_provider": "GCP", "mail_service": "Amazon SES"}, + {"cloud_provider": "Azure", "mail_service": "Amazon SES"}, + {"cloud_provider": "None", "mail_service": "Amazon SES"}, +] + + +def _fixture_id(ctx): + """Helper to get a user-friendly test name from the parametrized context.""" + return "-".join(f"{key}:{value}" for key, value in ctx.items()) + + +def build_files_list(base_dir): """Build a list containing absolute paths to the generated files.""" - return [ - os.path.join(dirpath, file_path) - for dirpath, subdirs, files in os.walk(root_dir) - for file_path in files - ] + return [os.path.join(dirpath, file_path) for dirpath, subdirs, files in os.walk(base_dir) for file_path in files] def check_paths(paths): - """Method to check all paths have correct substitutions, - used by other tests cases - """ + """Method to check all paths have correct substitutions.""" # Assert that no match is found in any of the files for path in paths: if is_binary(path): continue - for line in open(path, "r"): + for line in open(path): match = RE_OBJ.search(line) - msg = "cookiecutter variable not replaced in {}" - assert match is None, msg.format(path) + assert match is None, f"cookiecutter variable not replaced in {path}" -def test_default_configuration(cookies, context): - result = cookies.bake(extra_context=context) +@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) +def test_project_generation(cookies, context, context_override): + """Test that project is generated and fully rendered.""" + + result = cookies.bake(extra_context={**context, **context_override}) assert result.exit_code == 0 assert result.exception is None - assert result.project.basename == context["project_slug"] - assert result.project.isdir() + assert result.project_path.name == context["project_slug"] + assert result.project_path.is_dir() - paths = build_files_list(str(result.project)) + paths = build_files_list(str(result.project_path)) assert paths check_paths(paths) -@pytest.fixture(params=["use_mailhog", "use_celery", "windows"]) -def feature_context(request, context): - context.update({request.param: "y"}) - return context - - -def test_enabled_features(cookies, feature_context): - result = cookies.bake(extra_context=feature_context) - assert result.exit_code == 0 - assert result.exception is None - assert result.project.basename == feature_context["project_slug"] - assert result.project.isdir() - - paths = build_files_list(str(result.project)) - assert paths - check_paths(paths) - - -def test_flake8_compliance(cookies): - """generated project should pass flake8""" - result = cookies.bake() +@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) +def test_flake8_passes(cookies, context_override): + """Generated project should pass flake8.""" + result = cookies.bake(extra_context=context_override) try: - sh.flake8(str(result.project)) + sh.flake8(_cwd=str(result.project_path)) except sh.ErrorReturnCode as e: - pytest.fail(e) + pytest.fail(e.stdout.decode()) + + +@auto_fixable +@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) +def test_black_passes(cookies, context_override): + """Check whether generated project passes black style.""" + result = cookies.bake(extra_context=context_override) + + try: + sh.black( + "--check", + "--diff", + "--exclude", + "migrations", + ".", + _cwd=str(result.project_path), + ) + except sh.ErrorReturnCode as e: + pytest.fail(e.stdout.decode()) + + +@auto_fixable +@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) +def test_isort_passes(cookies, context_override): + """Check whether generated project passes isort style.""" + result = cookies.bake(extra_context=context_override) + + try: + sh.isort(_cwd=str(result.project_path)) + except sh.ErrorReturnCode as e: + pytest.fail(e.stdout.decode()) + + +@auto_fixable +@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) +def test_django_upgrade_passes(cookies, context_override): + """Check whether generated project passes django-upgrade.""" + result = cookies.bake(extra_context=context_override) + + python_files = [ + file_path.removeprefix(f"{result.project_path}/") + for file_path in glob.glob(str(result.project_path / "**" / "*.py"), recursive=True) + ] + try: + sh.django_upgrade( + "--target-version", + "4.2", + *python_files, + _cwd=str(result.project_path), + ) + except sh.ErrorReturnCode as e: + pytest.fail(e.stdout.decode()) + + +@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) +def test_djlint_lint_passes(cookies, context_override): + """Check whether generated project passes djLint --lint.""" + result = cookies.bake(extra_context=context_override) + + autofixable_rules = "H014,T001" + # TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687 + ignored_rules = "H006,H030,H031,T002" + try: + sh.djlint("--lint", "--ignore", f"{autofixable_rules},{ignored_rules}", ".", _cwd=str(result.project_path)) + except sh.ErrorReturnCode as e: + pytest.fail(e.stdout.decode()) + + +@auto_fixable +@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) +def test_djlint_check_passes(cookies, context_override): + """Check whether generated project passes djLint --check.""" + result = cookies.bake(extra_context=context_override) + + try: + sh.djlint("--check", ".", _cwd=str(result.project_path)) + except sh.ErrorReturnCode as e: + pytest.fail(e.stdout.decode()) + + +@pytest.mark.parametrize( + ["use_docker", "expected_test_script"], + [ + ("n", "pytest"), + ("y", "docker-compose -f local.yml run django pytest"), + ], +) +def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_script): + context.update({"ci_tool": "Travis", "use_docker": use_docker}) + result = cookies.bake(extra_context=context) + + assert result.exit_code == 0 + assert result.exception is None + assert result.project_path.name == context["project_slug"] + assert result.project_path.is_dir() + + with open(f"{result.project_path}/.travis.yml") as travis_yml: + try: + yml = yaml.safe_load(travis_yml)["jobs"]["include"] + assert yml[0]["script"] == ["flake8"] + assert yml[1]["script"] == [expected_test_script] + except yaml.YAMLError as e: + pytest.fail(str(e)) + + +@pytest.mark.parametrize( + ["use_docker", "expected_test_script"], + [ + ("n", "pytest"), + ("y", "docker-compose -f local.yml run django pytest"), + ], +) +def test_gitlab_invokes_precommit_and_pytest(cookies, context, use_docker, expected_test_script): + context.update({"ci_tool": "Gitlab", "use_docker": use_docker}) + result = cookies.bake(extra_context=context) + + assert result.exit_code == 0 + assert result.exception is None + assert result.project_path.name == context["project_slug"] + assert result.project_path.is_dir() + + with open(f"{result.project_path}/.gitlab-ci.yml") as gitlab_yml: + try: + gitlab_config = yaml.safe_load(gitlab_yml) + assert gitlab_config["precommit"]["script"] == [ + "pre-commit run --show-diff-on-failure --color=always --all-files" + ] + assert gitlab_config["pytest"]["script"] == [expected_test_script] + except yaml.YAMLError as e: + pytest.fail(e) + + +@pytest.mark.parametrize( + ["use_docker", "expected_test_script"], + [ + ("n", "pytest"), + ("y", "docker-compose -f local.yml run django pytest"), + ], +) +def test_github_invokes_linter_and_pytest(cookies, context, use_docker, expected_test_script): + context.update({"ci_tool": "Github", "use_docker": use_docker}) + result = cookies.bake(extra_context=context) + + assert result.exit_code == 0 + assert result.exception is None + assert result.project_path.name == context["project_slug"] + assert result.project_path.is_dir() + + with open(f"{result.project_path}/.github/workflows/ci.yml") as github_yml: + try: + github_config = yaml.safe_load(github_yml) + linter_present = False + for action_step in github_config["jobs"]["linter"]["steps"]: + if action_step.get("uses", "NA").startswith("pre-commit"): + linter_present = True + assert linter_present + + expected_test_script_present = False + for action_step in github_config["jobs"]["pytest"]["steps"]: + if action_step.get("run") == expected_test_script: + expected_test_script_present = True + assert expected_test_script_present + except yaml.YAMLError as e: + pytest.fail(e) + + +@pytest.mark.parametrize("slug", ["project slug", "Project_Slug"]) +def test_invalid_slug(cookies, context, slug): + """Invalid slug should fail pre-generation hook.""" + context.update({"project_slug": slug}) + + result = cookies.bake(extra_context=context) + + assert result.exit_code != 0 + assert isinstance(result.exception, FailedHookException) + + +@pytest.mark.parametrize("invalid_context", UNSUPPORTED_COMBINATIONS) +def test_error_if_incompatible(cookies, context, invalid_context): + """It should not generate project an incompatible combination is selected.""" + context.update(invalid_context) + result = cookies.bake(extra_context=context) + + assert result.exit_code != 0 + assert isinstance(result.exception, FailedHookException) + + +@pytest.mark.parametrize( + ["use_pycharm", "pycharm_docs_exist"], + [ + ("n", False), + ("y", True), + ], +) +def test_pycharm_docs_removed(cookies, context, use_pycharm, pycharm_docs_exist): + context.update({"use_pycharm": use_pycharm}) + result = cookies.bake(extra_context=context) + + with open(f"{result.project_path}/docs/index.rst") as f: + has_pycharm_docs = "pycharm/configuration" in f.read() + assert has_pycharm_docs is pycharm_docs_exist + + +def test_trim_domain_email(cookies, context): + """Check that leading and trailing spaces are trimmed in domain and email.""" + context.update( + { + "use_docker": "y", + "domain_name": " example.com ", + "email": " me@example.com ", + } + ) + result = cookies.bake(extra_context=context) + + assert result.exit_code == 0 + + prod_django_env = result.project_path / ".envs" / ".production" / ".django" + assert "DJANGO_ALLOWED_HOSTS=.example.com" in prod_django_env.read_text() + + base_settings = result.project_path / "config" / "settings" / "base.py" + assert '"me@example.com"' in base_settings.read_text() diff --git a/tests/test_docker.sh b/tests/test_docker.sh index eddfe98c6..5c60d20d3 100755 --- a/tests/test_docker.sh +++ b/tests/test_docker.sh @@ -3,17 +3,20 @@ # it is meant to be run from the root directory of the repository, eg: # sh tests/test_docker.sh -# install test requirements -pip install -r requirements.txt +set -o errexit +set -x # create a cache directory mkdir -p .cache/docker cd .cache/docker # create the project using the default settings in cookiecutter.json -cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y +cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y "$@" cd my_awesome_project +# make sure all images build +docker-compose -f local.yml build + # run the project's type checks docker-compose -f local.yml run django mypy my_awesome_project @@ -24,4 +27,16 @@ docker-compose -f local.yml run django pytest docker-compose -f local.yml run django python manage.py makemigrations --dry-run --check || { echo "ERROR: there were changes in the models, but migration listed above have not been created and are not saved in version control"; exit 1; } # Test support for translations -docker-compose -f local.yml run django python manage.py makemessages +docker-compose -f local.yml run django python manage.py makemessages --all + +# Make sure the check doesn't raise any warnings +docker-compose -f local.yml run django python manage.py check --fail-level WARNING + +# Generate the HTML for the documentation +docker-compose -f local.yml run docs make html + +# Run npm build script if package.json is present +if [ -f "package.json" ] +then + docker-compose -f local.yml run node npm run build +fi diff --git a/tests/test_hooks.py b/tests/test_hooks.py new file mode 100644 index 000000000..6afdc400b --- /dev/null +++ b/tests/test_hooks.py @@ -0,0 +1,26 @@ +"""Unit tests for the hooks""" +import os +from pathlib import Path + +import pytest + +from hooks.post_gen_project import append_to_gitignore_file + + +@pytest.fixture() +def working_directory(tmp_path): + prev_cwd = Path.cwd() + os.chdir(tmp_path) + try: + yield tmp_path + finally: + os.chdir(prev_cwd) + + +def test_append_to_gitignore_file(working_directory): + gitignore_file = working_directory / ".gitignore" + gitignore_file.write_text("node_modules/\n") + append_to_gitignore_file(".envs/*") + linesep = os.linesep.encode() + assert gitignore_file.read_bytes() == b"node_modules/" + linesep + b".envs/*" + linesep + assert gitignore_file.read_text() == "node_modules/\n.envs/*\n" diff --git a/tox.ini b/tox.ini index 040c8a41c..903d5a53b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,12 @@ [tox] skipsdist = true -envlist = py36 +envlist = py311,black-template [testenv] deps = -rrequirements.txt -commands = pytest {posargs:./tests} +passenv = AUTOFIXABLE_STYLES +commands = pytest -n auto {posargs:./tests} + +[testenv:black-template] +deps = black +commands = black --check hooks tests setup.py docs scripts diff --git a/{{cookiecutter.project_slug}}/.coveragerc b/{{cookiecutter.project_slug}}/.coveragerc deleted file mode 100644 index 283a4b89c..000000000 --- a/{{cookiecutter.project_slug}}/.coveragerc +++ /dev/null @@ -1,5 +0,0 @@ -[run] -include = {{cookiecutter.project_slug}}/* -omit = *migrations*, *tests* -plugins = - django_coverage_plugin diff --git a/{{cookiecutter.project_slug}}/.dockerignore b/{{cookiecutter.project_slug}}/.dockerignore index e63c0c184..7369480e3 100644 --- a/{{cookiecutter.project_slug}}/.dockerignore +++ b/{{cookiecutter.project_slug}}/.dockerignore @@ -1,4 +1,11 @@ -.* -!.coveragerc -!.env -!.pylintrc +.editorconfig +.gitattributes +.github +.gitignore +.gitlab-ci.yml +.idea +.pre-commit-config.yaml +.readthedocs.yml +.travis.yml +venv +.git diff --git a/{{cookiecutter.project_slug}}/.editorconfig b/{{cookiecutter.project_slug}}/.editorconfig index b19266bf3..c0ce34260 100644 --- a/{{cookiecutter.project_slug}}/.editorconfig +++ b/{{cookiecutter.project_slug}}/.editorconfig @@ -12,13 +12,7 @@ trim_trailing_whitespace = true indent_style = space indent_size = 4 -[*.py] -line_length=120 -known_first_party={{ cookiecutter.project_slug }} -multi_line_output=3 -default_section=THIRDPARTY - -[*.{html,css,scss,json,yml}] +[*.{html,css,scss,json,yml,xml}] indent_style = space indent_size = 2 @@ -28,6 +22,6 @@ trim_trailing_whitespace = false [Makefile] indent_style = tab -[nginx.conf] +[default.conf] indent_style = space indent_size = 2 diff --git a/{{cookiecutter.project_slug}}/.envs/.local/.django b/{{cookiecutter.project_slug}}/.envs/.local/.django index 2ed5fbf3d..ef581a1c0 100644 --- a/{{cookiecutter.project_slug}}/.envs/.local/.django +++ b/{{cookiecutter.project_slug}}/.envs/.local/.django @@ -3,14 +3,15 @@ USE_DOCKER=yes IPYTHONDIR=/app/.ipython +{%- if cookiecutter.use_celery == 'y' %} # Redis # ------------------------------------------------------------------------------ REDIS_URL=redis://redis:6379/0 -{% if cookiecutter.use_celery == 'y' %} + # Celery # ------------------------------------------------------------------------------ # Flower CELERY_FLOWER_USER=!!!SET CELERY_FLOWER_USER!!! CELERY_FLOWER_PASSWORD=!!!SET CELERY_FLOWER_PASSWORD!!! -{% endif %} +{%- endif %} diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.caddy b/{{cookiecutter.project_slug}}/.envs/.production/.caddy deleted file mode 100644 index 83d7fc7af..000000000 --- a/{{cookiecutter.project_slug}}/.envs/.production/.caddy +++ /dev/null @@ -1,3 +0,0 @@ -# Caddy -# ------------------------------------------------------------------------------ -DOMAIN_NAME={{ cookiecutter.domain_name }} diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.django b/{{cookiecutter.project_slug}}/.envs/.production/.django index 4175f8944..ad652c9ad 100644 --- a/{{cookiecutter.project_slug}}/.envs/.production/.django +++ b/{{cookiecutter.project_slug}}/.envs/.production/.django @@ -13,24 +13,48 @@ DJANGO_SECURE_SSL_REDIRECT=False # Email # ------------------------------------------------------------------------------ -MAILGUN_API_KEY= DJANGO_SERVER_EMAIL= +{% if cookiecutter.mail_service == 'Mailgun' %} +MAILGUN_API_KEY= MAILGUN_DOMAIN= - +{% elif cookiecutter.mail_service == 'Mailjet' %} +MAILJET_API_KEY= +MAILJET_SECRET_KEY= +{% elif cookiecutter.mail_service == 'Mandrill' %} +MANDRILL_API_KEY= +{% elif cookiecutter.mail_service == 'Postmark' %} +POSTMARK_SERVER_TOKEN= +{% elif cookiecutter.mail_service == 'Sendgrid' %} +SENDGRID_API_KEY= +SENDGRID_GENERATE_MESSAGE_ID=True +SENDGRID_MERGE_FIELD_FORMAT=None +{% elif cookiecutter.mail_service == 'SendinBlue' %} +SENDINBLUE_API_KEY= +{% elif cookiecutter.mail_service == 'SparkPost' %} +SPARKPOST_API_KEY= +{% endif %} +{% if cookiecutter.cloud_provider == 'AWS' %} # AWS # ------------------------------------------------------------------------------ DJANGO_AWS_ACCESS_KEY_ID= DJANGO_AWS_SECRET_ACCESS_KEY= DJANGO_AWS_STORAGE_BUCKET_NAME= - +{% elif cookiecutter.cloud_provider == 'GCP' %} +# GCP +# ------------------------------------------------------------------------------ +GOOGLE_APPLICATION_CREDENTIALS= +DJANGO_GCP_STORAGE_BUCKET_NAME= +{% elif cookiecutter.cloud_provider == 'Azure' %} +# Azure +# ------------------------------------------------------------------------------ +DJANGO_AZURE_ACCOUNT_KEY= +DJANGO_AZURE_ACCOUNT_NAME= +DJANGO_AZURE_CONTAINER_NAME= +{% endif %} # django-allauth # ------------------------------------------------------------------------------ DJANGO_ACCOUNT_ALLOW_REGISTRATION=True -{% if cookiecutter.use_compressor == 'y' %} -# django-compressor -# ------------------------------------------------------------------------------ -COMPRESS_ENABLED= -{% endif %} + # Gunicorn # ------------------------------------------------------------------------------ WEB_CONCURRENCY=4 diff --git a/{{cookiecutter.project_slug}}/.github/dependabot.yml b/{{cookiecutter.project_slug}}/.github/dependabot.yml new file mode 100644 index 000000000..be52c68d5 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.github/dependabot.yml @@ -0,0 +1,107 @@ +# Config for Dependabot updates. See Documentation here: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + # Update GitHub actions in workflows + - package-ecosystem: 'github-actions' + directory: '/' + # Every weekday + schedule: + interval: 'daily' + +{%- if cookiecutter.use_docker == 'y' %} + + # Enable version updates for Docker + # We need to specify each Dockerfile in a separate entry because Dependabot doesn't + # support wildcards or recursively checking subdirectories. Check this issue for updates: + # https://github.com/dependabot/dependabot-core/issues/2178 + - package-ecosystem: 'docker' + # Look for a `Dockerfile` in the `compose/local/django` directory + directory: 'compose/local/django/' + # Every weekday + schedule: + interval: 'daily' + # Ignore minor version updates (3.10 -> 3.11) but update patch versions + ignore: + - dependency-name: '*' + update-types: + - 'version-update:semver-major' + - 'version-update:semver-minor' + + - package-ecosystem: 'docker' + # Look for a `Dockerfile` in the `compose/local/docs` directory + directory: 'compose/local/docs/' + # Every weekday + schedule: + interval: 'daily' + # Ignore minor version updates (3.10 -> 3.11) but update patch versions + ignore: + - dependency-name: '*' + update-types: + - 'version-update:semver-major' + - 'version-update:semver-minor' + + - package-ecosystem: 'docker' + # Look for a `Dockerfile` in the `compose/local/node` directory + directory: 'compose/local/node/' + # Every weekday + schedule: + interval: 'daily' + + - package-ecosystem: 'docker' + # Look for a `Dockerfile` in the `compose/production/aws` directory + directory: 'compose/production/aws/' + # Every weekday + schedule: + interval: 'daily' + + - package-ecosystem: 'docker' + # Look for a `Dockerfile` in the `compose/production/django` directory + directory: 'compose/production/django/' + # Every weekday + schedule: + interval: 'daily' + # Ignore minor version updates (3.10 -> 3.11) but update patch versions + ignore: + - dependency-name: '*' + update-types: + - 'version-update:semver-major' + - 'version-update:semver-minor' + + - package-ecosystem: 'docker' + # Look for a `Dockerfile` in the `compose/production/postgres` directory + directory: 'compose/production/postgres/' + # Every weekday + schedule: + interval: 'daily' + + - package-ecosystem: 'docker' + # Look for a `Dockerfile` in the `compose/production/traefik` directory + directory: 'compose/production/traefik/' + # Every weekday + schedule: + interval: 'daily' + +{%- endif %} + + # Enable version updates for Python/Pip - Production + - package-ecosystem: 'pip' + # Look for a `requirements.txt` in the `root` directory + # also 'setup.cfg', 'runtime.txt' and 'requirements/*.txt' + directory: '/' + # Every weekday + schedule: + interval: 'daily' + +{%- if cookiecutter.frontend_pipeline == 'Gulp' %} + + # Enable version updates for javascript/npm + - package-ecosystem: 'npm' + # Look for a `packages.json` in the `root` directory + directory: '/' + # Every weekday + schedule: + interval: 'daily' + +{%- endif %} diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml new file mode 100644 index 000000000..ac231ee72 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -0,0 +1,100 @@ +name: CI + +# Enable Buildkit and let compose use it to speed up image building +env: + DOCKER_BUILDKIT: 1 + COMPOSE_DOCKER_CLI_BUILD: 1 + +on: + pull_request: + branches: ['master', 'main'] + paths-ignore: ['docs/**'] + + push: + branches: ['master', 'main'] + paths-ignore: ['docs/**'] + +concurrency: + group: {% raw %}${{ github.head_ref || github.run_id }}{% endraw %} + cancel-in-progress: true + +jobs: + linter: + runs-on: ubuntu-latest + steps: + - name: Checkout Code Repository + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + {%- if cookiecutter.open_source_license != 'Not open source' %} + # Consider using pre-commit.ci for open source project + {%- endif %} + - name: Run pre-commit + uses: pre-commit/action@v3.0.0 + + # With no caching at all the entire ci process takes 4m 30s to complete! + pytest: + runs-on: ubuntu-latest + {%- if cookiecutter.use_docker == 'n' %} + + services: + {%- if cookiecutter.use_celery == 'y' %} + redis: + image: redis:6 + ports: + - 6379:6379 + {%- endif %} + postgres: + image: postgres:12 + ports: + - 5432:5432 + env: + POSTGRES_PASSWORD: postgres + + env: + {%- if cookiecutter.use_celery == 'y' %} + CELERY_BROKER_URL: 'redis://localhost:6379/0' + {%- endif %} + # postgres://user:password@host:port/database + DATABASE_URL: 'postgres://postgres:postgres@localhost:5432/postgres' + {%- endif %} + + steps: + - name: Checkout Code Repository + uses: actions/checkout@v3 + {%- if cookiecutter.use_docker == 'y' %} + + - name: Build the Stack + run: docker-compose -f local.yml build + + - name: Run DB Migrations + run: docker-compose -f local.yml run --rm django python manage.py migrate + + - name: Run Django Tests + run: docker-compose -f local.yml run django pytest + + - name: Tear down the Stack + run: docker-compose -f local.yml down + {%- else %} + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + cache: pip + cache-dependency-path: | + requirements/base.txt + requirements/local.txt + + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements/local.txt + + - name: Test with pytest + run: pytest + {%- endif %} diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore index 1874e9d92..19bb2bc07 100644 --- a/{{cookiecutter.project_slug}}/.gitignore +++ b/{{cookiecutter.project_slug}}/.gitignore @@ -159,6 +159,10 @@ typings/ !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ {% if cookiecutter.use_pycharm == 'y' -%} @@ -321,29 +325,30 @@ Session.vim # Auto-generated tag files tags -{% if cookiecutter.use_docker == 'n' %} -### VirtualEnv template -# Virtualenv -# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ -[Bb]in -[Ii]nclude -[Ll]ib -[Ll]ib64 -[Ss]cripts -pyvenv.cfg -pip-selfcheck.json -.env -{% endif %} +# Redis dump file +dump.rdb ### Project template -{% if cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'n' %} +{%- if cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'n' %} MailHog {%- endif %} {{ cookiecutter.project_slug }}/media/ .pytest_cache/ -{% if cookiecutter.use_docker == 'y' %} +{%- if cookiecutter.use_docker == 'y' %} .ipython/ {%- endif %} + +{%- if cookiecutter.frontend_pipeline == 'Gulp' %} +project.css +project.min.css +vendors.js +*.min.js +*.min.js.map +{%- endif %} +{%- if cookiecutter.frontend_pipeline == 'Webpack' %} +{{ cookiecutter.project_slug }}/static/webpack_bundles/ +webpack-stats.json +{%- endif %} diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml new file mode 100644 index 000000000..a312a41ae --- /dev/null +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -0,0 +1,54 @@ +stages: + - lint + - test + +variables: + POSTGRES_USER: '{{ cookiecutter.project_slug }}' + POSTGRES_PASSWORD: '' + POSTGRES_DB: 'test_{{ cookiecutter.project_slug }}' + POSTGRES_HOST_AUTH_METHOD: trust + {%- if cookiecutter.use_celery == 'y' %} + CELERY_BROKER_URL: 'redis://redis:6379/0' + {%- endif %} + +precommit: + stage: lint + image: python:3.11 + variables: + PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit + cache: + paths: + - ${PRE_COMMIT_HOME} + before_script: + - pip install -q pre-commit + script: + - pre-commit run --show-diff-on-failure --color=always --all-files + +pytest: + stage: test + {%- if cookiecutter.use_docker == 'y' %} + image: docker/compose:1.29.2 + tags: + - docker + services: + - docker:dind + before_script: + - docker-compose -f local.yml build + # Ensure celerybeat does not crash due to non-existent tables + - docker-compose -f local.yml run --rm django python manage.py migrate + - docker-compose -f local.yml up -d + script: + - docker-compose -f local.yml run django pytest + {%- else %} + image: python:3.11 + tags: + - python + services: + - postgres:{{ cookiecutter.postgresql_version }} + variables: + DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB + before_script: + - pip install -r requirements/local.txt + script: + - pytest + {%- endif %} diff --git a/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_django.xml b/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_django.xml new file mode 100644 index 000000000..e84c5ffdd --- /dev/null +++ b/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_django.xml @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_docs.xml b/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_docs.xml new file mode 100644 index 000000000..0f77b28df --- /dev/null +++ b/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_docs.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/{{cookiecutter.project_slug}}/.idea/workspace.xml b/{{cookiecutter.project_slug}}/.idea/workspace.xml new file mode 100644 index 000000000..deb28ba1b --- /dev/null +++ b/{{cookiecutter.project_slug}}/.idea/workspace.xml @@ -0,0 +1,19 @@ + + + {%- if cookiecutter.use_docker == 'n' %} + + + {%- elif cookiecutter.use_celery == 'y' %} + + + {%- else %} + + + {%- endif %} + diff --git a/{{cookiecutter.project_slug}}/.idea/{{cookiecutter.project_slug}}.iml b/{{cookiecutter.project_slug}}/.idea/{{cookiecutter.project_slug}}.iml index 8ff6e3883..fe1aeae52 100644 --- a/{{cookiecutter.project_slug}}/.idea/{{cookiecutter.project_slug}}.iml +++ b/{{cookiecutter.project_slug}}/.idea/{{cookiecutter.project_slug}}.iml @@ -5,32 +5,32 @@ - {% if cookiecutter.js_task_runner != 'None' %} - + {% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %} + - {% else %} - + {% else %} + {% endif %} - - - -