diff --git a/.github/CONTRIBUTORS-template.md b/.github/CONTRIBUTORS-template.md new file mode 100644 index 000000000..d8ba28c63 --- /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 index 5a5aefc78..ced9c732b 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,7 +1,7 @@ # These are supported funding model platforms -github: pydanny -patreon: roygreenfeld +github: [pydanny, browniebroke] +patreon: feldroy open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 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..757b5990f 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -1,21 +1,32 @@ --- name: Bug Report about: Report a bug +labels: bug --- ## What happened? - - - ## What should've happened instead? +## Additional details + - -## Steps to reproduce - -[//]: # (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) +* Host system configuration: + * Version of cookiecutter CLI (get it with `cookiecutter --version`): + * OS: + * Python version: + * Docker versions (if using Docker): + * ... +* Options selected and/or [replay file](https://cookiecutter.readthedocs.io/en/latest/advanced/replay.html): + ``` + ``` + +Logs: +
+
+$ cookiecutter https://github.com/pydanny/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..7ebc06476 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/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. * 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. + +* Bruno Alla, Core Developer ([GitHub](https://github.com/sponsors/browniebroke)). diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 0c0f3d891..9d609eb98 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 consider asking your question on StackOverflow or Slack +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, post a question on [StackOverflow](https://stackoverflow.com/questions/tagged/cookiecutter-django) tagged with `cookiecutter-django`, you might get more visibility there than on our issue tracker. + +Finally, feel free to join [Slack](https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U) and ask around. 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..5559e62ff 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,27 +1,18 @@ -[//]: # (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/test_cookiecutter_generation.py` is 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..49550ba12 --- /dev/null +++ b/.github/changelog-template.md @@ -0,0 +1,9 @@ +## [{{merge_date.strftime('%Y-%m-%d')}}] +{%- 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.url }})) +{%- endfor -%} +{% endif -%} +{% endfor -%} diff --git a/.github/contributors.json b/.github/contributors.json new file mode 100644 index 000000000..25a33ed51 --- /dev/null +++ b/.github/contributors.json @@ -0,0 +1,1056 @@ +[ + { + "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": "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": "Jelmer Draaijer", + "github_login": "foarsitter", + "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": "" + } +] \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..5ee5d0a04 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +# 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: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..fd9668459 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,85 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + +jobs: + tox: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + tox-env: + - py38 + - black-template + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install dependencies + run: | + python -m pip install -U pip + python -m pip install -U tox + - name: Tox ${{ matrix.tox-env }} + run: tox -e ${{ matrix.tox-env }} + + docker: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + script: + - name: Basic + args: "" + - name: Extended + args: "use_celery=y use_drf=y js_task_runner=Gulp" + + env: + DOCKER_BUILDKIT: 1 + COMPOSE_DOCKER_CLI_BUILD: 1 + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Docker ${{ matrix.script.name }} + run: sh tests/test_docker.sh ${{ matrix.script.args }} + + bare: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + script: + - name: With Celery + args: "use_celery=y use_compressor=y" + + 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@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Bare Metal ${{ matrix.script.name }} + run: sh tests/test_bare.sh ${{ matrix.script.args }} diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml new file mode 100644 index 000000000..f6b465276 --- /dev/null +++ b/.github/workflows/issue-manager.yml @@ -0,0 +1,62 @@ +# Automatically close issues that have a keyword mark (an HTML comment) +# in the last comment in the issue, by a group of predefined users, after a custom delay. +# https://github.com/tiangolo/issue-manager + +# Default config: +# +# Wait 10 days and comment: "Assuming the original issue was solved, it will be automatically closed now" + +# Extra config: +# '' +# Wait 10 days and comment: "Automatically closing. To re-open, please provide the additional information requested" + +name: Issue Manager + +on: + # Every day at midnight + schedule: + - cron: "0 0 * * *" + # Manual trigger + workflow_dispatch: + +jobs: + issue-manager: + runs-on: ubuntu-latest + steps: + - uses: tiangolo/issue-manager@0.3.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + config: > + { + "answered": { + "delay": 864000, + "message": "Assuming the original issue was solved, it will be automatically closed now.", + "users": [ + "pydanny", + "audreyr", + "luzfcb", + "theskumar", + "jayfk", + "burhan", + "webyneter", + "browniebroke", + "sfdye" + ] + }, + "waiting": { + "delay": 864000, + "message": "Automatically closing. To re-open, please provide the additional information requested.", + "users": [ + "pydanny", + "audreyr", + "luzfcb", + "theskumar", + "jayfk", + "burhan", + "webyneter", + "browniebroke", + "sfdye" + ] + } + } diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml new file mode 100644 index 000000000..2b5bb09b5 --- /dev/null +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -0,0 +1,36 @@ +# Run pre-commit autoupdate every day at midnight +# and create a pull request if any changes + + +name: Pre-commit auto-update + +on: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: # to trigger manually + +jobs: + auto-update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install pre-commit + run: pip install pre-commit + + - name: Run pre-commit autoupdate + working-directory: "{{cookiecutter.project_slug}}" + run: pre-commit autoupdate + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3.5.2 + 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..0c72c7819 --- /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: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Update list + run: python scripts/update_changelog.py + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v4.7.2 + with: + commit_message: Update Changelog + file_pattern: CHANGELOG.md diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml new file mode 100644 index 000000000..4ce1c76f1 --- /dev/null +++ b/.github/workflows/update-contributors.yml @@ -0,0 +1,30 @@ +name: Update Contributors + +on: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Update list + run: python scripts/update_contributors.py + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v4.7.2 + 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/.travis.yml b/.travis.yml deleted file mode 100644 index 6039075a0..000000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -services: - - docker - -language: python - -python: 3.8 - -before_install: - - docker-compose -v - - docker -v - -matrix: - include: - - name: Test results - script: tox -e py38 - - name: Black template - script: tox -e black-template - - name: Basic Docker - script: sh tests/test_docker.sh - - name: Extended Docker - script: sh tests/test_docker.sh use_celery=y use_drf=y - - name: Bare metal - script: sh tests/test_bare.sh use_celery=y use_compressor=y - services: - - postgresql - - redis-server - env: - - CELERY_BROKER_URL=redis://localhost:6379/0 - -install: - - pip install tox - -notifications: - email: - on_success: change - on_failure: always diff --git a/CHANGELOG.md b/CHANGELOG.md index 27a8578a2..68f29a1f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,262 @@ # Change Log All enhancements and patches to Cookiecutter Django will be documented in this file. + + +## [2020-12-09] +### Changed +- Bump peter-evans/create-pull-request from v3.5.1 to v3.5.2 ([#2964](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2964)) + +## [2020-12-08] +### Updated +- Update pre-commit to 2.9.3 ([#2961](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2961)) + +## [2020-12-04] +### Updated +- Update django-debug-toolbar to 3.2 ([#2959](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2959)) + +## [2020-12-02] +### Updated +- Update django-model-utils to 4.1.1 ([#2957](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2957)) +- Update pygithub to 1.54 ([#2958](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2958)) + +## [2020-11-26] +### Updated +- Update django-extensions to 3.1.0 ([#2947](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2947)) +- Update pre-commit to 2.9.2 ([#2948](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2948)) +- Update django-allauth to 0.44.0 ([#2945](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2945)) + +## [2020-11-25] +### Changed +- Bump peter-evans/create-pull-request from v3.5.0 to v3.5.1 ([#2944](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2944)) + +## [2020-11-23] +### Updated +- Update uvicorn to 0.12.3 ([#2943](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2943)) +- Update pre-commit to 2.9.0 ([#2942](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2942)) + +## [2020-11-21] +### Changed +- Fix after uvicorn 0.12.0 - Ship extra dependencies ([#2939](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2939)) + +## [2020-11-20] +### Updated +- Update sentry-sdk to 0.19.4 ([#2938](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2938)) + +## [2020-11-19] +### Updated +- Update django-crispy-forms to 1.10.0 ([#2937](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2937)) + +## [2020-11-17] +### Changed +- Bump peter-evans/create-pull-request from v2 to v3.5.0 ([#2936](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2936)) + +## [2020-11-15] +### Changed +- Fix formatting in docs ([#2935](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2935)) + +## [2020-11-13] +### Changed +- Upgrade factory-boy to 3.1.0 ([#2932](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2932)) +### Updated +- Update sentry-sdk to 0.19.3 ([#2933](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2933)) +- Update sphinx to 3.3.1 ([#2934](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2934)) + +## [2020-11-12] +### Changed +- Migrate CI to Github Actions ([#2931](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2931)) + +## [2020-11-06] +### Updated +- Update djangorestframework to 3.12.2 ([#2930](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2930)) + +## [2020-11-04] +### Changed +- Fix docs service and add RTD support ([#2920](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2920)) +- Bump stefanzweifel/git-auto-commit-action from v4.6.0 to v4.7.2 ([#2914](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2914)) +### Updated +- Auto-update pre-commit hooks ([#2908](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2908)) +- Update mypy to 0.790 ([#2886](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2886)) +- Update django-stubs to 1.7.0 ([#2916](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2916)) + +## [2020-11-03] +### Updated +- Update sentry-sdk to 0.19.2 ([#2926](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2926)) +- Update sphinx to 3.3.0 ([#2925](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2925)) +- Update django to 3.0.11 ([#2924](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2924)) +- Update pytz to 2020.4 ([#2923](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2923)) +- Update pre-commit to 2.8.2 ([#2919](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2919)) +- Update pytest to 6.1.2 ([#2917](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2917)) +- Update sh to 1.14.1 ([#2912](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2912)) +- Update pytest-django to 4.1.0 ([#2911](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2911)) +- Update pillow to 8.0.1 ([#2910](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2910)) +- Update django-celery-beat to 2.1.0 ([#2907](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2907)) +- Update uvicorn to 0.12.2 ([#2906](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2906)) + +## [2020-10-19] +### Updated +- Update sentry-sdk to 0.19.1 ([#2905](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2905)) + +## [2020-10-17] +### Updated +- Update django-allauth to 0.43.0 ([#2901](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2901)) +- Update pytest-django to 4.0.0 ([#2903](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2903)) + +## [2020-10-15] +### Updated +- Update pillow to 8.0.0 ([#2898](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2898)) + +## [2020-10-14] +### Updated +- Auto-update pre-commit hooks ([#2897](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2897)) +- Update sentry-sdk to 0.19.0 ([#2896](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2896)) + +## [2020-10-13] +### Updated +- Update isort to 5.6.4 ([#2895](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2895)) + +## [2020-10-12] +### Changed +- Bump stefanzweifel/git-auto-commit-action from v4.5.1 to v4.6.0 ([#2893](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2893)) +### Updated +- Auto-update pre-commit hooks ([#2892](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2892)) + +## [2020-10-11] +### Updated +- Auto-update pre-commit hooks ([#2890](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2890)) +- Update isort to 5.6.3 ([#2891](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2891)) +- Update django-anymail to 8.1 ([#2887](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2887)) +- Update tox to 3.20.1 ([#2885](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2885)) + +## [2020-10-09] +### Updated +- Auto-update pre-commit hooks ([#2884](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2884)) +- Update isort to 5.6.1 ([#2883](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2883)) + +## [2020-10-08] +### Changed +- Add dedicated websockets package ([#2881](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2881)) +### Updated +- Update isort to 5.6.0 ([#2882](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2882)) + +## [2020-10-04] +### Updated +- Update pytest to 6.1.1 ([#2880](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2880)) +- Update mypy and django-stubs ([#2874](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2874)) +- Auto-update pre-commit hooks ([#2876](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2876)) +- Update flake8 to 3.8.4 ([#2877](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2877)) + +## [2020-10-01] +### Changed +- Bump actions/setup-python from v2.1.2 to v2.1.3 ([#2869](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2869)) +### Updated +- Update ipdb to 0.13.4 ([#2873](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2873)) +- Auto-update pre-commit hooks ([#2867](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2867)) +- Update uvicorn to 0.12.1 ([#2866](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2866)) +- Update isort to 5.5.4 ([#2864](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2864)) +- Update sentry-sdk to 0.18.0 ([#2863](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2863)) +- Update djangorestframework to 3.12.1 ([#2862](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2862)) +- Update pytest to 6.1.0 ([#2859](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2859)) +- Update django-debug-toolbar to 3.1.1 ([#2855](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2855)) + +## [2020-09-23] +### Updated +- Update sentry-sdk to 0.17.7 ([#2847](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2847)) +- Update django-debug-toolbar to 3.1 ([#2846](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2846)) + +## [2020-09-21] +### Changed +- Adding GitHub-Action CI Option ([#2837](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2837)) +### Updated +- Update django-debug-toolbar to 3.0 ([#2842](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2842)) +- Auto-update pre-commit hooks ([#2843](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2843)) +- Update isort to 5.5.3 ([#2844](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2844)) + +## [2020-09-18] +### Updated +- Update django-extensions to 3.0.9 ([#2839](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2839)) + +## [2020-09-16] +### Updated +- Update sentry-sdk to 0.17.6 ([#2833](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2833)) +- Update pytest-django to 3.10.0 ([#2832](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2832)) + +## [2020-09-14] +### Fixed +- Downgrade Celery to 4.4.6 ([#2829](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2829)) +### Updated +- Update sentry-sdk to 0.17.5 ([#2828](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2828)) +- Update coverage to 5.3 ([#2826](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2826)) +- Update django-storages to 1.10.1 ([#2825](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2825)) + +## [2020-09-12] +### Updated +- Updating Traefik version from 2.0 to 2.2.11 ([#2814](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2814)) +- Update pytest to 6.0.2 ([#2819](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2819)) +- Update django-anymail to 8.0 ([#2818](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2818)) + +## [2020-09-11] +### Updated +- Auto-update pre-commit hooks ([#2809](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2809)) + +## [2020-09-10] +### Updated +- Update isort to 5.5.2 ([#2807](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2807)) +- Update sentry-sdk to 0.17.4 ([#2805](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2805)) + +## [2020-09-09] +### Changed +- Update actions/setup-python requirement to v2.1.2 ([#2804](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2804)) +- Clean up nested venv files from `.gitignore` ([#2800](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2800)) + +## [2020-09-08] +### Changed +- Traeffik and Django dockerfile changes ([#2801](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2801)) + +## [2020-09-07] +### Changed +- Add :z/:Z to mounted volumes in {local,production}.yml ([#2663](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2663)) +- Remove --no-binary option for psycopg2 ([#2798](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2798)) +- Updated Gitlab CI to use Python 3.8 instead of Python 3.7 ([#2794](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2794)) +### Fixed +- Fix options for sphinx-autobuild in docs Makefile ([#2799](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2799)) +### Updated +- Update psycopg2-binary to 2.8.6 ([#2797](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2797)) + +## [2020-09-05] +### Updated +- Auto-update pre-commit hooks ([#2793](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2793)) + +## [2020-09-04] +### Updated +- Update django-extensions to 3.0.8 ([#2792](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2792)) +- Update isort to 5.5.1 ([#2791](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2791)) +- Auto-update pre-commit hooks ([#2790](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2790)) +- Update isort to 5.5.0 ([#2789](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2789)) + +## [2020-09-02] +### Changed +- Add environment and traces_sample_rate keyword to sentry_sdk.init ([#2777](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2777)) +### Updated +- Update sentry-sdk to 0.17.3 ([#2788](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2788)) +- Update django-extensions to 3.0.7 ([#2787](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2787)) + +## [2020-09-01] +### Changed +- Exclude venv directory and update document link ([#2780](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2780)) +### Updated +- Update tox to 3.20.0 ([#2786](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2786)) +- Update django-storages to 1.10 ([#2781](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2781)) +- Update sentry-sdk to 0.17.2 ([#2784](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2784)) +- Update django to 3.0.10 ([#2785](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2785)) +- Update sphinx-autobuild to 2020.9.1 ([#2782](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2782)) +- Update django-extensions to 3.0.6 ([#2783](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2783)) + +## [2020-08-31] +### Updated +- Update sh to 1.14.0 ([#2779](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2779)) +- Update sentry-sdk to 0.17.1 ([#2778](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2778)) + ## [2020-04-13] ### Changed - Updated to Python 3.8 (@codnee) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 0a64e628b..5d88bf5bf 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -8,7 +8,6 @@ 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 ------- diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 000000000..6649f3fd7 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,1501 @@ +# 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
+ +*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 +
Adam Bogdał + bogdal +
Adam Dobrawy + ad-m +
Adam Steele + adammsteele +
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 +
Arnav Choudhury + arnav13081994 +
AsheKR + ashekr +
Ashley Camba + +
Barclay Gauld + yunti +
Bartek + btknu +
Ben Lopatin + +
Ben Warren + bwarren2 +
Benjamin Abel + +
Bert de Miranda + bertdemiranda +
Bo Lopker + blopker +
Bo Peng + BoPeng +
Bouke Haarsma + +
Brent Payne + brentpayne + brentpayne
Bruce Olivier + bolivierjr +
Caio Ariede + caioariede + caioariede
Carl Johnson + carlmjohnson + carlmjohnson
Catherine Devlin + catherinedevlin +
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 +
Dan Shultz + shultz +
Dani Hodovic + danihodovic +
Daniel Hepper + dhepper + danielhepper
Daniel Hillier + danifus +
Daniel Sears + highpost + highpost
Daniele Tricoli + eriol +
David Díaz + ddiazpinto + DavidDiazPinto
Davit Tovmasyan + davitovmasyan +
Davur Clementsen + dsclementsen + davur
Delio Castillo + jangeador + jangeador
Demetris Stavrou + demestav +
Denis Bobrov + delneg +
Denis Orehovsky + apirobot +
Denis Savran + blaxpy +
Diane Chen + purplediane + purplediane88
Dong Huynh + trungdong +
Duda Nogueira + dudanogueira + dudanogueira
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
Gabriel Mejia + elgartoinf + elgartoinf
Garry Cairns + garry-cairns +
Garry Polley + garrypolley +
Gilbishkosma + Gilbishkosma +
Glenn Wiskur + gwiskur +
Guilherme Guy + guilherme1guy +
Hamish Durkin + durkode +
Hana Quadara + hanaquadara +
Hannah Lazarus + hanhanhan +
Harry Moreno + morenoh149 + morenoh149
Harry Percival + hjwp +
Hendrik Schneider + hendrikschneider +
Henrique G. G. Pereira + ikkebr +
Howie Zhao + howiezhao +
Ian Lee + IanLee1521 +
Irfan Ahmad + erfaan + erfaan
Isaac12x + Isaac12x +
Ivan Khomutov + ikhomutov +
Jakub Musko + umgelurgel +
James Williams + jameswilliams1 +
Jan Fabry + janfabry +
Jan Van Bruggen + jvanbrug +
Jelmer Draaijer + foarsitter +
Jens Nilsson + phiberjenz +
Jerome Caisip + jeromecaisip +
Jerome Leclanche + jleclanche + Adys
Jimmy Gitonga + Afrowave + afrowave
John Cass + jcass77 + cass_john
Jonathan Thompson + nojanath +
Jules Cheron + jules-ch +
Julien Almarcha + sladinji +
Julio Castillo + juliocc +
Kaido Kert + kaidokert +
kappataumu + kappataumu + kappataumu
Kaveh + ka7eh +
Keith Bailey + keithjeb +
Keith Webber + townie +
Kevin A. Stone + +
Kevin Ndung'u + kevgathuku +
Keyvan Mosharraf + keyvanm +
Krzysztof Szumny + noisy +
Krzysztof Żuraw + krzysztofzuraw +
Leo won + leollon +
Leo Zhou + glasslion +
Leon Kim + PilhwanKim +
Leonardo Jimenez + xpostudio4 +
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 Knapper + mknapper1 +
Matt Linares + +
Matt Menzenski + menzenski +
Matt Warren + mfwarren +
Matthew Sisley + mjsisley +
Matthias Sieber + manonthemat + MatzeOne
Meghan Heintz + dot2dotseurat +
Mesut Yılmaz + myilmaz +
Michael Gecht + mimischi + _mischi
Michael Samoylov + msamoylov +
Min ho Kim + minho42 +
mozillazg + mozillazg +
Nico Stefani + nicolas471 + moby_dick91
Oleg Russkin + rolep +
Pablo + oubiga +
Parbhat Puri + parbhat +
Pawan Chaurasia + rjsnh1522 +
Peter Bittner + bittner +
Peter Coles + mrcoles +
Philipp Matthies + canonnervio +
Pierre Chiquet + pchiquet +
Raony Guimarães Corrêa + raonyguimaraes +
Raphael Pierzina + hackebrot +
Reggie Riser + reggieriser +
René Muhl + rm-- +
Richard Hajdu + Tusky +
Roman Afanaskin + siauPatrick +
Roman Osipenko + romanosipenko +
Russell Davies + +
Sam Collins + MightySCollins +
Sascha + saschalalala + saschalalala
Simon Rey + eqqe +
Sorasful + sorasful +
Srinivas Nyayapati + shireenrao +
stepmr + stepmr +
Steve Steiner + ssteinerX +
Sudarshan Wadkar + wadkar +
Sule Marshall + suledev +
Sławek Ehlert + slafs +
Tano Abeleyra + tanoabeleyra +
Taylor Baldwin + +
Théo Segonds + show0k +
Tim Claessens + timclaessens +
Tim Freund + timfreund +
Tom Atkins + knitatoms +
Tom Offermann + +
Travis McNeill + Travistock + tavistock_esq
Tubo Shi + Tubo +
Umair Ashraf + umrashrf + fabumair
Vadim Iskuchekov + Egregors + egregors
Vicente G. Reyes + reyesvicente + highcenburg
Vitaly Babiy + +
Vivian Guillen + viviangb +
Vlad Doster + vladdoster +
Wes Turner + westurner + westurner
Will Farley + goldhand + g01dhand
William Archinal + archinal +
Xaver Y.R. Chen + yrchen + yrchen
Yaroslav Halchenko + +
Yuchen Xie + mapx +
+ +### 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 3166ac820..000000000 --- a/CONTRIBUTORS.rst +++ /dev/null @@ -1,420 +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`_ - 2O4 `@2O4`_ - a7p `@a7p`_ - Aaron Eikenberry `@aeikenberry`_ - Adam Bogdał `@bogdal`_ - Adam Dobrawy `@ad-m`_ - Adam Steele `@adammsteele`_ - 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 Mikhnevich `@zcho`_ - Andrew Chen Wang `@Andrew-Chen-Wang`_ - Andy Rose - Anna Callahan `@jazztpt`_ - Anna Sidwell `@takkaria`_ - Antonia Blair `@antoniablair`_ @antoniablairart - Anuj Bansal `@ahhda`_ - Arcuri Davide `@dadokkio`_ - Areski Belaid `@areski`_ - AsheKR `@ashekr`_ - Ashley Camba - Barclay Gauld `@yunti`_ - Bartek `@btknu`_ - Ben Lopatin - Ben Warren `@bwarren2`_ - Benjamin Abel - Bert de Miranda `@bertdemiranda`_ - Bo Lopker `@blopker`_ - Bo Peng `@BoPeng`_ - Bouke Haarsma - Brent Payne `@brentpayne`_ @brentpayne - Bruce Olivier `@bolivierjr`_ - Burhan Khalid            `@burhan`_                   @burhan - Caio Ariede `@caioariede`_ @caioariede - 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`_ - Cole Maclean `@cole`_ @cole - Collederas `@Collederas`_ - Craig Margieson `@cmargieson`_ - Cristian Vargas `@cdvv7788`_ - Cullen Rhodes `@c-rhodes`_ - Curtis St Pierre `@curtisstpierre`_ @cstpierre1388 - Dan Shultz `@shultz`_ - Dani Hodovic `@danihodovic`_ - Daniel Hepper `@dhepper`_ @danielhepper - Daniel Hillier `@danifus`_ - Daniel Sears `@highpost`_ @highpost - Daniele Tricoli `@eriol`_ - David Díaz `@ddiazpinto`_ @DavidDiazPinto - Davit Tovmasyan `@davitovmasyan`_ - Davur Clementsen `@dsclementsen`_ @davur - Delio Castillo `@jangeador`_ @jangeador - Demetris Stavrou `@demestav`_ - Denis Bobrov `@delneg`_ - Denis Orehovsky `@apirobot`_ - Denis Savran `@blaxpy`_ - Diane Chen `@purplediane`_ @purplediane88 - Dónal Adams `@epileptic-fish`_ - Dong Huynh `@trungdong`_ - Duda Nogueira `@dudanogueira`_ @dudanogueira - Emanuel Calso `@bloodpet`_ @bloodpet - Eraldo Energy `@eraldo`_ - Eric Groom `@ericgroom`_ - Ernesto Cedeno `@codnee`_ - Eyad Al Sibai `@eyadsibai`_ - Felipe Arruda `@arruda`_ - Florian Idelberger `@step21`_ @windrush - Gabriel Mejia `@elgartoinf`_ @elgartoinf - Garry Cairns `@garry-cairns`_ - Garry Polley `@garrypolley`_ - Gilbishkosma `@Gilbishkosma`_ - Glenn Wiskur `@gwiskur`_ - Guilherme Guy `@guilherme1guy`_ - Hamish Durkin `@durkode`_ - Hana Quadara `@hanaquadara`_ - Hannah Lazarus `@hanhanhan`_ - Harry Moreno `@morenoh149`_ @morenoh149 - Harry Percival `@hjwp`_ - Hendrik Schneider `@hendrikschneider`_ - Henrique G. G. Pereira `@ikkebr`_ - Howie Zhao `@howiezhao`_ - Ian Lee `@IanLee1521`_ - Irfan Ahmad `@erfaan`_ @erfaan - Isaac12x `@Isaac12x`_ - Ivan Khomutov `@ikhomutov`_ - James Williams `@jameswilliams1`_ - Jan Van Bruggen `@jvanbrug`_ - Jelmer Draaijer `@foarsitter`_ - Jerome Caisip `@jeromecaisip`_ - Jens Nilsson `@phiberjenz`_ - Jerome Leclanche `@jleclanche`_ @Adys - Jimmy Gitonga `@afrowave`_ @afrowave - John Cass `@jcass77`_ @cass_john - Jonathan Thompson `@nojanath`_ - Jules Cheron `@jules-ch`_ - Julien Almarcha `@sladinji`_ - Julio Castillo `@juliocc`_ - Kaido Kert `@kaidokert`_ - kappataumu `@kappataumu`_ @kappataumu - Kaveh `@ka7eh`_ - Keith Bailey `@keithjeb`_ - Keith Webber `@townie`_ - Kevin A. Stone - Kevin Ndung'u `@kevgathuku`_ - Keyvan Mosharraf `@keyvanm`_ - Krzysztof Szumny `@noisy`_ - Krzysztof Żuraw `@krzysztofzuraw`_ - Leo won `@leollon`_ - Leo Zhou `@glasslion`_ - Leon Kim `@PilhwanKim`_ - Leonardo Jimenez `@xpostudio4`_ - 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 Knapper `@mknapper1`_ - Matt Linares - Matt Menzenski `@menzenski`_ - Matt Warren `@mfwarren`_ - Matthew Sisley `@mjsisley`_ - Meghan Heintz `@dot2dotseurat`_ - Mesut Yılmaz `@myilmaz`_ - Michael Gecht `@mimischi`_ @_mischi - Michael Samoylov `@msamoylov`_ - Min ho Kim `@minho42`_ - mozillazg `@mozillazg`_ - Nico Stefani `@nicolas471`_ @moby_dick91 - Oleg Russkin `@rolep`_ - Pablo `@oubiga`_ - Parbhat Puri `@parbhat`_ - Pawan Chaurasia `@rjsnh1522`_ - Peter Bittner `@bittner`_ - Peter Coles `@mrcoles`_ - Philipp Matthies `@canonnervio`_ - Pierre Chiquet `@pchiquet`_ - Raony Guimarães Corrêa `@raonyguimaraes`_ - Raphael Pierzina `@hackebrot`_ - Reggie Riser `@reggieriser`_ - René Muhl `@rm--`_ - Roman Afanaskin `@siauPatrick`_ - Roman Osipenko `@romanosipenko`_ - Russell Davies - Sam Collins `@MightySCollins`_ - Sascha `@saschalalala`_ @saschalalala - Shupeyko Nikita `@webyneter`_ - Sławek Ehlert `@slafs`_ - Sorasful `@sorasful`_ - Srinivas Nyayapati `@shireenrao`_ - stepmr `@stepmr`_ - Steve Steiner `@ssteinerX`_ - Sudarshan Wadkar `@wadkar`_ - Sule Marshall `@suledev`_ - Tano Abeleyra `@tanoabeleyra`_ - Taylor Baldwin - Théo Segonds `@show0k`_ - Tim Claessens `@timclaessens`_ - Tim Freund `@timfreund`_ - Tom Atkins `@knitatoms`_ - Tom Offermann - Travis McNeill `@Travistock`_ @tavistock_esq - Tubo Shi `@Tubo`_ - Umair Ashraf `@umrashrf`_ @fabumair - Vadim Iskuchekov `@Egregors`_ @egregors - Vicente G. Reyes `@reyesvicente`_ @highcenburg - Vitaly Babiy - Vivian Guillen `@viviangb`_ - Vlad Doster `@vladdoster`_ - Will Farley `@goldhand`_ @g01dhand - William Archinal `@archinal`_ - Xaver Y.R. Chen `@yrchen`_ @yrchen - Yaroslav Halchenko - Yotam Tal `@yotamtal`_ - Yuchen Xie `@mapx`_ -========================== ============================ ============== - -.. _@a7p: https://github.com/a7p -.. _@2O4: https://github.com/2O4 -.. _@ad-m: https://github.com/ad-m -.. _@adammsteele: https://github.com/adammsteele -.. _@aeikenberry: https://github.com/aeikenberry -.. _@afrowave: https://github.com/afrowave -.. _@ahhda: https://github.com/ahhda -.. _@alb3rto: https://github.com/alb3rto -.. _@ameistad: https://github.com/ameistad -.. _@amjith: https://github.com/amjith -.. _@andor-pierdelacabeza: https://github.com/andor-pierdelacabeza -.. _@andresgz: https://github.com/andresgz -.. _@antoniablair: https://github.com/antoniablair -.. _@Andrew-Chen-Wang: https://github.com/Andrew-Chen-Wang -.. _@apirobot: https://github.com/apirobot -.. _@archinal: https://github.com/archinal -.. _@areski: https://github.com/areski -.. _@arruda: https://github.com/arruda -.. _@ashekr: https://github.com/ashekr -.. _@bertdemiranda: https://github.com/bertdemiranda -.. _@bittner: https://github.com/bittner -.. _@blaxpy: https://github.com/blaxpy -.. _@bloodpet: https://github.com/bloodpet -.. _@blopker: https://github.com/blopker -.. _@bogdal: https://github.com/bogdal -.. _@bolivierjr: https://github.com/bolivierjr -.. _@BoPeng: https://github.com/BoPeng -.. _@brentpayne: https://github.com/brentpayne -.. _@btknu: https://github.com/btknu -.. _@burhan: https://github.com/burhan -.. _@bwarren2: https://github.com/bwarren2 -.. _@c-rhodes: https://github.com/c-rhodes -.. _@caffodian: https://github.com/caffodian -.. _@canonnervio: https://github.com/canonnervio -.. _@caioariede: https://github.com/caioariede -.. _@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 -.. _@cmargieson: https://github.com/cmargieson -.. _@codnee: https://github.com/codnee -.. _@cole: https://github.com/cole -.. _@Collederas: https://github.com/Collederas -.. _@curtisstpierre: https://github.com/curtisstpierre -.. _@dadokkio: https://github.com/dadokkio -.. _@danihodovic: https://github.com/danihodovic -.. _@danifus: https://github.com/danifus -.. _@davitovmasyan: https://github.com/davitovmasyan -.. _@ddiazpinto: https://github.com/ddiazpinto -.. _@delneg: https://github.com/delneg -.. _@demestav: https://github.com/demestav -.. _@dezoito: https://github.com/dezoito -.. _@dhepper: https://github.com/dhepper -.. _@dot2dotseurat: https://github.com/dot2dotseurat -.. _@dudanogueira: https://github.com/dudanogueira -.. _@dsclementsen: https://github.com/dsclementsen -.. _@guilherme1guy: https://github.com/guilherme1guy -.. _@durkode: https://github.com/durkode -.. _@Egregors: https://github.com/Egregors -.. _@elgartoinf: https://gihub.com/elgartoinf -.. _@epileptic-fish: https://gihub.com/epileptic-fish -.. _@eraldo: https://github.com/eraldo -.. _@erfaan: https://github.com/erfaan -.. _@ericgroom: https://github.com/ericgroom -.. _@eriol: https://github.com/eriol -.. _@eyadsibai: https://github.com/eyadsibai -.. _@flyudvik: https://github.com/flyudvik -.. _@foarsitter: https://github.com/foarsitter -.. _@garry-cairns: https://github.com/garry-cairns -.. _@garrypolley: https://github.com/garrypolley -.. _@Gilbishkosma: https://github.com/Gilbishkosma -.. _@gwiskur: https://github.com/gwiskur -.. _@glasslion: https://github.com/glasslion -.. _@goldhand: https://github.com/goldhand -.. _@hackebrot: https://github.com/hackebrot -.. _@hairychris: https://github.com/hairychris -.. _@hanaquadara: https://github.com/hanaquadara -.. _@hanhanhan: https://github.com/hanhanhan -.. _@hendrikschneider: https://github.com/hendrikschneider -.. _@highpost: https://github.com/highpost -.. _@hjwp: https://github.com/hjwp -.. _@howiezhao: https://github.com/howiezhao -.. _@IanLee1521: https://github.com/IanLee1521 -.. _@ikhomutov: https://github.com/ikhomutov -.. _@jameswilliams1: https://github.com/jameswilliams1 -.. _@ikkebr: https://github.com/ikkebr -.. _@Isaac12x: https://github.com/Isaac12x -.. _@iynaix: https://github.com/iynaix -.. _@jangeador: https://github.com/jangeador -.. _@jazztpt: https://github.com/jazztpt -.. _@jcass77: https://github.com/jcass77 -.. _@jeromecaisip: https://github.com/jeromecaisip -.. _@jleclanche: https://github.com/jleclanche -.. _@jules-ch: https://github.com/jules-ch -.. _@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 -.. _@keithjeb: https://github.com/keithjeb -.. _@kevgathuku: https://github.com/kevgathuku -.. _@keyvanm: https://github.com/keyvanm -.. _@knitatoms: https://github.com/knitatoms -.. _@krzysztofzuraw: https://github.com/krzysztofzuraw -.. _@leollon: https://github.com/leollon -.. _@MathijsHoogland: https://github.com/MathijsHoogland -.. _@mapx: https://github.com/mapx -.. _@mattayes: https://github.com/mattayes -.. _@menzenski: https://github.com/menzenski -.. _@mfwarren: https://github.com/mfwarren -.. _@MightySCollins: https://github.com/MightySCollins -.. _@mimischi: https://github.com/mimischi -.. _@minho42: https://github.com/minho42 -.. _@mjsisley: https://github.com/mjsisley -.. _@mknapper1: https://github.com/mknapper1 -.. _@morenoh149: https://github.com/morenoh149 -.. _@mostaszewski: https://github.com/mostaszewski -.. _@mozillazg: https://github.com/mozillazg -.. _@mrcoles: https://github.com/mrcoles -.. _@msaizar: https://github.com/msaizar -.. _@msamoylov: https://github.com/msamoylov -.. _@myilmaz: https://github.com/myilmaz -.. _@nicolas471: https://github.com/nicolas471 -.. _@noisy: https://github.com/noisy -.. _@nojanath: https://github.com/nojanath -.. _@originell: https://github.com/originell -.. _@oubiga: https://github.com/oubiga -.. _@parbhat: https://github.com/parbhat -.. _@rjsnh1522: https://github.com/rjsnh1522 -.. _@pchiquet: https://github.com/pchiquet -.. _@phiberjenz: https://github.com/phiberjenz -.. _@PilhwanKim: https://github.com/PilhwanKim -.. _@purplediane: https://github.com/purplediane -.. _@raonyguimaraes: https://github.com/raonyguimaraes -.. _@reggieriser: https://github.com/reggieriser -.. _@reyesvicente: https://github.com/reyesvicente -.. _@rm--: https://github.com/rm-- -.. _@rolep: https://github.com/rolep -.. _@romanosipenko: https://github.com/romanosipenko -.. _@saschalalala: https://github.com/saschalalala -.. _@scaramagus: https://github.com/scaramagus -.. _@shireenrao: https://github.com/shireenrao -.. _@show0k: https://github.com/show0k -.. _@shultz: https://github.com/shultz -.. _@siauPatrick: https://github.com/siauPatrick -.. _@sladinji: https://github.com/sladinji -.. _@slafs: https://github.com/slafs -.. _@sorasful:: https://github.com/sorasful -.. _@ssteinerX: https://github.com/ssteinerx -.. _@step21: https://github.com/step21 -.. _@stepmr: https://github.com/stepmr -.. _@suledev: https://github.com/suledev -.. _@takkaria: https://github.com/takkaria -.. _@tanoabeleyra: https://github.com/tanoabeleyra -.. _@timclaessens: https://github.com/timclaessens -.. _@timfreund: https://github.com/timfreund -.. _@townie: https://github.com/townie -.. _@Travistock: https://github.com/Tavistock -.. _@trungdong: https://github.com/trungdong -.. _@Tubo: https://github.com/tubo -.. _@umrashrf: https://github.com/umrashrf -.. _@viviangb: https://github.com/viviangb -.. _@vladdoster: https://github.com/vladdoster -.. _@wadkar: https://github.com/wadkar -.. _@xpostudio4: https://github.com/xpostudio4 -.. _@yrchen: https://github.com/yrchen -.. _@yotamtal: https://github.com/yotamtal -.. _@yunti: https://github.com/yunti -.. _@zcho: https://github.com/zcho - -Special Thanks -~~~~~~~~~~~~~~ - -The following haven't provided code directly, but have provided guidance and advice. - -* Jannis Leidel -* Nate Aune -* Barry Morrison diff --git a/README.rst b/README.rst index cfb253787..dbc510a47 100644 --- a/README.rst +++ b/README.rst @@ -1,8 +1,8 @@ Cookiecutter Django -======================= +=================== -.. image:: https://travis-ci.org/pydanny/cookiecutter-django.svg?branch=master - :target: https://travis-ci.org/pydanny/cookiecutter-django?branch=master +.. image:: https://img.shields.io/github/workflow/status/pydanny/cookiecutter-django/CI/master + :target: https://github.com/pydanny/cookiecutter-django/actions?query=workflow%3ACI :alt: Build Status .. image:: https://readthedocs.org/projects/cookiecutter-django/badge/?version=latest @@ -96,7 +96,7 @@ Constraints ----------- * Only maintained 3rd party libraries are used. -* Uses PostgreSQL everywhere (9.4 - 11.3) +* Uses PostgreSQL everywhere (9.4 - 12.3) * Environment variables for configuration (This won't work with Apache/mod_wsgi). Support this Project! @@ -110,16 +110,17 @@ This project is run by volunteers. Please support them in their efforts to maint Projects that provide financial support to the maintainers: -Django Crash Course + + ~~~~~~~~~~~~~~~~~~~~~~~~~ -.. image:: https://cdn.shopify.com/s/files/1/0304/6901/files/Django-Crash-Course-300x436.jpg - :name: Django Crash Course: Covers Django 3.0 and Python 3.8 +.. image:: https://cdn.shopify.com/s/files/1/0304/6901/products/Two-Scoops-of-Django-3-Alpha-Cover_540x_26507b15-e489-470b-8a97-02773dd498d1_1080x.jpg + :name: Two Scoops of Django 3.x :align: center - :alt: Django Crash Course - :target: https://www.roygreenfeld.com/products/django-crash-course + :alt: Two Scoops of Django + :target: https://www.feldroy.com/products//two-scoops-of-django-3-x -Django Crash Course for Django 3.0 and Python 3.8 is the best cheese-themed Django reference in the universe! +Two Scoops of Django 3.x is the best ice cream-themed Django reference in the universe! pyup ~~~~~~~~~~~~~~~~~~ @@ -176,11 +177,11 @@ Answer the prompts with your own desired options_. For example:: use_heroku [n]: y use_compressor [n]: y Select postgresql_version: - 1 - 11.3 - 2 - 10.8 - 3 - 9.6 - 4 - 9.5 - 5 - 9.4 + 1 - 12.3 + 2 - 11.8 + 3 - 10.8 + 4 - 9.6 + 5 - 9.5 Choose from 1, 2, 3, 4, 5 [1]: 1 Select js_task_runner: 1 - None diff --git a/cookiecutter.json b/cookiecutter.json index 62155ad0e..4a580036d 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -18,11 +18,11 @@ "use_pycharm": "n", "use_docker": "n", "postgresql_version": [ - "11.3", + "12.3", + "11.8", "10.8", "9.6", - "9.5", - "9.4" + "9.5" ], "js_task_runner": [ "None", @@ -56,9 +56,9 @@ "ci_tool": [ "None", "Travis", - "Gitlab" + "Gitlab", + "Github" ], "keep_local_envs_in_vcs": "y", - "debug": "n" } diff --git a/docs/deployment-with-docker.rst b/docs/deployment-with-docker.rst index 8a206885a..01df2e44d 100644 --- a/docs/deployment-with-docker.rst +++ b/docs/deployment-with-docker.rst @@ -82,7 +82,7 @@ The Traefik reverse proxy used in the default configuration will get you a valid You can read more about this feature and how to configure it, at `Automatic HTTPS`_ in the Traefik docs. -.. _Automatic HTTPS: https://docs.traefik.io/configuration/acme/ +.. _Automatic HTTPS: https://docs.traefik.io/https/acme/ (Optional) Postgres Data Volume Modifications diff --git a/docs/developing-locally-docker.rst b/docs/developing-locally-docker.rst index d6b4146d5..0d582d484 100644 --- a/docs/developing-locally-docker.rst +++ b/docs/developing-locally-docker.rst @@ -116,7 +116,7 @@ Consider the aforementioned ``.envs/.local/.postgres``: :: 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 @@ -178,8 +178,7 @@ When developing locally you can go with MailHog_ for email testing provided ``us 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. +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. @@ -200,3 +199,96 @@ 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 + +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. + +On order to create a secure environment, we need to have a trusted SSL certficate 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 environements. + +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`` on the projects 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 environmental 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 a5d598f0b..2b7806ce4 100644 --- a/docs/developing-locally.rst +++ b/docs/developing-locally.rst @@ -24,9 +24,9 @@ First things first. $ source /bin/activate -#. Install cookiecutter-django +#. Install cookiecutter-django: :: - $ cookiecutter gh:pydanny/cookiecutter-django :: + $ cookiecutter gh:pydanny/cookiecutter-django #. Install development requirements: :: @@ -34,10 +34,10 @@ First things first. $ git init # A git repo is required for pre-commit to install $ pre-commit install - .. note:: + .. note:: - the `pre-commit` exists in the generated project as default. - for the details of `pre-commit`, follow the [site of pre-commit](https://pre-commit.com/). + the `pre-commit` exists in the generated project as default. + for the details of `pre-commit`, follow the [site of pre-commit](https://pre-commit.com/). #. Create a new PostgreSQL database using createdb_: :: diff --git a/docs/document.rst b/docs/document.rst index 7207e357c..a30979094 100644 --- a/docs/document.rst +++ b/docs/document.rst @@ -4,42 +4,41 @@ Document ========= This project uses Sphinx_ documentation generator. -After you have set up to `develop locally`_, run the following commands to generate the HTML documentation: :: - $ sphinx-build docs/ docs/_build/html/ +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 run --rm django sphinx-build docs/ docs/_build/html/ + $ docker-compose -f local.yml up docs + +Navigate to port 7000 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 ---------------------------- -Sphinx can automatically generate documentation from docstrings, to enable this feature, follow these steps: +Edit the ``docs`` files and project application docstrings to create your documentation. -1. Add Sphinx extension in ``docs/conf.py`` file, like below: :: +Sphinx can automatically include class and function signatures and docstrings in generated documentation. +See the generated project documentation for more examples. - extensions = [ - 'sphinx.ext.autodoc', - ] +Setting up ReadTheDocs +---------------------- -2. Uncomment the following lines in the ``docs/conf.py`` file: :: +To setup your documentation on `ReadTheDocs`_, you must - # import django - # sys.path.insert(0, os.path.abspath('..')) - # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") - # django.setup() +1. Go to `ReadTheDocs`_ and login/create an account +2. Add your GitHub repository +3. Trigger a build -3. Run the following command: :: - - $ sphinx-apidoc -f -o ./docs/modules/ ./tpub/ migrations/* - - If you set up your project to `develop locally with docker`_, run the following command: :: - - $ docker-compose -f local.yml run --rm django sphinx-apidoc -f -o ./docs/modules ./tpub/ migrations/* - -4. Regenerate HTML documentation as written above. +Additionally, you can auto-build Pull Request previews, but `you must enable it`_. +.. _localhost: http://localhost:7000/ .. _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/linters.rst b/docs/linters.rst index 2d6232181..a4f60cc8d 100644 --- a/docs/linters.rst +++ b/docs/linters.rst @@ -19,7 +19,7 @@ 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 diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index 1c2fc3149..8a81e19de 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -49,11 +49,11 @@ use_docker: postgresql_version: Select a PostgreSQL_ version to use. The choices are: - 1. 11.3 - 2. 10.8 - 3. 9.6 - 4. 9.5 - 5. 9.4 + 1. 12.3 + 2. 11.8 + 3. 10.8 + 4. 9.6 + 5. 9.5 js_task_runner: Select a JavaScript task runner. The choices are: @@ -119,6 +119,7 @@ ci_tool: 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 @@ -176,3 +177,4 @@ debug: .. _GitLab CI: https://docs.gitlab.com/ee/ci/ +.. _Github Actions: https://docs.github.com/en/actions diff --git a/docs/settings.rst b/docs/settings.rst index 949d5f35f..7563f50d2 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -49,6 +49,8 @@ DJANGO_AWS_S3_CUSTOM_DOMAIN AWS_S3_CUSTOM_DOMAIN n/a DJANGO_GCP_STORAGE_BUCKET_NAME GS_BUCKET_NAME n/a raises error GOOGLE_APPLICATION_CREDENTIALS n/a n/a raises error SENTRY_DSN SENTRY_DSN n/a raises error +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_API_KEY n/a raises error MAILGUN_DOMAIN MAILGUN_SENDER_DOMAIN n/a raises error diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 13d0ff00a..ede14c324 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -75,6 +75,11 @@ def remove_heroku_files(): # don't remove the file if we are using travisci but not using heroku continue os.remove(file_name) + remove_heroku_build_hooks() + + +def remove_heroku_build_hooks(): + shutil.rmtree("bin") def remove_gulp_files(): @@ -118,6 +123,10 @@ def remove_dotgitlabciyml_file(): os.remove(".gitlab-ci.yml") +def remove_dotgithub_folder(): + shutil.rmtree(".github") + + def append_to_project_gitignore(path): gitignore_file_path = ".gitignore" with open(gitignore_file_path, "a") as gitignore_file: @@ -346,6 +355,8 @@ def main(): if "{{ cookiecutter.use_heroku }}".lower() == "n": remove_heroku_files() + elif "{{ cookiecutter.use_compressor }}".lower() == "n": + remove_heroku_build_hooks() if ( "{{ cookiecutter.use_docker }}".lower() == "n" @@ -388,6 +399,9 @@ def main(): if "{{ cookiecutter.ci_tool }}".lower() != "gitlab": remove_dotgitlabciyml_file() + if "{{ cookiecutter.ci_tool }}".lower() != "github": + remove_dotgithub_folder() + if "{{ cookiecutter.use_drf }}".lower() == "n": remove_drf_starter_files() diff --git a/requirements.txt b/requirements.txt index e6e63d634..482b00768 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,17 +1,23 @@ cookiecutter==1.7.2 -sh==1.13.1 +sh==1.14.1 binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -black==19.10b0 -flake8==3.8.3 -flake8-isort==3.0.0 +black==20.8b1 +isort==5.6.4 +flake8==3.8.4 +flake8-isort==4.0.0 # Testing # ------------------------------------------------------------------------------ -tox==3.16.1 -pytest==5.4.3 +tox==3.20.1 +pytest==5.4.3 # pyup: <6 # https://github.com/hackebrot/pytest-cookies/issues/51 pytest-cookies==0.5.1 pytest-instafail==0.4.2 pyyaml==5.3.1 + +# Scripting +# ------------------------------------------------------------------------------ +PyGithub==1.54 +jinja2==2.11.2 diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/scripts/__init__.py @@ -0,0 +1 @@ + diff --git a/scripts/update_changelog.py b/scripts/update_changelog.py new file mode 100644 index 000000000..08ff5b095 --- /dev/null +++ b/scripts/update_changelog.py @@ -0,0 +1,78 @@ +import os +from pathlib import Path +from github import Github +from jinja2 import Template +import datetime as dt + +CURRENT_FILE = Path(__file__) +ROOT = CURRENT_FILE.parents[1] +GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", None) + +# Generate changelog for PRs merged yesterday +MERGED_DATE = dt.date.today() - dt.timedelta(days=1) + + +def main() -> None: + """ + Script entry point. + """ + merged_pulls = list(iter_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 + rendered_content = generate_md(grouped_pulls) + + # Update CHANGELOG.md file + file_path = ROOT / "CHANGELOG.md" + old_content = file_path.read_text() + updated_content = old_content.replace( + "", + f"\n\n{rendered_content}", + ) + file_path.write_text(updated_content) + + +def iter_pulls(): + """Fetch merged pull requests at the date we're interested in.""" + repo = Github(login_or_token=GITHUB_TOKEN).get_repo("pydanny/cookiecutter-django") + 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): + """Group pull request by change type.""" + grouped_pulls = { + "Changed": [], + "Fixed": [], + "Updated": [], + } + for pull in pull_requests_list: + label_names = {l.name for l in pull.labels} + if "update" in label_names: + group_name = "Updated" + elif "bug" in label_names: + group_name = "Fixed" + else: + group_name = "Changed" + grouped_pulls[group_name].append(pull) + return grouped_pulls + + +def generate_md(grouped_pulls): + """Generate markdown file from Jinja template.""" + changelog_template = ROOT / ".github" / "changelog-template.md" + template = Template(changelog_template.read_text(), autoescape=True) + return template.render(merge_date=MERGED_DATE, grouped_pulls=grouped_pulls) + + +if __name__ == "__main__": + main() diff --git a/scripts/update_contributors.py b/scripts/update_contributors.py new file mode 100644 index 000000000..0236daae3 --- /dev/null +++ b/scripts/update_contributors.py @@ -0,0 +1,104 @@ +import json +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"] + + +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(per_page=5).get_repo("pydanny/cookiecutter-django") + 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__": + main() diff --git a/setup.py b/setup.py index 6b80bd9a0..c72ba1c9d 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ except ImportError: # 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 = "3.0.7" +version = "3.0.11" if sys.argv[-1] == "tag": os.system(f'git tag -a {version} -m "version {version}"') diff --git a/tests/test_bare.sh b/tests/test_bare.sh index 7021a7e47..eae09dc78 100755 --- a/tests/test_bare.sh +++ b/tests/test_bare.sh @@ -1,9 +1,14 @@ #!/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_docker.sh +# sh tests/test_bare.sh set -o errexit +set -x + +# Install modern pip with new resolver: +# https://blog.python.org/2020/11/pip-20-3-release-new-resolver.html +pip install 'pip>=20.3' # install test requirements pip install -r requirements.txt diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index aa7cc75a4..af6e4588b 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -37,11 +37,11 @@ SUPPORTED_COMBINATIONS = [ {"use_pycharm": "n"}, {"use_docker": "y"}, {"use_docker": "n"}, - {"postgresql_version": "11.3"}, + {"postgresql_version": "12.3"}, + {"postgresql_version": "11.8"}, {"postgresql_version": "10.8"}, {"postgresql_version": "9.6"}, {"postgresql_version": "9.5"}, - {"postgresql_version": "9.4"}, {"cloud_provider": "AWS", "use_whitenoise": "y"}, {"cloud_provider": "AWS", "use_whitenoise": "n"}, {"cloud_provider": "GCP", "use_whitenoise": "y"}, @@ -96,6 +96,7 @@ SUPPORTED_COMBINATIONS = [ {"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"}, @@ -132,13 +133,13 @@ def check_paths(paths): for line in open(path, "r"): 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}" @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 @@ -176,7 +177,10 @@ def test_black_passes(cookies, context_override): @pytest.mark.parametrize( ["use_docker", "expected_test_script"], - [("n", "pytest"), ("y", "docker-compose -f local.yml run django pytest"),], + [ + ("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}) @@ -189,7 +193,7 @@ def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_scrip with open(f"{result.project}/.travis.yml", "r") as travis_yml: try: - yml = yaml.load(travis_yml, Loader=yaml.FullLoader)["jobs"]["include"] + 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: @@ -198,7 +202,10 @@ def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_scrip @pytest.mark.parametrize( ["use_docker", "expected_test_script"], - [("n", "pytest"), ("y", "docker-compose -f local.yml run django pytest"),], + [ + ("n", "pytest"), + ("y", "docker-compose -f local.yml run django pytest"), + ], ) def test_gitlab_invokes_flake8_and_pytest( cookies, context, use_docker, expected_test_script @@ -213,13 +220,49 @@ def test_gitlab_invokes_flake8_and_pytest( with open(f"{result.project}/.gitlab-ci.yml", "r") as gitlab_yml: try: - gitlab_config = yaml.load(gitlab_yml, Loader=yaml.FullLoader) + gitlab_config = yaml.safe_load(gitlab_yml) assert gitlab_config["flake8"]["script"] == ["flake8"] 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 exec -T django pytest"), + ], +) +def test_github_invokes_flake8_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.basename == context["project_slug"] + assert result.project.isdir() + + with open(f"{result.project}/.github/workflows/ci.yml", "r") as github_yml: + try: + github_config = yaml.safe_load(github_yml) + flake8_present = False + for action_step in github_config["jobs"]["flake8"]["steps"]: + if action_step.get("run") == "flake8": + flake8_present = True + assert flake8_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 failed pre-generation hook.""" diff --git a/tests/test_docker.sh b/tests/test_docker.sh index 55771c14c..740f8fc22 100755 --- a/tests/test_docker.sh +++ b/tests/test_docker.sh @@ -4,6 +4,7 @@ # sh tests/test_docker.sh set -o errexit +set -x # install test requirements pip install -r requirements.txt diff --git a/tox.ini b/tox.ini index 242183c39..cecc7435f 100644 --- a/tox.ini +++ b/tox.ini @@ -8,4 +8,4 @@ commands = pytest {posargs:./tests} [testenv:black-template] deps = black -commands = black --check hooks tests setup.py docs +commands = black --check hooks tests setup.py docs scripts diff --git a/{{cookiecutter.project_slug}}/.github/dependabot.yml b/{{cookiecutter.project_slug}}/.github/dependabot.yml new file mode 100644 index 000000000..8e8ac8663 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + # Update Github actions in workflows + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml new file mode 100644 index 000000000..52818e187 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -0,0 +1,95 @@ +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" ] + paths-ignore: [ "docs/**" ] + + push: + branches: [ "master" ] + paths-ignore: [ "docs/**" ] + + +jobs: + flake8: + runs-on: ubuntu-latest + steps: + + - name: Checkout Code Repository + uses: actions/checkout@v2 + + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install flake8 + run: | + python -m pip install --upgrade pip + pip install flake8 + + - name: Lint with flake8 + run: flake8 + +# With no caching at all the entire ci process takes 4m 30s to complete! + pytest: + runs-on: ubuntu-latest + steps: + + - name: Checkout Code Repository + uses: actions/checkout@v2 + {% if cookiecutter.use_docker == 'y' -%} + + - name: Build the Stack + run: docker-compose -f local.yml build + + - name: Make DB Migrations + run: docker-compose -f local.yml run --rm django python manage.py migrate + + - name: Run the Stack + run: docker-compose -f local.yml up -d + + - name: Run Django Tests + run: docker-compose -f local.yml exec -T django pytest + + - name: Tear down the Stack + run: docker-compose down + + {%- else %} + + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Get pip cache dir + id: pip-cache-location + run: | + echo "::set-output name=dir::$(pip cache dir)" + + {% raw %} + - name: Cache pip Project Dependencies + uses: actions/cache@v2 + with: + # Get the location of pip cache dir + path: ${{ steps.pip-cache-location.outputs.dir }} + # Look to see if there is a cache hit for the corresponding requirements file + key: ${{ runner.os }}-pip-${{ hashFiles('**/local.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + {% endraw %} + + - 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 cb8ad8358..311b43a57 100644 --- a/{{cookiecutter.project_slug}}/.gitignore +++ b/{{cookiecutter.project_slug}}/.gitignore @@ -321,19 +321,6 @@ Session.vim # Auto-generated tag files tags -{% if cookiecutter.use_docker == 'n' %} - -### VirtualEnv template -# Virtualenv -[Bb]in -[Ii]nclude -[Ll]ib -[Ll]ib64 -[Ss]cripts -pyvenv.cfg -pip-selfcheck.json -.env -{% endif %} ### Project template {% if cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'n' %} diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index 246c4c982..60925b811 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -13,7 +13,7 @@ variables: flake8: stage: lint - image: python:3.7-alpine + image: python:3.8-alpine before_script: - pip install -q flake8 script: @@ -21,7 +21,7 @@ flake8: pytest: stage: test - image: python:3.7 + image: python:3.8 {% if cookiecutter.use_docker == 'y' -%} image: docker/compose:latest tags: @@ -39,7 +39,7 @@ pytest: tags: - python services: - - postgres:11 + - postgres:{{ cookiecutter.postgresql_version }} variables: DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index 6aa9207a9..55368bb73 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -4,19 +4,24 @@ fail_fast: true repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: master + rev: v3.3.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - repo: https://github.com/psf/black - rev: 19.10b0 + rev: 20.8b1 hooks: - id: black + - repo: https://github.com/timothycrosley/isort + rev: 5.6.4 + hooks: + - id: isort + - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.3 + rev: 3.8.4 hooks: - id: flake8 args: ['--config=setup.cfg'] diff --git a/{{cookiecutter.project_slug}}/.readthedocs.yml b/{{cookiecutter.project_slug}}/.readthedocs.yml new file mode 100644 index 000000000..b193a85e0 --- /dev/null +++ b/{{cookiecutter.project_slug}}/.readthedocs.yml @@ -0,0 +1,9 @@ +version: 2 + +sphinx: + configuration: docs/conf.py + +python: + version: 3.8 + install: + - requirements: requirements/local.txt diff --git a/{{cookiecutter.project_slug}}/bin/post_compile b/{{cookiecutter.project_slug}}/bin/post_compile new file mode 100644 index 000000000..a9c94b39a --- /dev/null +++ b/{{cookiecutter.project_slug}}/bin/post_compile @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +compress_enabled() { +python << END +import sys + +from environ import Env + +env = Env(COMPRESS_ENABLED=(bool, True)) +if env('COMPRESS_ENABLED'): + sys.exit(0) +else: + sys.exit(1) + +END +} + +if compress_enabled +then + python manage.py compress +fi +python manage.py collectstatic --noinput diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile new file mode 100644 index 000000000..315fdd405 --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.8-slim-buster + +ENV PYTHONUNBUFFERED 1 +ENV PYTHONDONTWRITEBYTECODE 1 + +RUN apt-get update \ + # dependencies for building Python packages + && apt-get install -y build-essential \ + # psycopg2 dependencies + && apt-get install -y libpq-dev \ + # Translations dependencies + && apt-get install -y gettext \ + # Uncomment below lines to enable Sphinx output to latex and pdf + # && apt-get install -y texlive-latex-recommended \ + # && apt-get install -y texlive-fonts-recommended \ + # && apt-get install -y texlive-latex-extra \ + # && apt-get install -y latexmk \ + # cleaning up unused files + && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ + && rm -rf /var/lib/apt/lists/* + +# Requirements are installed here to ensure they will be cached. +COPY ./requirements /requirements +# All imports needed for autodoc. +RUN pip install -r /requirements/local.txt -r /requirements/production.txt + +COPY ./compose/local/docs/start /start-docs +RUN sed -i 's/\r$//g' /start-docs +RUN chmod +x /start-docs + +WORKDIR /docs diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/start b/{{cookiecutter.project_slug}}/compose/local/docs/start new file mode 100644 index 000000000..fd2e0de6a --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/local/docs/start @@ -0,0 +1,7 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set -o nounset + +make livehtml diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile index 72f71d6ec..2e6a195b7 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile @@ -32,26 +32,26 @@ COPY ./requirements /requirements RUN pip install --no-cache-dir -r /requirements/production.txt \ && rm -rf /requirements -COPY ./compose/production/django/entrypoint /entrypoint +COPY --chown=django:django ./compose/production/django/entrypoint /entrypoint RUN sed -i 's/\r$//g' /entrypoint RUN chmod +x /entrypoint -RUN chown django /entrypoint -COPY ./compose/production/django/start /start + +COPY --chown=django:django ./compose/production/django/start /start RUN sed -i 's/\r$//g' /start RUN chmod +x /start -RUN chown django /start + {%- if cookiecutter.use_celery == "y" %} -COPY ./compose/production/django/celery/worker/start /start-celeryworker +COPY --chown=django:django ./compose/production/django/celery/worker/start /start-celeryworker RUN sed -i 's/\r$//g' /start-celeryworker RUN chmod +x /start-celeryworker -RUN chown django /start-celeryworker -COPY ./compose/production/django/celery/beat/start /start-celerybeat + +COPY --chown=django:django ./compose/production/django/celery/beat/start /start-celerybeat RUN sed -i 's/\r$//g' /start-celerybeat RUN chmod +x /start-celerybeat -RUN chown django /start-celerybeat + COPY ./compose/production/django/celery/flower/start /start-flower RUN sed -i 's/\r$//g' /start-flower diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile index 746aa2b48..aa879052b 100644 --- a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile @@ -1,5 +1,5 @@ -FROM traefik:v2.0 -RUN mkdir -p /etc/traefik/acme -RUN touch /etc/traefik/acme/acme.json -RUN chmod 600 /etc/traefik/acme/acme.json +FROM traefik:v2.2.11 +RUN mkdir -p /etc/traefik/acme \ + && touch /etc/traefik/acme/acme.json \ + && chmod 600 /etc/traefik/acme/acme.json COPY ./compose/production/traefik/traefik.yml /etc/traefik diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index 7f339fadc..f69908c2d 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -80,6 +80,7 @@ THIRD_PARTY_APPS = [ {%- if cookiecutter.use_drf == "y" %} "rest_framework", "rest_framework.authtoken", + "corsheaders", {%- endif %} ] @@ -134,6 +135,9 @@ AUTH_PASSWORD_VALIDATORS = [ # https://docs.djangoproject.com/en/dev/ref/settings/#middleware MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", +{%- if cookiecutter.use_drf == 'y' %} + "corsheaders.middleware.CorsMiddleware", +{%- endif %} {%- if cookiecutter.use_whitenoise == 'y' %} "whitenoise.middleware.WhiteNoiseMiddleware", {%- endif %} @@ -321,6 +325,10 @@ REST_FRAMEWORK = { ), "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), } + +# django-cors-headers - https://github.com/adamchainz/django-cors-headers#setup +CORS_URLS_REGEX = r"^/api/.*$" + {%- endif %} # Your stuff... # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 3d4f324cd..340046f98 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -34,7 +34,7 @@ CACHES = { "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", # Mimicing memcache behavior. - # http://jazzband.github.io/django-redis/latest/#_memcached_exceptions_behavior + # https://github.com/jazzband/django-redis#memcached-exceptions-behavior "IGNORE_EXCEPTIONS": True, }, } @@ -86,8 +86,6 @@ _AWS_EXPIRY = 60 * 60 * 24 * 7 AWS_S3_OBJECT_PARAMETERS = { "CacheControl": f"max-age={_AWS_EXPIRY}, s-maxage={_AWS_EXPIRY}, must-revalidate" } -# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings -AWS_DEFAULT_ACL = None # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None) # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#cloudfront @@ -235,13 +233,12 @@ ANYMAIL = {} # ------------------------------------------------------------------------------ # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_ENABLED COMPRESS_ENABLED = env.bool("COMPRESS_ENABLED", default=True) +{%- if cookiecutter.cloud_provider == 'None' %} # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE -{%- if cookiecutter.cloud_provider == 'AWS' %} -COMPRESS_STORAGE = "storages.backends.s3boto3.S3Boto3Storage" -{%- elif cookiecutter.cloud_provider == 'GCP' %} -COMPRESS_STORAGE = "storages.backends.gcloud.GoogleCloudStorage" -{%- elif cookiecutter.cloud_provider == 'None' %} COMPRESS_STORAGE = "compressor.storage.GzipCompressorFileStorage" +{%- elif cookiecutter.cloud_provider in ('AWS', 'GCP') and cookiecutter.use_whitenoise == 'n' %} +# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE +COMPRESS_STORAGE = STATICFILES_STORAGE {%- endif %} # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %} # noqa F405{% endif %} @@ -354,13 +351,17 @@ sentry_logging = LoggingIntegration( ) {%- if cookiecutter.use_celery == 'y' %} +integrations = [sentry_logging, DjangoIntegration(), CeleryIntegration()] +{% else %} +integrations = [sentry_logging, DjangoIntegration()] +{% endif -%} + sentry_sdk.init( dsn=SENTRY_DSN, - integrations=[sentry_logging, DjangoIntegration(), CeleryIntegration()], + integrations=integrations, + environment=env("SENTRY_ENVIRONMENT", default="production"), + traces_sample_rate=env.float("SENTRY_TRACES_SAMPLE_RATE", default=0.0), ) -{% else %} -sentry_sdk.init(dsn=SENTRY_DSN, integrations=[sentry_logging, DjangoIntegration()]) -{% endif -%} {% endif %} # Your stuff... # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/docs/Makefile b/{{cookiecutter.project_slug}}/docs/Makefile index d4bb2cbb9..0b56e1f86 100644 --- a/{{cookiecutter.project_slug}}/docs/Makefile +++ b/{{cookiecutter.project_slug}}/docs/Makefile @@ -3,18 +3,38 @@ # You can set these variables from the command line, and also # from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build -c . SOURCEDIR = . -BUILDDIR = _build +BUILDDIR = ./_build +{%- if cookiecutter.use_docker == 'y' %} +APP = /app +{%- else %} +APP = ../{{cookiecutter.project_slug}} +{% endif %} + +.PHONY: help livehtml apidocs Makefile # Put it first so that "make" without argument is like "make help". help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @$(SPHINXBUILD) help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -.PHONY: help Makefile +# Build, watch and serve docs with live reload +livehtml: + sphinx-autobuild -b html + {%- if cookiecutter.use_docker == 'y' %} --host 0.0.0.0 + {%- else %} --open-browser + {%- endif %} --port 7000 --watch $(APP) -c . $(SOURCEDIR) $(BUILDDIR)/html + +# Outputs rst files from django application code +apidocs: + {%- if cookiecutter.use_docker == 'y' %} + sphinx-apidoc -o $(SOURCEDIR)/api /app + {%- else %} + sphinx-apidoc -o $(SOURCEDIR)/api ../{{cookiecutter.project_slug}} + {%- endif %} # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @$(SPHINXBUILD) -b $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/{{cookiecutter.project_slug}}/docs/conf.py b/{{cookiecutter.project_slug}}/docs/conf.py index bfde1e3a6..c640e1c63 100644 --- a/{{cookiecutter.project_slug}}/docs/conf.py +++ b/{{cookiecutter.project_slug}}/docs/conf.py @@ -9,15 +9,27 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -# + import os import sys +import django -# import django -# sys.path.insert(0, os.path.abspath('..')) -# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") -# django.setup() - +if os.getenv("READTHEDOCS", default=False) == "True": + sys.path.insert(0, os.path.abspath("..")) + os.environ["DJANGO_READ_DOT_ENV_FILE"] = "True" + os.environ["USE_DOCKER"] = "no" +else: +{%- if cookiecutter.use_docker == 'y' %} + sys.path.insert(0, os.path.abspath("/app")) +{%- else %} + sys.path.insert(0, os.path.abspath("..")) +{%- endif %} +os.environ["DATABASE_URL"] = "sqlite:///readthedocs.db" +{%- if cookiecutter.use_celery == 'y' %} +os.environ["CELERY_BROKER_URL"] = os.getenv("REDIS_URL", "redis://redis:6379") +{%- endif %} +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") +django.setup() # -- Project information ----------------------------------------------------- @@ -31,17 +43,19 @@ author = "{{ cookiecutter.author_name }}" # 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 = [ + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", +] # Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] +# templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for @@ -52,4 +66,4 @@ html_theme = "alabaster" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +# html_static_path = ["_static"] diff --git a/{{cookiecutter.project_slug}}/docs/howto.rst b/{{cookiecutter.project_slug}}/docs/howto.rst new file mode 100644 index 000000000..25f442c37 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docs/howto.rst @@ -0,0 +1,46 @@ +How To - Project Documentation +====================================================================== + +Get Started +---------------------------------------------------------------------- + +Documentation can be written as rst files in the `{{cookiecutter.project_slug}}/docs/_source`. + +{% if cookiecutter.use_docker == 'n' %} +To build and serve docs, use the command: + :: + + make livehtml + +from inside the `{{cookiecutter.project_slug}}/docs` directory. +{% else %} +To build and serve docs, use the commands: + :: + + docker-compose -f local.yml up docs +{% endif %} + +Changes to files in `docs/_source` will be picked up and reloaded automatically. + +`Sphinx `_ is the tool used to build documentation. + +Docstrings to Documentation +---------------------------------------------------------------------- + +The sphinx extension `apidoc `_ is used to automatically document code using signatures and docstrings. + +Numpy or Google style docstrings will be picked up from project files and availble for documentation. See the `Napoleon `_ extension for details. + +For an in-use example, see the `page source <_sources/users.rst.txt>`_ for :ref:`users`. + +To compile all docstrings automatically into documentation source files, use the command: + :: + + make apidocs + +{% if cookiecutter.use_docker == 'y' %} +This can be done in the docker container: + :: + + docker run --rm docs make apidocs +{% endif -%} diff --git a/{{cookiecutter.project_slug}}/docs/index.rst b/{{cookiecutter.project_slug}}/docs/index.rst index b107a9e5c..5fafc6966 100644 --- a/{{cookiecutter.project_slug}}/docs/index.rst +++ b/{{cookiecutter.project_slug}}/docs/index.rst @@ -10,7 +10,9 @@ Welcome to {{ cookiecutter.project_name }}'s documentation! :maxdepth: 2 :caption: Contents: + howto pycharm/configuration + users diff --git a/{{cookiecutter.project_slug}}/docs/make.bat b/{{cookiecutter.project_slug}}/docs/make.bat index 922152e96..b19f42c6a 100644 --- a/{{cookiecutter.project_slug}}/docs/make.bat +++ b/{{cookiecutter.project_slug}}/docs/make.bat @@ -4,11 +4,13 @@ pushd %~dp0 REM Command file for Sphinx documentation + if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build + set SPHINXBUILD=sphinx-build -c . ) -set SOURCEDIR=. +set SOURCEDIR=_source set BUILDDIR=_build +set APP=..\{{cookiecutter.project_slug}} if "%1" == "" goto help @@ -20,16 +22,25 @@ if errorlevel 9009 ( echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. + echo.Install sphinx-autobuild for live serving. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +%SPHINXBUILD% -b %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end +:livehtml +sphinx-autobuild -b html --open-browser -p 7000 --watch %APP% -c . %SOURCEDIR% %BUILDDIR%/html +GOTO :EOF + +:apidocs +sphinx-apidoc -o %SOURCEDIR%/api %APP% +GOTO :EOF + :help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +%SPHINXBUILD% -b help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd diff --git a/{{cookiecutter.project_slug}}/docs/users.rst b/{{cookiecutter.project_slug}}/docs/users.rst new file mode 100644 index 000000000..6cf645562 --- /dev/null +++ b/{{cookiecutter.project_slug}}/docs/users.rst @@ -0,0 +1,15 @@ + .. _users: + +Users +====================================================================== + +Starting a new project, it’s highly recommended to set up a custom user model, +even if the default User model is sufficient for you. + +This model behaves identically to the default user model, +but you’ll be able to customize it in the future if the need arises. + +.. automodule:: {{cookiecutter.project_slug}}.users.models + :members: + :noindex: + diff --git a/{{cookiecutter.project_slug}}/gulpfile.js b/{{cookiecutter.project_slug}}/gulpfile.js index 1f9884ec8..206f8a019 100644 --- a/{{cookiecutter.project_slug}}/gulpfile.js +++ b/{{cookiecutter.project_slug}}/gulpfile.js @@ -163,9 +163,9 @@ function initBrowserSync() { // Watch function watchPaths() { - watch(`${paths.sass}/*.scss`, styles) - watch(`${paths.templates}/**/*.html`).on("change", reload) - watch([`${paths.js}/*.js`, `!${paths.js}/*.min.js`], scripts).on("change", reload) + watch(`${paths.sass}/*.scss`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, styles) + watch(`${paths.templates}/**/*.html`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}).on("change", reload) + watch([`${paths.js}/*.js`, `!${paths.js}/*.min.js`]{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, scripts).on("change", reload) } // Generate all assets diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml index b603f1778..e285f3498 100644 --- a/{{cookiecutter.project_slug}}/local.yml +++ b/{{cookiecutter.project_slug}}/local.yml @@ -17,7 +17,7 @@ services: - mailhog {%- endif %} volumes: - - .:/app + - .:/app:z env_file: - ./.envs/.local/.django - ./.envs/.local/.postgres @@ -32,10 +32,27 @@ services: image: {{ cookiecutter.project_slug }}_production_postgres container_name: postgres volumes: - - local_postgres_data:/var/lib/postgresql/data - - local_postgres_data_backups:/backups + - local_postgres_data:/var/lib/postgresql/data:Z + - local_postgres_data_backups:/backups:z env_file: - ./.envs/.local/.postgres + + docs: + image: {{ cookiecutter.project_slug }}_local_docs + container_name: docs + build: + context: . + dockerfile: ./compose/local/docs/Dockerfile + env_file: + - ./.envs/.local/.django + volumes: + - ./docs:/docs:z + - ./config:/app/config:z + - ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}:z + ports: + - "7000:7000" + command: /start-docs + {%- if cookiecutter.use_mailhog == 'y' %} mailhog: @@ -97,7 +114,7 @@ services: depends_on: - django volumes: - - .:/app + - .:/app:z # http://jdlm.info/articles/2016/03/06/lessons-building-node-app-docker.html - /app/node_modules command: npm run dev diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml index 2cd2af132..93b61b134 100644 --- a/{{cookiecutter.project_slug}}/production.yml +++ b/{{cookiecutter.project_slug}}/production.yml @@ -25,8 +25,8 @@ services: dockerfile: ./compose/production/postgres/Dockerfile image: {{ cookiecutter.project_slug }}_production_postgres volumes: - - production_postgres_data:/var/lib/postgresql/data - - production_postgres_data_backups:/backups + - production_postgres_data:/var/lib/postgresql/data:Z + - production_postgres_data_backups:/backups:z env_file: - ./.envs/.production/.postgres @@ -38,7 +38,7 @@ services: depends_on: - django volumes: - - production_traefik:/etc/traefik/acme + - production_traefik:/etc/traefik/acme:z ports: - "0.0.0.0:80:80" - "0.0.0.0:443:443" @@ -75,5 +75,5 @@ services: env_file: - ./.envs/.production/.django volumes: - - production_postgres_data_backups:/backups + - production_postgres_data_backups:/backups:z {%- endif %} diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 4baf2f376..9b0900696 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,40 +1,46 @@ -pytz==2020.1 # https://github.com/stub42/pytz -python-slugify==4.0.0 # https://github.com/un33k/python-slugify -Pillow==7.1.2 # https://github.com/python-pillow/Pillow +pytz==2020.4 # https://github.com/stub42/pytz +python-slugify==4.0.1 # https://github.com/un33k/python-slugify +Pillow==8.0.1 # https://github.com/python-pillow/Pillow {%- if cookiecutter.use_compressor == "y" %} -rcssmin==1.0.6{% if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} --install-option="--without-c-extensions"{% endif %} # https://github.com/ndparker/rcssmin +{%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} +rcssmin==1.0.6 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin +{%- else %} +rcssmin==1.0.6 # https://github.com/ndparker/rcssmin +{%- endif %} {%- endif %} argon2-cffi==20.1.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} -whitenoise==5.1.0 # https://github.com/evansd/whitenoise +whitenoise==5.2.0 # https://github.com/evansd/whitenoise {%- endif %} -redis==3.5.0 # https://github.com/andymccurdy/redis-py +redis==3.5.3 # https://github.com/andymccurdy/redis-py {%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %} -hiredis==1.0.1 # https://github.com/redis/hiredis-py +hiredis==1.1.0 # https://github.com/redis/hiredis-py {%- endif %} {%- if cookiecutter.use_celery == "y" %} -celery==4.4.5 # pyup: < 5.0 # https://github.com/celery/celery -django-celery-beat==2.0.0 # https://github.com/celery/django-celery-beat +celery==4.4.6 # pyup: < 5.0,!=4.4.7 # https://github.com/celery/celery +django-celery-beat==2.1.0 # https://github.com/celery/django-celery-beat +django-timezone-field==4.0 # https://github.com/celery/django-celery-beat/pull/378 {%- if cookiecutter.use_docker == 'y' %} -flower==0.9.4 # https://github.com/mher/flower +flower==0.9.5 # https://github.com/mher/flower {%- endif %} {%- endif %} {%- if cookiecutter.use_async == 'y' %} -uvicorn==0.11.5 # https://github.com/encode/uvicorn +uvicorn[standard]==0.12.3 # https://github.com/encode/uvicorn {%- endif %} # Django # ------------------------------------------------------------------------------ -django==3.0.7 # pyup: < 3.1 # https://www.djangoproject.com/ +django==3.0.11 # pyup: < 3.1 # https://www.djangoproject.com/ django-environ==0.4.5 # https://github.com/joke2k/django-environ -django-model-utils==4.0.0 # https://github.com/jazzband/django-model-utils -django-allauth==0.42.0 # https://github.com/pennersr/django-allauth -django-crispy-forms==1.9.1 # https://github.com/django-crispy-forms/django-crispy-forms +django-model-utils==4.1.1 # https://github.com/jazzband/django-model-utils +django-allauth==0.44.0 # https://github.com/pennersr/django-allauth +django-crispy-forms==1.10.0 # https://github.com/django-crispy-forms/django-crispy-forms {%- if cookiecutter.use_compressor == "y" %} django-compressor==2.4 # https://github.com/django-compressor/django-compressor {%- endif %} django-redis==4.12.1 # https://github.com/jazzband/django-redis {%- if cookiecutter.use_drf == "y" %} # Django REST Framework -djangorestframework==3.11.0 # https://github.com/encode/django-rest-framework +djangorestframework==3.12.2 # https://github.com/encode/django-rest-framework +django-cors-headers==3.5.0 # https://github.com/adamchainz/django-cors-headers {%- endif %} diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 98bbbc5b1..70e9090f4 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,12 +1,11 @@ --r ./base.txt +-r base.txt Werkzeug==1.0.1 # https://github.com/pallets/werkzeug -ipdb==0.13.3 # https://github.com/gotcha/ipdb -Sphinx==3.1.1 # https://github.com/sphinx-doc/sphinx +ipdb==0.13.4 # https://github.com/gotcha/ipdb {%- if cookiecutter.use_docker == 'y' %} -psycopg2==2.8.5 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 +psycopg2==2.8.6 # https://github.com/psycopg/psycopg2 {%- else %} -psycopg2-binary==2.8.5 # https://github.com/psycopg/psycopg2 +psycopg2-binary==2.8.6 # https://github.com/psycopg/psycopg2 {%- endif %} {%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %} watchgod==0.6 # https://github.com/samuelcolvin/watchgod @@ -14,28 +13,33 @@ watchgod==0.6 # https://github.com/samuelcolvin/watchgod # Testing # ------------------------------------------------------------------------------ -mypy==0.782 # https://github.com/python/mypy -django-stubs==1.5.0 # https://github.com/typeddjango/django-stubs -pytest==5.4.3 # https://github.com/pytest-dev/pytest -pytest-sugar==0.9.3 # https://github.com/Frozenball/pytest-sugar +mypy==0.790 # https://github.com/python/mypy +django-stubs==1.7.0 # https://github.com/typeddjango/django-stubs +pytest==6.1.2 # https://github.com/pytest-dev/pytest +pytest-sugar==0.9.4 # https://github.com/Frozenball/pytest-sugar + +# Documentation +# ------------------------------------------------------------------------------ +sphinx==3.3.1 # https://github.com/sphinx-doc/sphinx +sphinx-autobuild==2020.9.1 # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ -flake8==3.8.3 # https://github.com/PyCQA/flake8 -flake8-isort==3.0.0 # https://github.com/gforcada/flake8-isort -coverage==5.1 # https://github.com/nedbat/coveragepy -black==19.10b0 # https://github.com/ambv/black -pylint-django==2.0.15 # https://github.com/PyCQA/pylint-django +flake8==3.8.4 # https://github.com/PyCQA/flake8 +flake8-isort==4.0.0 # https://github.com/gforcada/flake8-isort +coverage==5.3 # https://github.com/nedbat/coveragepy +black==20.8b1 # https://github.com/ambv/black +pylint-django==2.3.0 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} -pre-commit==2.5.1 # https://github.com/pre-commit/pre-commit +pre-commit==2.9.3 # https://github.com/pre-commit/pre-commit # Django # ------------------------------------------------------------------------------ -factory-boy==2.12.0 # https://github.com/FactoryBoy/factory_boy +factory-boy==3.1.0 # https://github.com/FactoryBoy/factory_boy -django-debug-toolbar==2.2 # https://github.com/jazzband/django-debug-toolbar -django-extensions==3.0.0 # https://github.com/django-extensions/django-extensions +django-debug-toolbar==3.2 # https://github.com/jazzband/django-debug-toolbar +django-extensions==3.1.0 # https://github.com/django-extensions/django-extensions django-coverage-plugin==1.8.0 # https://github.com/nedbat/django_coverage_plugin -pytest-django==3.9.0 # https://github.com/pytest-dev/pytest-django +pytest-django==4.1.0 # https://github.com/pytest-dev/pytest-django diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 5ec4745cd..eed4477e3 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -1,42 +1,42 @@ # PRECAUTION: avoid production dependencies that aren't in development --r ./base.txt +-r base.txt gunicorn==20.0.4 # https://github.com/benoitc/gunicorn -psycopg2==2.8.5 --no-binary psycopg2 # https://github.com/psycopg/psycopg2 +psycopg2==2.8.6 # https://github.com/psycopg/psycopg2 {%- if cookiecutter.use_whitenoise == 'n' %} Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==0.15.1 # https://github.com/getsentry/sentry-python +sentry-sdk==0.19.5 # https://github.com/getsentry/sentry-python {%- endif %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} -hiredis==1.0.1 # https://github.com/redis/hiredis-py +hiredis==1.1.0 # https://github.com/redis/hiredis-py {%- endif %} # Django # ------------------------------------------------------------------------------ {%- if cookiecutter.cloud_provider == 'AWS' %} -django-storages[boto3]==1.9.1 # https://github.com/jschneier/django-storages +django-storages[boto3]==1.10.1 # https://github.com/jschneier/django-storages {%- elif cookiecutter.cloud_provider == 'GCP' %} -django-storages[google]==1.9.1 # https://github.com/jschneier/django-storages +django-storages[google]==1.10.1 # https://github.com/jschneier/django-storages {%- endif %} {%- if cookiecutter.mail_service == 'Mailgun' %} -django-anymail[mailgun]==7.1.0 # https://github.com/anymail/django-anymail +django-anymail[mailgun]==8.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Amazon SES' %} -django-anymail[amazon_ses]==7.1.0 # https://github.com/anymail/django-anymail +django-anymail[amazon_ses]==8.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mailjet' %} -django-anymail[mailjet]==7.1.0 # https://github.com/anymail/django-anymail +django-anymail[mailjet]==8.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mandrill' %} -django-anymail[mandrill]==7.1.0 # https://github.com/anymail/django-anymail +django-anymail[mandrill]==8.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Postmark' %} -django-anymail[postmark]==7.1.0 # https://github.com/anymail/django-anymail +django-anymail[postmark]==8.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Sendgrid' %} -django-anymail[sendgrid]==7.1.0 # https://github.com/anymail/django-anymail +django-anymail[sendgrid]==8.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SendinBlue' %} -django-anymail[sendinblue]==7.1.0 # https://github.com/anymail/django-anymail +django-anymail[sendinblue]==8.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SparkPost' %} -django-anymail[sparkpost]==7.1.0 # https://github.com/anymail/django-anymail +django-anymail[sparkpost]==8.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Other SMTP' %} -django-anymail==7.1.0 # https://github.com/anymail/django-anymail +django-anymail==8.1 # https://github.com/anymail/django-anymail {%- endif %} diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt index 724c203e1..43b47fb46 100644 --- a/{{cookiecutter.project_slug}}/runtime.txt +++ b/{{cookiecutter.project_slug}}/runtime.txt @@ -1 +1 @@ -python-3.8.2 +python-3.8.5 diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg index 6520aff76..5bde75cff 100644 --- a/{{cookiecutter.project_slug}}/setup.cfg +++ b/{{cookiecutter.project_slug}}/setup.cfg @@ -1,10 +1,10 @@ [flake8] max-line-length = 120 -exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules +exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv [pycodestyle] max-line-length = 120 -exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules +exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv [mypy] python_version = 3.8 diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html index cba1b7cf7..99fe27ab0 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html @@ -5,8 +5,8 @@ {% block title %}{% endraw %}{{ cookiecutter.project_name }}{% raw %}{% endblock title %} - - + +