diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..fa096ed --- /dev/null +++ b/.coveragerc @@ -0,0 +1,9 @@ +[run] +branch = True +source = tjdests +omit = + */migrations/* + */apps.py + */urls.py + */wsgi.py + */routing.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6df5365 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,3 @@ +# WARNING: Do not edit this file manually! Edit ci/spec.yml and run ci/regen-workflow.py. + +{"name": "CI", "on": ["push", "pull_request"], "defaults": {"run": {"shell": "bash"}}, "jobs": {"lint": {"runs-on": "ubuntu-latest", "strategy": {"matrix": {"python-version": [3.9]}}, "steps": [{"name": "Set up repo", "uses": "actions/checkout@v2"}, {"name": "Set up Python ${{ matrix.python-version }}", "uses": "actions/setup-python@v2", "with": {"python-version": "${{ matrix.python-version }}"}}, {"name": "Set up pip cache", "uses": "actions/cache@v2", "with": {"path": "~/.cache/pip\n~/.cache/pipenv\n", "key": "${{ matrix.python-version }}"}}, {"name": "Set up venv", "run": "set -e\npip install pipenv\npipenv install --dev --deploy\n"}, {"name": "Check formatting with format.sh", "run": "set -e\npipenv run ./scripts/format.sh\necho \"A failure means that you did not run format.sh\"\ntest -z \"$(git status --porcelain=v1 .)\"\n"}, {"name": "Check formatting with check.sh", "run": "pipenv run ./scripts/check.sh"}]}, "test": {"runs-on": "ubuntu-latest", "strategy": {"matrix": {"python-version": [3.9]}}, "steps": [{"name": "Set up repo", "uses": "actions/checkout@v2"}, {"name": "Set up Python ${{ matrix.python-version }}", "uses": "actions/setup-python@v2", "with": {"python-version": "${{ matrix.python-version }}"}}, {"name": "Set up pip cache", "uses": "actions/cache@v2", "with": {"path": "~/.cache/pip\n~/.cache/pipenv\n", "key": "${{ matrix.python-version }}"}}, {"name": "Set up venv", "run": "set -e\npip install pipenv\npipenv install --dev --deploy\n"}, {"name": "Run test suite", "run": "pipenv run coverage run ./manage.py test"}, {"name": "Report coverage to Coveralls", "uses": "AndreMiras/coveralls-python-action@develop", "with": {"parallel": true}}]}, "finish_success": {"needs": ["lint", "test"], "runs-on": "ubuntu-latest", "steps": [{"name": "Tell Coveralls that parallel jobs have finished", "uses": "coverallsapp/github-action@master", "with": {"github-token": "${{ secrets.GITHUB_TOKEN }}", "parallel-finished": true}}]}}} \ No newline at end of file diff --git a/Pipfile b/Pipfile index d974d5a..37d08b3 100644 --- a/Pipfile +++ b/Pipfile @@ -11,9 +11,9 @@ django-crispy-forms = "~=1.11.2" django-extensions = "~=3.1.2" gunicorn = "~=20.1.0" ipython = "~=7.22.0" +psycopg2 = "~=2.8.6" social-auth-app-django = "~=4.0.0" whitenoise = "~=5.2.0" -psycopg2 = "~=2.8.6" [dev-packages] autopep8 = "~=1.5.6" @@ -25,6 +25,7 @@ isort = "~=5.8.0" mypy = "~=0.812" pylint = "~=2.7.4" pylint-django = "~=2.4.2" +pyyaml = "~=5.4.1" typed-ast = "~=1.4.2" # Required by black, but Pipenv doesn't pull it in correctly on 3.8 [requires] diff --git a/Pipfile.lock b/Pipfile.lock index a738288..ed347a8 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c84b644774fb934b60adfeb23eb60dac86249c2fd547e3d495dc33130a5d029b" + "sha256": "7acf3652f76921f8340efd0ee531ac934a859593802eb992ac75a380518057e9" }, "pipfile-spec": 6, "requires": { @@ -646,6 +646,41 @@ ], "version": "==2021.1" }, + "pyyaml": { + "hashes": [ + "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", + "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", + "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", + "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", + "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", + "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", + "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", + "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", + "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", + "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", + "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", + "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", + "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", + "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", + "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", + "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", + "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", + "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", + "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", + "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", + "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", + "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", + "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", + "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", + "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", + "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", + "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", + "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", + "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" + ], + "index": "pypi", + "version": "==5.4.1" + }, "regex": { "hashes": [ "sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5", diff --git a/ci/regen-workflow.py b/ci/regen-workflow.py new file mode 100755 index 0000000..5c012b0 --- /dev/null +++ b/ci/regen-workflow.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +import os +import sys +import json + +try: + import yaml +except ImportError: + sys.exit("Please install pyyaml. (In some package managers, this is called python-yaml or python3-yaml.)") + +# Why is this script necessary? Well, the different jobs run in the CI build have a lot of shared steps. +# To avoid duplication, the CI YAML file relies on a lot of anchors (look up "YAML anchors" for details) to +# riuse pieces of information +# Unfortunately, GitHub does not support YAML anchors in workflow files: +# https://github.community/t/support-for-yaml-anchors/16128/33 +# The only way to get it to work is to have an intermediary script like this. + +repo_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + +with open(os.path.join(repo_dir, "ci/spec.yml")) as f: + loader = yaml.SafeLoader(f) + + loader.bool_values = dict(yaml.SafeLoader.bool_values) + # GitHub Actions has an "on" key that gets translated to 'true' without this. + loader.bool_values.update({"on": "on"}) + + ci_spec = loader.get_single_data() + +ci_spec.pop(".anchors", None) + +with open(os.path.join(repo_dir, ".github/workflows/ci.yml"), "w") as f: + f.write("# WARNING: Do not edit this file manually! Edit ci/spec.yml and run ci/regen-workflow.py.\n\n") + + json.dump(ci_spec, f) \ No newline at end of file diff --git a/ci/spec.yml b/ci/spec.yml new file mode 100644 index 0000000..f2b98a2 --- /dev/null +++ b/ci/spec.yml @@ -0,0 +1,92 @@ +name: CI +on: [push, pull_request] + +defaults: + run: + shell: bash + +.anchors: + python_versions: &python_versions + - 3.9 + + python_setup: &python_setup + name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + repo_setup: &repo_setup + name: Set up repo + uses: actions/checkout@v2 + + setup_pip_cache: &setup_pip_cache + name: Set up pip cache + uses: actions/cache@v2 + with: + path: | + ~/.cache/pip + ~/.cache/pipenv + key: ${{ matrix.python-version }} + + setup_venv: &setup_venv + name: Set up venv + run: | + set -e + pip install pipenv + pipenv install --dev --deploy +jobs: + lint: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: *python_versions + + steps: + - *repo_setup + - *python_setup + - *setup_pip_cache + - *setup_venv + + - name: Check formatting with format.sh + run: | + set -e + pipenv run ./scripts/format.sh + echo "A failure means that you did not run format.sh" + test -z "$(git status --porcelain=v1 .)" + + - name: Check formatting with check.sh + run: pipenv run ./scripts/check.sh + + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: *python_versions + + steps: + - *repo_setup + - *python_setup + - *setup_pip_cache + - *setup_venv + + - name: Run test suite + run: pipenv run coverage run ./manage.py test + + - name: Report coverage to Coveralls + uses: AndreMiras/coveralls-python-action@develop + with: + parallel: true + + finish_success: + needs: + - lint + - test + + runs-on: ubuntu-latest + + steps: + - name: Tell Coveralls that parallel jobs have finished + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true \ No newline at end of file