-
Notifications
You must be signed in to change notification settings - Fork 441
Pinax 20.XX Release Plan
- High Level Release Process
- Release Overviews
- Community Plan
- pinax-starter-app Updates
- pinax-cli Updates
- App Repo File Tree
-
App Updates- Must Have
- Drop and Add Support for Python and Django Versions
- A Note About Tool and Dependency Versions
- Fix Linting
- Update Makefile
- Create or Update CircleCI config.yml
- Update tox.ini
- Update Third-Party Dependencies
- Remove .coveragerc
- Remove setup.cfg
- Update MANIFEST.in
- Update .gitignore
- Update setup.py
- Update Version in setup.py and Change Log
- Update README.md
- Update Standard License
- Remove CONTRIBUTING.md
- Automate Adding Authors to AUTHORS File
- App Updates- Nice to Have
- Reference
- Drop Django 2.0 Support in Pinax Starter Projects
For info about our high level release process, read the RELEASE.md file in the Pinax Default Community Health File Repo.
The Pinax 18.01 release was completed in the spring of 2018. Around 28 Pinax apps were included. Most updates are explained in Converting to CircleCI and Codecov and Upgrading app for Django v2.0
Updates completed in the 18.01 release:
- Dropped support for Django 1.8, 1.9, 1.10 and Python 3.3
- Added support for Django 2.0 (See: Upgrading app for Django v2.0)
- Converted from Travis CI to CircleCI and CodeCov (See: Converting to CircleCi and Codecov)
- Changed app
README.md
layouts - Moved docs to
README.md
s - Updated
setup.py
format - Updated
.gitignore
High level-updates proposed for the 20.XX release:
- Drop support for Django 2.0, 2.1, and Python 3.4 (Official support ended in 2019)
- Drop support for Django 1.11 (Official support ends in April 2020)
- Drop support for Python 2.7 (Official support ended in January 2020)
- Drop support for Python 3.5, in order to take advantage of new features/tools available for Python 3.6 (Official support also ends in 2020)
- Continue/add support for Django 2.2, 3.0, and Python 3.6, 3.7, and 3.8
- Create organization-level, default, community health file repo and add existing and new community health files
New features and tools available as of Python 3.6 and up:
- Option to use Black
- Python support for static type checking
- Python support for f-strings
The 20.XX release will focus on apps that were included in the 18.01 release. If possible, we will included apps in the 20.XX release that were not included in the 18.01 release.
As part of the 20.XX release, a new community plan was created. See the MAINTAINERS.md
in the global community health file repo for more info: https://github.com/pinax/.github/blob/master/MAINTAINERS.md.
pinax-starter-app is a Pinax project that can be used to generate a new Pinax app. pinax-starter-app should be updated with each release to reflect the latest changes and best practices that were incorporated into the release.
The following is the current Pinax app root file tree. All apps should include Makefile
and runtests.py
. All apps that have models should include makemigrations.py
.
.circleci/config.yml
pinax/
.coveragerc
.gitignore
AUTHORS
CONTRIBUTING.md
LICENSE
Makefile
MANIFEST.in
README.md
makemigrations.py
runtests.py
setup.cfg
setup.py
tox.ini
The following is a new, simpler Pinax app root file tree.
.coveragerc
can be removed because the content can be read from the tox
file. setup.cfg
will no longer be needed due to dropping Python 2.7 support. CONTRIBUTING.md
will be moved to an organization-level, default community health file repo.
.circleci/config.yml
pinax/
.gitignore
AUTHORS
LICENSE
Makefile
MANIFEST.in
README.md
makemigrations.py
runtests.py
setup.py
tox.ini
For more information about dropping support for Python 2 see "Porting Python 2 Code to Python 3."
Examples provided by @mfonism for dropping Python 2 support in Pinax
- django-user-accounts: https://gist.github.com/mfonism/e12890d34dedc3e4de30efe2d7795184
- pinax-ratings: https://gist.github.com/mfonism/3b68ab55bb637b603c350bf8027b140c
Remove from __future__
imports
Remove Python 2 compatibility import statement and decorator(s)
python_2_unicode_compatible
Remove django.utils.six
imports
from django.utils.six.moves import cPickle as pickle
becomes import pickle
class ClassName(object):
becomes class ClassName():
super(ClassName, self)
becomes super()
Use str.format()
instead of %
formatting
Before
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__) # noqa
After
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__) # noqa
Before
import pkg_resources
__version__ = pkg_resources.get_distribution("pinax-<app>").version
After
import pkg_resources
__version__ = pkg_resources.get_distribution("pinax-<app>").version
Typically, developer tools used to test the code for production quality, such as flake8
, flake8-quotes
, and isort
are updated to their most recent versions. The dependencies that are required to run the code do not need to be updated, unless there is a problem with an included version. For example, pinax-blog has had a problem with Markdown 3.0.1
in the past (See PR 123).
In Makefile
and elsewhere, change references of detox
to tox
and tox --parallel--safe-build
. detox
was merged into tox
. (See: https://github.com/pinax/pinax/issues/143)
In the apps included in the most recent release, references to docs, documentation, and Sphinx should be gone, due to docs having been moved to README.md
s. Docs no longer need to be generated via Makefile
. This update might not have been made yet in deprecated apps.
all: init test
init:
python setup.py develop
pip install tox "coverage<5"
test:
coverage erase
tox --parallel--safe-build
coverage html
For apps that were included in the 18.01 release, the existing .circleci/config.yml
will need to be updated. For those that weren't, any existing .travis.yml
will need to be deleted and a .circleci/config.yml
will need to be created.
Move all dependencies to the same section
command: pip install --user tox codecov "coverage<5"
Note - v2-deps-
is used if checksum fails, therefore is not a typo.
version: 2.1
common: &common
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- v2-deps-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }}
- v2-deps-
- run:
name: install dependencies
command: pip install --user tox codecov "coverage<5"
- run:
name: run tox
command: ~/.local/bin/tox
- run:
name: upload coverage report
command: |
if [[ "$UPLOAD_COVERAGE" != 0 ]]; then
PATH=$HOME/.local/bin:$PATH
coverage xml
~/.local/bin/codecov --required -X search gcov pycov -f coverage.xml --flags $CIRCLE_JOB
fi
- save_cache:
paths:
- .tox
- ~/.cache/pip
- ~/.local
- ./eggs
key: v2-deps-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.py" }}-{{ checksum "tox.ini" }}
jobs:
lint:
<<: *common
docker:
- image: circleci/python:3.8
environment:
- TOXENV=checkqa
- UPLOAD_COVERAGE=0
py36dj22:
<<: *common
docker:
- image: circleci/python:3.6
environment:
TOXENV=py36-dj22
py36dj30:
<<: *common
docker:
- image: circleci/python:3.6
environment:
TOXENV=py36-dj30
py37dj22:
<<: *common
docker:
- image: circleci/python:3.7
environment:
TOXENV=py37-dj22
py37dj30:
<<: *common
docker:
- image: circleci/python:3.7
environment:
TOXENV=py37-dj30
py38dj22:
<<: *common
docker:
- image: circleci/python:3.8
environment:
TOXENV=py38-dj22
py38dj30:
<<: *common
docker:
- image: circleci/python:3.8
environment:
TOXENV=py38-dj30
workflows:
version: 2
test:
jobs:
- lint
- py36dj22
- py36dj30
- py37dj22
- py37dj30
- py38dj22
- py38dj30
Update tox.ini
files with current supported versions matrix info.
This configuration performs testing on Python 3.6, 3.7, and 3.8 alongside Django 2.2 and 3.0.
In the example, flake8
, flake8-quotes
, and isort
have been updated to most recent versions.
isort
is required for automated import sorting and flake8-quotes
for enforcing double quote standard.
Note: coverage is pinned as coverage<5
(also in Makefile
and CircleCI config.yml
) due to a Python 3.6.0
bug (See: https://github.com/nedbat/coveragepy/issues/703).
Also, look for instances of six
in known_third_party
. six
is deprecated now.
Sometimes, after the tox
config has been changed, or the app has been updated, the imports might need to be resorted. You will know because tox
will give you a qa
error telling you this. The command to sort the imports is below. After re-sorting, commit the changes and push them to your branch.
isort --recursive pinax -sp tox.ini
# tox.ini
[flake8]
ignore = E265,E501,W504
max-line-length = 100
max-complexity = 10
exclude = **/*/migrations/*
inline-quotes = double
[isort]
multi_line_output=3
known_django=django
known_third_party=account,appconf,pinax
sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
include_trailing_comma=True
skip_glob=**/*/migrations/*
[coverage:run]
source = pinax
omit = **/*/conf.py,**/*/tests/*,**/*/migrations/*,**/*/admin.py
branch = true
data_file = .coverage
[coverage:report]
omit = **/*/conf.py,**/*/tests/*,**/*/migrations/*,**/*/admin.py
exclude_lines =
coverage: omit
show_missing = True
[tox]
envlist =
checkqa,
py{36,37,38}-dj{22,30}
[testenv]
passenv = CI CIRCLECI CIRCLE_*
deps =
coverage<5
codecov
dj22: Django>=2.2,<3.0
dj30: Django>=3.0,<3.1
master: https://github.com/django/django/tarball/master
usedevelop = True
commands =
coverage run setup.py test
coverage report -m --skip-covered
[testenv:checkqa]
commands =
flake8 pinax
isort --recursive --check-only --diff pinax -sp tox.ini
deps =
flake8 == 3.7.9
flake8-quotes == 2.1.1
isort == 4.3.21
Dependencies do not need to be updated, unless there is a problem with an included version.
Note the [isort]
- known_third_party
section should contain appropriate app names for every application listed in setup.py
install_requires
section. This snippet from setup.py
is appropriate for the tox.ini
above:
# setup.py
setup(
# other settings
install_requires=[
"django-appconf>=1.0.2",
"django-user-accounts>=2.1.0",
],
)
The coverage.py
configs can be consolidated into the tox.ini
file. The .coveragerc
file can then be removed, because coverage.py
can read from the tox.ini
file (See: https://coverage.readthedocs.io/en/coverage-4.4.2/config.html). Otherwise, we have some duplicate info within .coveragerc
and tox.ini
files.
We would need to ensure that the tox.ini
includes any relevant info that is only in the .coveragerc
files, specifically, all of the omitted paths. This will primarily involve the admin.py
path (See .coveragerc
example below). Note: branch = true
and branch = 1
are both Boolean values (See: https://coverage.readthedocs.io/en/v4.5.x/config.html#syntax)
For simplicity sake, every tox
file contains admin.py
, even those in apps that do not contain admin.py
.
Note: the omit
syntax is slightly different depending on whether it's in the .coveragerc
or tox.ini
.
app
refers to the name of the app
[run]
source = pinax
omit = pinax/app/tests/*,pinax/app/admin.py
branch = 1
[report]
omit = pinax/app/tests/*,pinax/app/admin.py
When Python 2 support dropped, apparently the universal wheel syntax can be removed from the setup.cfg
and a pure Python wheel used instead (See the PyPi Sample Project or Packaging Tutorial Wheels section for more info). That is, if a setup.cfg
is needed at all.
With universal wheel syntax:
[bdist_wheel]
universal=1
The MANIFEST.in
should include:
include AUTHORS
include LICENSE
include README.md
The MANIFEST.in
could include any of the following lines, depending upon if that folder is included in the app:
recursive-include pinax/<app>/locale *
recursive-include pinax/<app>/static *
recursive-include pinax/<app>/templates *
Apps included in the last release should already have an up-to-date .gitignore
. Before updating a .gitignore
, take a moment to check that you are not removing anything important in the process.
Possible addition: VSCode
Note: pinax-images .gitignore
includes additional info
MANIFEST
.DS_Store
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
docs/_build/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
*.eggs
.python-version
# Pipfile
Pipfile
Pipfile.lock
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coveragerc
.cache
nosetests.xml
coverage.xml
# IDEs
.idea/
Update version based on SemVer
VERSION = "0.0"
Update supported versions matrix
Supported Django and Python Versions
------------------------------------
+-----------------+-----+-----+-----+
| Django / Python | 3.6 | 3.7 | 3.8 |
+=================+=====+=====+=====+
| 2.2 | * | * | * |
+-----------------+-----+-----+-----+
| 3.0 | * | * | * |
+-----------------+-----+-----+-----+
A previous app release had a typo in the email address; fix the typo
author_email="team@pinaxproject.com",
install_requires=[
"django>=2.2",
],
tests_require=[
],
Not all apps are in "Development Status :: 5 - Production/Stable"
; Avoid accidentally changing development status when copying and pasting.
classifiers=[
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Framework :: Django",
"Framework :: Django :: 2.2",
"Framework :: Django :: 3.0",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Topic :: Software Development :: Libraries :: Python Modules",
],
A few apps contain a "Publish Helper" in the setup.py; this should be removed in favor of a standard approach across all app repos, perhaps the GitHub Action to auto-publish to PyPI.
# Publish Helper.
if sys.argv[-1] == 'publish':
os.system('python setup.py sdist bdist_wheel upload')
sys.exit()
The version number should be updated in setup.py
, if not already. This version number should be noted in the README.md
Change Log, including updates made (these will go in the release notes when tagging to publish) and PR/issue links, if applicable. The supported versions matrices should also be updated in the setup.py
and README.md
.
"Versions" should be capitalized in this Table of Contents entry and heading
* [Supported Django and Python Versions](#supported-django-and-python-versions)
#### Supported Django and Python Versions
Add Important Links
section to Table of Contents and README.md body.
* [About Pinax](#about-pinax)
* [Important Links](#important-links)
## Important Links
Where you can find what you need:
* Releases: published to [PyPI](https://pypi.org/search/?q=pinax) or tagged in app repos in the [Pinax GitHub organization](https://github.com/pinax/)
* Global documentation: [Pinax documentation website](https://pinaxproject.com/pinax/)
* App specific documentation: app repos in the [Pinax GitHub organization](https://github.com/pinax/)
* Support information: [SUPPORT.md](https://github.com/pinax/.github/blob/master/SUPPORT.md) file in the [Pinax default community health file repo](https://github.com/pinax/.github/)
* Contributing information: [CONTRIBUTING.md](https://github.com/pinax/.github/blob/master/CONTRIBUTING.md) file in the [Pinax default community health file repo](https://github.com/pinax/.github/)
* Current and historical release docs: [Pinax Wiki](https://github.com/pinax/pinax/wiki/)
Optionally, if a pinax-app is included in an exemplary demo, a link to that demo can be added to the app's README.md Overview
section (Example: https://github.com/pinax/pinax-calendars/blob/master/README.md#overview)
I have considered adding a dedicated App Demo
section. A link in the README.md
would lead to the exemplary demo the app is included in.
Django / Python | 3.6 | 3.7 | 3.8 |
---|---|---|---|
2.2 | * | * | * |
3.0 | * | * | * |
Update Contribute
section to point to community health file repo
## Contribute
[Contributing](https://github.com/pinax/.github/blob/master/CONTRIBUTING.md) information can be found in the [Pinax community health file repo](https://github.com/pinax/.github).
Update Code of Conduct link to point to community health file repo
## Code of Conduct
In order to foster a kind, inclusive, and harassment-free community, the Pinax Project has a [Code of Conduct](https://github.com/pinax/.github/blob/master/CODE_OF_CONDUCT.md). We ask you to treat everyone as a smart human programmer that shares an interest in Python, Django, and Pinax with you.
## Change Log Blurb
* Drop Django 1.11, 2.0, and 2.1, and Python 2,7, 3.4, and 3.5 support
* Add Django 2.2 and 3.0, and Python 3.6, 3.7, and 3.8 support
* Update packaging configs
* Direct users to community resources
The MIT License (MIT)
Copyright (c) 2012-present James Tauber and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Update README.md entry as well.
## License
Copyright (c) 2012-present James Tauber and contributors under the [MIT license](https://opensource.org/licenses/MIT).
CONTRIBUTING.md
will be deleted from individual repos.
(See script and follow up post by @mfonism in issue "Standardize AUTHORS Files and Automate Adding Authors")
Windows OS repo_path
example:
repo_path = r"C:/Users/Mfonism/Codeville/OSSDjango/Pinax/pinax-likes"
Mac OS repo_path
example:
repo_path = r"/Users/katherinemichel/pinax-forums"
Some apps should have templates and are missing them. Some templates that should be in pinax-templates are still in individual apps. Add or move templates when possible.
If templates are added to pinax-templates, add the standard pinax-templates blurb to the README.md
of the app the templates belong to.
Apps that do not include URLs need not have a test directory urls.py
file or a ROOT_URLCONF="pinax.<app>.tests.urls",
setting in the runtests.py
file.
A few apps are still missing test coverage.
Increase test coverage to > 80, where needed.
- Badges in correct order (including any new/missing one(s)), and rendering properly
- Correct
setup.py
variables - Updated supported versions matrix (Also in
README.md
) - Improved features descriptions, if possible (Also in
README.md
) - Updated Pinax team email in
setup.py
(team@pinaxproject.com not team@pinaxprojects.com) (See: https://github.com/pinax/pinax/issues/139) - If needed, updated classifiers
install_requires
andtests_require
- Updated classifiers
Table of Contents
- About Pinax
- Important Links
- Overview
- Features
- Dependencies (if applicable)
- Supported Django and Python Versions
- Documentation
- Installation
- Usage
- Templates (if applicable)
- Change Log
- History (if applicable)
- Contribute
- Code of Conduct
- Connect with Pinax
- License
-
README.md
organized into standard PinaxREADME.md
layout (See: pinax-announcements README) - Verify app name is correct throughout
README.md
(usually pinax-) - Table of contents, in correct order, with no deadlinks
- Patch, if it exists; if not, make one (Patrick has created these in the past)
- Badges in correct order (including any new/missing one(s)), and rendering properly
- Standard
About Pinax
,Contribute
,Code of Conduct
,Connect with Pinax
, andLicense
sections - Improved features descriptions, if possible (Also in
setup.py
) - Updated supported versions matrix (Also in
setup.py
; See: supported versions matrix example) - Updated dependencies information
- Accurate installation instructions
- Docs moved to
README.md
(For apps included in the latest release,README.rst
files should have already been converted intoREADME.md
files, with theMANIFEST.in
reflecting the new file name ending.) - Improved usage docs
- If templates have been added or moved to pinax-templates, a standard pinax-templates blurb should have been added to
README.md
of the app the templates belong to - Accurate
Change Log
- If applicable,
History
section that provides special project/app history - Accurate code-fencing across
README.md
s (See: code-fencing example; spacing varies amongREADME.md
s) - Lack of typos
Code-fence all code examples with these common language names: shell
, python
, and django
in order to get syntax highlighting. Use django
for templates, Github will syntax highlight correctly.
```shell
$ pip install pinax-eventlog
```
produces
$ pip install pinax-eventlog
```python
# myapp/apps.py from django.apps import AppConfig from django.db.models.signals import post_migrate from myapp.signals import handlers class MyAppConfig(AppConfig): name = 'myapp' verbose_name = 'My App' def ready(self): post_migrate.connect(handlers.create_notice_types, sender=self)
```
produces
# myapp/apps.py
from django.apps import AppConfig
from django.db.models.signals import post_migrate
from myapp.signals import handlers
class MyAppConfig(AppConfig):
name = 'myapp'
verbose_name = 'My App'
def ready(self):
post_migrate.connect(handlers.create_notice_types, sender=self)
```django
{% testimonials as quotes %} {% for quote in quotes %} <p class="lead"> {{quote.text}} {{quote.author}} </p> {% endfor %}
```
produces
{% testimonials as quotes %}
{% for quote in quotes %}
<p class="lead">
{{quote.text}}
{{quote.author}}
</p>
{% endfor %}
By dropping Django 2.0, we will be able to remove from the Pinax Starter Projects if/else statements that complicate the code.
from django.conf import settings
from django.contrib import admin
{% if django_version < "2" %}from django.conf.urls import include, url{% endif %}
from django.conf.urls.static import static
{% if django_version >= "2" %}from django.urls import include, path{% endif %}
from django.views.generic import TemplateView
urlpatterns = [{% if django_version >= "2" %}
path("", TemplateView.as_view(template_name="homepage.html"), name="home"),
path("admin/", admin.site.urls),
path("account/", include("account.urls")),
{% else %}
url(r"^$", TemplateView.as_view(template_name="homepage.html"), name="home"),
url(r"^admin/", admin.site.urls),
url(r"^account/", include("account.urls")),
{% endif %}]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)