diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 93a4de2..42144b9 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -15,10 +15,11 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - # python-version: [3.7, 3.8, 3.9] - # django-version: [2.2, 3.0] - python-version: [3.9] - django-version: [3.2] + python-version: ['3.6', '3.9'] + django-version: ['3.2.10', '4.0'] + exclude: + - django-version: '4.0' + python-version: '3.6' steps: - uses: actions/checkout@v2 @@ -37,6 +38,6 @@ jobs: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest + - name: Run tests run: | - pytest + coverage run --parallel --source watchman runtests.py diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5b35843..0000000 --- a/.travis.yml +++ /dev/null @@ -1,46 +0,0 @@ -dist: xenial -language: python - -python: - - "3.8" - - "3.7" - - "3.6" - - "3.5" - -env: - matrix: - - DJANGO_VERSION=2.2 - - DJANGO_VERSION=3.0 - -matrix: - exclude: - - python: "3.5" - env: DJANGO_VERSION=3.0 - -install: - - pip install tox coveralls - -# command to run tests using coverage, e.g. python setup.py test -script: - - tox -e py${TRAVIS_PYTHON_VERSION//./}-dj${DJANGO_VERSION//./},coverage - -# report coverage to coveralls.io -after_success: coveralls - -notifications: - slack: tobalabs:XPt5OlsKuFGgIQZp0DpNXBUl - -jobs: - include: - - stage: pypi release - if: tag IS present - python: "3.7" - script: echo "Deploying to pypi ..." - deploy: - provider: pypi - user: mwarkentin - password: - secure: "cQtAP8fMu+KzfBKG3ibTTXmDGZuz/FBp8RrLI8ddMGV4Jj5ElZLsvbqU43fiHbtVPV/uALDPF76WNGlpRH1P4w9m4XrFNCvkrnjtwIk7NZWi7uubWZcqQk9VE7MTP+i2IYrtNlGmlq1dbdJZcwS0mdzJcAAhAaP830Ekmqws9xE=" - distributions: "sdist bdist_wheel" - on: - tags: true diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3e0c649..5d2c2c9 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -74,21 +74,15 @@ Ready to contribute? Here's how to set up `django-watchman` for local developmen a. Now you can make your changes locally. -5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:: - - $ flake8 watchman tests - $ python setup.py test - $ tox - - a. To get flake8 and tox, just pip install them into your virtualenv. - -6. Commit your changes and push your branch to GitHub:: +5. Commit your changes and push your branch to GitHub:: $ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature -7. Submit a pull request through the GitHub website. +6. Submit a pull request through the GitHub website. + +7. Make sure that tests are passing in Github Actions Pull Request Guidelines ----------------------- @@ -99,9 +93,8 @@ Before you submit a pull request, check that it meets these guidelines: 2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst. -3. The pull request should work for Python 2.6, 2.7, and 3.3, and for PyPy. Check - https://travis-ci.org/mwarkentin/django-watchman/pull_requests - and make sure that the tests pass for all supported Python versions. +3. The pull request should work for Python 3.6 and 3.10. Check the Github + Actions and make sure that the tests pass for all supported Python versions. Tips ---- diff --git a/Makefile b/Makefile index d1e98c8..da04798 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,10 @@ -.PHONY: help clean clean-build clean-pyc lint test test-all coverage docs release dist run +.PHONY: help clean clean-build clean-pyc lint test docs release dist run help: @echo "clean-build - remove build artifacts" @echo "clean-pyc - remove Python file artifacts" @echo "lint - check PEP8 style with flake8, and rst with rst-lint" @echo "test - run tests quickly with the default Python" - @echo "testall - run tests on every Python version with tox" @echo "coverage - check code coverage quickly with the default Python" @echo "docs - generate Sphinx HTML documentation, including API docs" @echo "release - package and upload a release" @@ -29,16 +28,7 @@ lint: rst-lint *.rst test: - python runtests.py - -test-all: - tox - -coverage: - coverage run --source watchman runtests.py - coverage report -m - coverage html - open htmlcov/index.html + act --job build docs: rm -f docs/watchman.rst diff --git a/README.rst b/README.rst index 8ed7199..3876e82 100644 --- a/README.rst +++ b/README.rst @@ -5,9 +5,6 @@ django-watchman .. image:: http://img.shields.io/pypi/v/django-watchman.svg :target: http://badge.fury.io/py/django-watchman -.. image:: http://img.shields.io/travis/mwarkentin/django-watchman/master.svg - :target: https://travis-ci.org/mwarkentin/django-watchman - .. image:: http://img.shields.io/coveralls/mwarkentin/django-watchman.svg :target: https://coveralls.io/r/mwarkentin/django-watchman?branch=master diff --git a/RELEASING.rst b/RELEASING.rst index b79d8f2..77582cd 100644 --- a/RELEASING.rst +++ b/RELEASING.rst @@ -2,7 +2,7 @@ Releasing ========= -Releases are created via Travis or uploaded locally using `twine `_. +Releases are created via Github Actions (soon: https://github.com/mwarkentin/django-watchman/issues/177) or uploaded locally using `twine `_. When the release is ready to go: @@ -12,12 +12,10 @@ When the release is ready to go: * Push tag: ``git push origin 1.0.0`` * Create a release from the tag on Github -Travis will run the full test suite and deploy to pypi in a separate stage if everything passes. - Local fallback ~~~~~~~~~~~~~~ -If Travis isn't available or working for releases for some reason, you can use `twine`_ to upload the release. +If Github Actions isn't available or working for releases for some reason, you can use `twine`_ to upload the release. * Install and configure `twine`_ * Check dist locally: ``make dist`` diff --git a/requirements-test.txt b/requirements-test.txt index 54b5c15..7ea3e04 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -4,4 +4,3 @@ django-nose>=1.2 flake8>=2.1.0 restructuredtext_lint==0.12.2 mysqlclient>=1.3.13 -tox>=1.7.0 diff --git a/runtests.py b/runtests.py index 157243e..4c0183e 100644 --- a/runtests.py +++ b/runtests.py @@ -28,6 +28,7 @@ ], SITE_ID=1, NOSE_ARGS=['-s'], + SECRET_KEY="ABCD1234" ) from django_nose import NoseTestSuiteRunner diff --git a/tests/test_views.py b/tests/test_views.py index 9060b2c..fee41b0 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -84,14 +84,13 @@ def test_response_contains_expected_checks(self): def test_check_database_handles_exception(self): response = checks._check_database('foo') self.assertFalse(response['foo']['ok']) - self.assertEqual(response['foo']['error'], "The connection foo doesn't exist") + self.assertEqual(response['foo']['error'], "The connection 'foo' doesn't exist.") def test_check_cache_handles_exception(self): - expected_error = "Could not find config for 'foo' in settings.CACHES" response = checks._check_cache('foo') self.assertFalse(response['foo']['ok']) - self.assertIn(response['foo']['error'], expected_error) + self.assertIn(response['foo']['error'], "The connection 'foo' doesn't exist.") def test_response_skipped_checks(self): expected_checks = ['caches', 'storage', ] @@ -278,48 +277,6 @@ def test_default_error_code(self, patched_check_databases): self.assertEqual(response.status_code, 500) -class TestDBError(TransactionTestCase): - """ - Ensure that we produce a valid response even in case of database - connection issues with `ATOMIC_REQUESTS` enabled. - - Since overriding `DATABASES` isn't officially supported we need to perform - some gymnastics here to convince django. - """ - def setUp(self): - # Cache current database connections - self.databases = copy(connections._databases) - self.connection = getattr(connections._connections, DEFAULT_DB_ALIAS, None) - del connections.__dict__['databases'] # remove cached_property value - connections._databases = None - connections._connections = local() - - def tearDown(self): - # Restore previous database connections - connections._databases = self.databases - setattr(connections._connections, DEFAULT_DB_ALIAS, self.connection) - del connections.__dict__['databases'] # remove cached_property value - - @override_settings( - DATABASES={ - 'default': { - "ENGINE": "django.db.backends.mysql", - "HOST": "no.host.by.this.name.some-tld-that-doesnt-exist", - "ATOMIC_REQUESTS": True - }, - } - ) - # can't use override_settings because of - # https://github.com/mwarkentin/django-watchman/issues/13 - @patch('watchman.settings.WATCHMAN_ERROR_CODE', 201) - def test_db_error_w_atomic_requests(self): - # Ensure we don't trigger django's generic 500 page in case of DB error - response = Client().get('/', data={ - 'check': 'watchman.checks.databases', - }) - self.assertEqual(response.status_code, 201) - - class TestWatchmanDashboard(unittest.TestCase): def setUp(self): # Ensure that every test executes with separate settings diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 4079be8..0000000 --- a/tox.ini +++ /dev/null @@ -1,27 +0,0 @@ -[tox] -envlist = - covclean, - py{36,37,38}-dj{22,30}, - py{35}-dj22, - coverage - -[testenv] -setenv = - PYTHONPATH = {toxinidir}:{toxinidir}/watchman -commands = coverage run --parallel --source watchman runtests.py {posargs} -deps = - dj22: Django>=2.2,<2.3 - dj30: Django>=3.0,<3.1 - -r{toxinidir}/requirements-test.txt - -[testenv:covclean] -skip_install=True -deps = coverage>=4.0 -commands = coverage erase - -[testenv:coverage] -skip_install=True -deps = coverage>=4.0 -commands = - coverage combine - coverage report --show-missing diff --git a/watchman/views.py b/watchman/views.py index f30c8c9..f18fef0 100644 --- a/watchman/views.py +++ b/watchman/views.py @@ -6,7 +6,7 @@ from django.db.transaction import non_atomic_requests from django.http import JsonResponse, HttpResponse from django.shortcuts import render -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from watchman import __version__, settings from watchman.decorators import auth from watchman.utils import get_checks