Contributing¶
Summary¶
PRs welcome!
- Consider starting a discussion to see if there's interest in what you want to do.
- Submit PRs from feature branches on forks to the
develop
branch. - Ensure PRs pass all CI checks.
- Maintain test coverage at 100%.
Git¶
- Why use Git? Git enables creation of multiple versions of a code repository called branches, with the ability to track and undo changes in detail.
- Install Git by downloading from the website, or with a package manager like Homebrew.
- Configure Git to connect to GitHub with SSH.
- Fork this repo.
- Create a branch in your fork.
- Commit your changes with a properly-formatted Git commit message.
- Create a pull request (PR) to incorporate your changes into the upstream project you forked.
Code quality¶
Code style¶
- Python code is formatted with Black. Configuration for Black is stored in pyproject.toml.
- Python imports are organized automatically with isort.
- The isort package organizes imports in three sections:
- Standard library
- Dependencies
- Project
- Within each of those groups,
import
statements occur first, thenfrom
statements, in alphabetical order. - You can run isort from the command line with
poetry run isort .
. - Configuration for isort is stored in pyproject.toml.
- The isort package organizes imports in three sections:
- Other web code (JSON, Markdown, YAML) is formatted with Prettier.
Static type checking¶
- Mypy is used for type-checking.
- To learn type annotation basics, see this gist and the Real Python type checking tutorial.
Pre-commit¶
Pre-commit runs Git hooks. Configuration is stored in .pre-commit-config.yaml. It can run locally before each commit (hence "pre-commit"), or on different Git events like pre-push
. Pre-commit is installed in the Poetry environment. To use:
# after running `poetry install`
path/to/fastenv
❯ poetry shell
# install hooks that run before each commit
path/to/fastenv
.venv ❯ pre-commit install
# and/or install hooks that run before each push
path/to/fastenv
.venv ❯ pre-commit install --hook-type pre-push
Python¶
Poetry¶
This project uses Poetry for dependency management.
Install project with all dependencies: poetry install -E all
.
Highlights¶
- Automatic virtual environment management: Poetry automatically manages the
virtualenv
for the application. - Automatic dependency management: rather than having to run
pip freeze > requirements.txt
, Poetry automatically manages the dependency file (called pyproject.toml), and enables SemVer-level control over dependencies like npm. Poetry also manages a lockfile (called poetry.lock), which is similar to package-lock.json for npm. Poetry uses this lockfile to automatically track specific versions and hashes for every dependency. - Dependency resolution: Poetry will automatically resolve any dependency version conflicts. pip did not have dependency resolution until the end of 2020.
- Dependency separation: Poetry can maintain separate lists of dependencies for development and production in the pyproject.toml. Production installs can skip development dependencies for speed.
- Builds: Poetry has features for easily building the project into a Python package.
Installation¶
The recommended installation method is through the Poetry custom installer, which vendorizes dependencies into an isolated environment, and allows you to update Poetry with poetry self update
.
You can also install Poetry however you prefer to install your user Python packages (pipx install poetry
, pip install --user poetry
, etc). Use the standard update methods with these tools (pipx upgrade poetry
, pip install --user --upgrade poetry
, etc).
Key commands¶
# Basic usage: https://python-poetry.org/docs/basic-usage/
poetry install # create virtual environment and install dependencies
poetry show --tree # list installed packages
poetry add PACKAGE@VERSION # add package production dependencies
poetry add PACKAGE@VERSION --dev # add package to development dependencies
poetry update # update dependencies (not available with standard tools)
poetry version # list or update version of this package
poetry shell # activate the virtual environment, like source venv/bin/activate
poetry run COMMAND # run a command within the virtual environment
poetry env info # https://python-poetry.org/docs/managing-environments/
poetry config virtualenvs.in-project true # install virtualenvs into .venv
poetry export -f requirements.txt > requirements.txt --dev # export deps
Testing with pytest¶
- Tests are in the tests/ directory.
- Run tests by invoking
pytest
from the command-line within the Poetry environment in the root directory of the repo. - pytest features used include:
- pytest plugins include:
- pytest configuration is in pyproject.toml.
- Test coverage results are reported when invoking
pytest
from the command-line. To see interactive HTML coverage reports, invoke pytest withpytest --cov-report=html
. - Test coverage reports are generated within GitHub Actions workflows by pytest-cov with coverage.py, and uploaded to Codecov using codecov/codecov-action. Codecov is then integrated into pull requests with the Codecov GitHub app.
GitHub Actions workflows¶
GitHub Actions is a continuous integration/continuous deployment (CI/CD) service that runs on GitHub repos. It replaces other services like Travis CI. Actions are grouped into workflows and stored in .github/workflows. See Getting the Gist of GitHub Actions for more info.
Maintainers¶
- The default branch is
develop
. - PRs should be merged into
develop
. Head branches are deleted automatically after PRs are merged. - The only merges to
main
should be fast-forward merges fromdevelop
. - Branch protection is enabled on
develop
andmain
.develop
:- Require signed commits
- Include adminstrators
- Allow force pushes
main
:- Require signed commits
- Include adminstrators
- Do not allow force pushes
- Require status checks to pass before merging (commits must have previously been pushed to
develop
and passed all checks)
- To create a release:
- Bump the version number in
pyproject.toml
withpoetry version
and commit the changes todevelop
. - Push to
develop
and verify all CI checks pass. - Fast-forward merge to
main
, push, and verify all CI checks pass. - Create an annotated and signed Git tag
- Follow SemVer guidelines when choosing a version number.
- List PRs and commits in the tag message:
git log --pretty=format:"- %s (%h)" \ "$(git describe --abbrev=0 --tags)"..HEAD
- Omit the leading
v
(use1.0.0
instead ofv1.0.0
) - Example:
git tag -a -s 1.0.0
- Push the tag. GitHub Actions and Poetry will build the Python package and publish to PyPI.
- Bump the version number in