Skip to content

Pinax 20.XX Release Plan

KatherineMichel edited this page Jul 21, 2020 · 16 revisions

Table of Contents

High Level Release Process

For info about our high level release process, read the RELEASE.md file in the Pinax Default Community Health File Repo.

Release Overviews

Pinax 18.01 Release Overview

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:

Pinax 20.XX Release Overview

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.

Community Plan

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 Updates

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.

pinax-cli Updates

App Repo File Tree

Old Pinax App Repo File Tree

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

New Pinax App Repo File Tree

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

App Updates- Must Have

Drop and Add Support for Python and Django Versions

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

Python 2/3 Compatibility

Remove from __future__ imports

Remove Python 2 compatibility import statement and decorator(s)

python_2_unicode_compatible

six

Remove django.utils.six imports

from django.utils.six.moves import cPickle as pickle becomes import pickle

Django

Class Definition

class ClassName(object): becomes class ClassName():

super

super(ClassName, self) becomes super()

Exceptions

String Formatting

Use str.format() instead of % formatting

Fix Linting

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

A Note About Tool and Dependency Versions

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).

Update Makefile

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.mds. 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

Create or Update CircleCI config.yml

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

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

Update Third-Party Dependencies

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",
    ],
)

Commonly Included Dependencies

Remove .coveragerc

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

Remove setup.cfg

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

Update MANIFEST.in

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 *

Update .gitignore

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 setup.py

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()

Update Version Number, Supported Versions Matrix, and Change Log

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.

Small Typo Fix

"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

Update README.md

Important Links README.md Blurb

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/)

Demo

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.

Supported Django and Python Versions README.md Matrix

Django / Python 3.6 3.7 3.8
2.2 * * *
3.0 * * *

Contribute README.md Blurb

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).

Code of Conduct README.md Blurb

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 README.md Blurb

## 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

Update Standard License

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).

Remove CONTRIBUTING.md

CONTRIBUTING.md will be deleted from individual repos.

Automate Adding Authors to AUTHORS File

(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"

App Updates- Nice to Have

Update Templates

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.

Add Smoke Tests

Update Unit Tests

Test URLs

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.

Add Unit Tests

A few apps are still missing test coverage.

Increase Test Coverage

Increase test coverage to > 80, where needed.

Reference

setup.py Checklist

  • 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 and tests_require
  • Updated classifiers

Standard README.md Table of Contents

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 Checklist

  • README.md organized into standard Pinax README.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, and License 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 into README.md files, with the MANIFEST.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.mds (See: code-fencing example; spacing varies among README.mds)
  • Lack of typos

Code-Fencing Examples

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

```shell
$ pip install pinax-eventlog
```

produces

$ pip install pinax-eventlog

python

```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

```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 %}

Dropping Django 2.0 Support in Pinax Starter Projects

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)
Clone this wiki locally