From 0bfbec181b6130ac42619f1ba4d06eb8428fe5ea Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Fri, 15 Mar 2019 09:22:45 +0100 Subject: [PATCH 01/13] removed django 1.10 and added py37 to the test matrix --- .travis.yml | 8 ++++---- tox.ini | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 72c8122..b81d90e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,16 @@ language: python matrix: include: - - python: 2.7 - env: TOXENV=py27-django110 - python: 2.7 env: TOXENV=py27-django111 - - python: 3.6 - env: TOXENV=py36-django110 - python: 3.6 env: TOXENV=py36-django111 + - python: 3.7 + env: TOXENV=py37-django111 - python: 3.6 env: TOXENV=py36-django2 + - python: 3.7 + env: TOXENV=py37-django2 before_cache: - rm -rf $HOME/.cache/pip/log diff --git a/tox.ini b/tox.ini index 8fd447a..7fa1554 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,11 @@ [tox] envlist = - py{27,36}-django{110, 111} - py{36}-django2 + py{27,36,37}-django111 + py{36,37}-django2 [testenv] commands = coverage run --parallel -m pytest {posargs} deps = - django110: Django>=1.10,<1.11 django111: Django>=1.11,<1.12 django2: Django>=2.0,<3 extras = test From 6300b784a13afec1fa85b51e82c5700e8c848e79 Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Fri, 15 Mar 2019 09:27:49 +0100 Subject: [PATCH 02/13] correct config for python 3.7 --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index b81d90e..6555111 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,14 @@ matrix: env: TOXENV=py36-django111 - python: 3.7 env: TOXENV=py37-django111 + dist: xenial + sudo: true - python: 3.6 env: TOXENV=py36-django2 - python: 3.7 env: TOXENV=py37-django2 + dist: xenial + sudo: true before_cache: - rm -rf $HOME/.cache/pip/log From b30aeb8c952fef57001a37d8fa8bcfd6ea8b9000 Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Fri, 15 Mar 2019 09:44:25 +0100 Subject: [PATCH 03/13] updated requirements --- setup.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index d790b3d..2db4c7a 100644 --- a/setup.py +++ b/setup.py @@ -6,15 +6,15 @@ tests_require = [ 'coverage==.4.2', - 'freezegun==0.3.9', - 'pytest==3.0.5', - 'pytest-django==3.1.2', + 'freezegun==0.3.11', + 'pytest==4.3.1', + 'pytest-django==3.4.8', # Linting - 'isort==4.2.5', - 'flake8==3.0.3', + 'isort==4.3.15', + 'flake8==3.7.7', 'flake8-blind-except==0.1.1', - 'flake8-debugger==1.4.0', + 'flake8-debugger==3.1.0', ] setup( From e04d69a445a7130cc3165837fb5ba22867993918 Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Fri, 15 Mar 2019 09:57:22 +0100 Subject: [PATCH 04/13] require django>=1.11 and updated six --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 2db4c7a..187043d 100644 --- a/setup.py +++ b/setup.py @@ -26,8 +26,8 @@ author="Lab Digital", author_email="opensource@labdigital.nl", install_requires=[ - 'Django>=1.8', - 'six>=1.1', + 'Django>=1.11', + 'six>=1.12', ], tests_require=tests_require, extras_require={ From e88e11552cd130e6ca0deffbf5bc0865b25c7b7d Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Tue, 26 Mar 2019 13:02:44 +0100 Subject: [PATCH 05/13] Fixed running local coverage --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 187043d..50f54b3 100644 --- a/setup.py +++ b/setup.py @@ -5,10 +5,11 @@ ] tests_require = [ - 'coverage==.4.2', + 'coverage==4.2', 'freezegun==0.3.11', 'pytest==4.3.1', 'pytest-django==3.4.8', + 'pytest-cov==2.6.2', # Linting 'isort==4.3.15', From d2b778dab26ef5ffcbce551e189f0fc8f2f015e0 Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Tue, 26 Mar 2019 13:07:10 +0100 Subject: [PATCH 06/13] added grace period to SESSION_EXPIRE_AFTER_LAST_ACTIVITY and formatted project using black --- Makefile | 6 ++ README.rst | 8 +++ src/django_session_timeout/__init__.py | 2 +- src/django_session_timeout/middleware.py | 16 +++-- tests/conftest.py | 23 +++---- tests/test_middleware.py | 80 +++++++++++++++++++----- 6 files changed, 100 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index a171a35..50c44f2 100644 --- a/Makefile +++ b/Makefile @@ -20,3 +20,9 @@ release: rm -rf dist/* python setup.py sdist bdist_wheel twine upload dist/* + +BLACK_EXCLUDE="/(\.git|\.hg|\.mypy_cache|\.tox|\.venv|_build|buck-out|build|dist)/" +black: + pip install --upgrade black + black --verbose --exclude $(BLACK_EXCLUDE) ./src + black --verbose --exclude $(BLACK_EXCLUDE) ./tests diff --git a/README.rst b/README.rst index d9dd042..4da1dca 100644 --- a/README.rst +++ b/README.rst @@ -52,3 +52,11 @@ To expire the session X seconds after the `last activity`, use the following set .. code-block:: python SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True + + +By default, `last activiy` will be grouped per second. +To group by different period use the following setting: + +.. code-block:: python + + SESSION_EXPIRE_AFTER_LAST_ACTIVITY_GRACE_PERIOD = 60 # group by minute diff --git a/src/django_session_timeout/__init__.py b/src/django_session_timeout/__init__.py index ffcc925..27fdca4 100644 --- a/src/django_session_timeout/__init__.py +++ b/src/django_session_timeout/__init__.py @@ -1 +1 @@ -__version__ = '0.0.3' +__version__ = "0.0.3" diff --git a/src/django_session_timeout/middleware.py b/src/django_session_timeout/middleware.py index a8dc586..d6a9e41 100644 --- a/src/django_session_timeout/middleware.py +++ b/src/django_session_timeout/middleware.py @@ -9,18 +9,19 @@ MiddlewareMixin = object -SESSION_TIMEOUT_KEY = '_session_init_timestamp_' +SESSION_TIMEOUT_KEY = "_session_init_timestamp_" class SessionTimeoutMiddleware(MiddlewareMixin): def process_request(self, request): - if not hasattr(request, 'session') or request.session.is_empty(): + if not hasattr(request, "session") or request.session.is_empty(): return init_time = request.session.setdefault(SESSION_TIMEOUT_KEY, time.time()) expire_seconds = getattr( - settings, 'SESSION_EXPIRE_SECONDS', settings.SESSION_COOKIE_AGE) + settings, "SESSION_EXPIRE_SECONDS", settings.SESSION_COOKIE_AGE + ) session_is_expired = time.time() - init_time > expire_seconds @@ -29,6 +30,11 @@ def process_request(self, request): return redirect_to_login(next=request.path) expire_since_last_activity = getattr( - settings, 'SESSION_EXPIRE_AFTER_LAST_ACTIVITY', False) - if expire_since_last_activity: + settings, "SESSION_EXPIRE_AFTER_LAST_ACTIVITY", False + ) + grace_period = getattr( + settings, "SESSION_EXPIRE_AFTER_LAST_ACTIVITY_GRACE_PERIOD", 1 + ) + + if expire_since_last_activity and time.time() - init_time > grace_period: request.session[SESSION_TIMEOUT_KEY] = time.time() diff --git a/tests/conftest.py b/tests/conftest.py index c71ff96..605428e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,23 +4,20 @@ def pytest_configure(): settings.configure( INSTALLED_APPS=[ - 'django.contrib.contenttypes', - 'django.contrib.auth', - 'django.contrib.sessions' + "django.contrib.contenttypes", + "django.contrib.auth", + "django.contrib.sessions", ], MIDDLEWARE_CLASSES=[], - ROOT_URLCONF='tests.urls', + ROOT_URLCONF="tests.urls", CACHES={ - 'default': { - 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', - 'LOCATION': 'unique-snowflake', + "default": { + "BACKEND": "django.core.cache.backends.locmem.LocMemCache", + "LOCATION": "unique-snowflake", } }, - SESSION_ENGINE='django.contrib.sessions.backends.cache', + SESSION_ENGINE="django.contrib.sessions.backends.cache", DATABASES={ - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': 'db.sqlite', - }, - } + "default": {"ENGINE": "django.db.backends.sqlite3", "NAME": "db.sqlite"} + }, ) diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 25660f9..1f14474 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -6,12 +6,12 @@ from django_session_timeout.middleware import SessionTimeoutMiddleware -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def r(rf): - req = rf.get('/') + req = rf.get("/") middleware = SessionMiddleware() middleware.process_request(req) - req.session['example_key'] = '1' + req.session["example_key"] = "1" req.session.save() yield req @@ -35,32 +35,32 @@ def test_session_expire(r, settings): settings.SESSION_EXPIRE_SECONDS = 3600 middleware = SessionTimeoutMiddleware() - with freeze_time('2017-08-31 21:46:00'): + with freeze_time("2017-08-31 21:46:00"): assert middleware.process_request(r) is None - with freeze_time('2017-08-31 22:45:00'): + with freeze_time("2017-08-31 22:45:00"): assert middleware.process_request(r) is None - with freeze_time('2017-08-31 22:46:01'): + with freeze_time("2017-08-31 22:46:01"): response = middleware.process_request(r) assert SESSION_TIMEOUT_KEY not in r.session - assert response['location'] == '/accounts/login/?next=/' + assert response["location"] == "/accounts/login/?next=/" def test_session_expire_no_expire_setting(r, settings): settings.SESSION_COOKIE_AGE = 3600 middleware = SessionTimeoutMiddleware() - with freeze_time('2017-08-31 21:46:00'): + with freeze_time("2017-08-31 21:46:00"): assert middleware.process_request(r) is None - with freeze_time('2017-08-31 22:45:00'): + with freeze_time("2017-08-31 22:45:00"): assert middleware.process_request(r) is None - with freeze_time('2017-08-31 22:46:01'): + with freeze_time("2017-08-31 22:46:01"): response = middleware.process_request(r) assert SESSION_TIMEOUT_KEY not in r.session - assert response['location'] == '/accounts/login/?next=/' + assert response["location"] == "/accounts/login/?next=/" def test_session_expire_last_activity(r, settings): @@ -68,16 +68,64 @@ def test_session_expire_last_activity(r, settings): settings.SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True middleware = SessionTimeoutMiddleware() - with freeze_time('2017-08-31 20:46:00'): + with freeze_time("2017-08-31 20:46:00"): assert middleware.process_request(r) is None - with freeze_time('2017-08-31 21:45:00'): + with freeze_time("2017-08-31 21:45:00"): assert middleware.process_request(r) is None - with freeze_time('2017-08-31 21:46:01'): + with freeze_time("2017-08-31 21:46:01"): assert middleware.process_request(r) is None - with freeze_time('2017-08-31 23:46:02'): + with freeze_time("2017-08-31 23:46:02"): response = middleware.process_request(r) assert SESSION_TIMEOUT_KEY not in r.session - assert response['location'] == '/accounts/login/?next=/' \ No newline at end of file + assert response["location"] == "/accounts/login/?next=/" + + +def test_session_expire_last_activity_grace_(r, settings): + settings.SESSION_COOKIE_AGE = 3600 + settings.SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True + settings.SESSION_EXPIRE_AFTER_LAST_ACTIVITY_GRACE_PERIOD = 90 + middleware = SessionTimeoutMiddleware() + + value = None + + with freeze_time("2017-08-31 20:46:00"): + assert middleware.process_request(r) is None + value = r.session[SESSION_TIMEOUT_KEY] + + with freeze_time("2017-08-31 20:47:00"): + assert middleware.process_request(r) is None + assert r.session[SESSION_TIMEOUT_KEY] is value + + with freeze_time("2017-08-31 20:47:31"): + assert middleware.process_request(r) is None + assert r.session[SESSION_TIMEOUT_KEY] is not value + + with freeze_time("2017-08-31 21:47:32"): + response = middleware.process_request(r) + assert SESSION_TIMEOUT_KEY not in r.session + assert response["location"] == "/accounts/login/?next=/" + + +def test_session_expire_last_activity_grace_not_update(r, settings): + settings.SESSION_COOKIE_AGE = 3600 + settings.SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True + settings.SESSION_EXPIRE_AFTER_LAST_ACTIVITY_GRACE_PERIOD = 90 + middleware = SessionTimeoutMiddleware() + + value = None + + with freeze_time("2017-08-31 20:46:00"): + assert middleware.process_request(r) is None + value = r.session[SESSION_TIMEOUT_KEY] + + with freeze_time("2017-08-31 20:47:00"): + assert middleware.process_request(r) is None + assert r.session[SESSION_TIMEOUT_KEY] is value + + with freeze_time("2017-08-31 21:46:01"): + response = middleware.process_request(r) + assert SESSION_TIMEOUT_KEY not in r.session + assert response["location"] == "/accounts/login/?next=/" From 2eef18c41082cdfb1ea7e4fa65a0d2dbc9540417 Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Tue, 26 Mar 2019 13:13:05 +0100 Subject: [PATCH 07/13] incorrect pytest-cov --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 50f54b3..56bbfad 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ 'freezegun==0.3.11', 'pytest==4.3.1', 'pytest-django==3.4.8', - 'pytest-cov==2.6.2', + 'pytest-cov==2.6.1', # Linting 'isort==4.3.15', From 95b263f4be9bf1445f7764225ad801947d55347f Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Tue, 26 Mar 2019 13:16:35 +0100 Subject: [PATCH 08/13] bumped coverage --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 56bbfad..a52802f 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ ] tests_require = [ - 'coverage==4.2', + 'coverage==4.5.3', 'freezegun==0.3.11', 'pytest==4.3.1', 'pytest-django==3.4.8', From 658dc2194d9911ed74239419f744b50cb575c3d3 Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Tue, 26 Mar 2019 16:37:27 +0100 Subject: [PATCH 09/13] Add azure-pipelines --- azure-pipelines.yml | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..8bc7f1c --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,46 @@ +jobs: + - job: Test + pool: + vmImage: "ubuntu-16.04" + strategy: + matrix: + python 3.6: + python.version: "3.6" + TOXENV: "py36" + python 3.7: + python.version: "3.7" + TOXENV: "py37" + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: "$(python.version)" + - script: | + python -m pip install --upgrade pip + pip3 install --upgrade setuptools + pip3 install --upgrade tox + pip3 install --upgrade codecov + displayName: "Install testing requirements" + - script: tox -e $(TOXENV) + displayName: "Run tox with TOXENV=$(TOXENV)" + - script: | + tox -e coverage-report + codecov + condition: succeeded() + displayName: "Upload coverage information to codecov.io" + - job: Publish + pool: + vmImage: "ubuntu-16.04" + dependsOn: Test + condition: in(variables['Build.SourceBranch'], 'refs/heads/master') + displayName: "Publish artifacts" + steps: + - task: CopyFiles@2 + displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)' + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: | + **/* + !.git/**/* + TargetFolder: '$(Build.ArtifactStagingDirectory)' + - task: PublishBuildArtifacts@1 + displayName: drop From 234ee52d7e569da614040c75869783a7a79c6ede Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Mon, 1 Apr 2019 14:48:45 +0200 Subject: [PATCH 10/13] Feature/azure pipeline updates (#6) * update pipeline to use python version and updated badges --- README.rst | 25 +++++++++++++++++-------- azure-pipelines.yml | 10 ++++++++++ setup.py | 9 ++++++++- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index 4da1dca..d2cd432 100644 --- a/README.rst +++ b/README.rst @@ -1,12 +1,7 @@ -====================== -django-session-timeout -====================== +.. start-no-pypi - -Status -====== -.. image:: https://travis-ci.org/labd/django-session-timeout.svg?branch=master - :target: https://travis-ci.org/labd/django-session-timeout +.. image:: https://dev.azure.com/lab-digital-opensource/django-session-timeout/_apis/build/status/labd.django-session-timeout?branchName=master + :target: https://dev.azure.com/lab-digital-opensource/django-session-timeout/_build/latest?definitionId=2&branchName=master .. image:: http://codecov.io/github/LabD/django-session-timeout/coverage.svg?branch=master :target: http://codecov.io/github/LabD/django-session-timeout?branch=master @@ -14,6 +9,20 @@ Status .. image:: https://img.shields.io/pypi/v/django-session-timeout.svg :target: https://pypi.python.org/pypi/django-session-timeout/ +.. image:: https://readthedocs.org/projects/django-session-timeout/badge/?version=stable + :target: https://django-session-timeout.readthedocs.io/en/stable/?badge=stable + :alt: Documentation Status + +.. image:: https://img.shields.io/github/stars/labd/django-session-timeout.svg?style=social&logo=github + :target: https://github.com/Labd/django-session-timeout/stargazers + +.. end-no-pypi + +====================== +django-session-timeout +====================== + +Add timestamp to sessions to expire them independently Installation ============ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8bc7f1c..c552231 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,4 +1,13 @@ jobs: + - job: UpdateBuildNumber + pool: + vmImage: ubuntu-16.04 + steps: + - script: | + pip3 install --upgrade setuptools + echo "##vso[build.UpdateBuildNumber]`python3 setup.py --version`-$BUILD_BUILDID" + displayName: Set Version number + - job: Test pool: vmImage: "ubuntu-16.04" @@ -27,6 +36,7 @@ jobs: codecov condition: succeeded() displayName: "Upload coverage information to codecov.io" + - job: Publish pool: vmImage: "ubuntu-16.04" diff --git a/setup.py b/setup.py index a52802f..02a1d2f 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,5 @@ +import re + from setuptools import find_packages, setup docs_require = [ @@ -18,11 +20,16 @@ 'flake8-debugger==3.1.0', ] +with open('README.rst') as fh: + long_description = re.sub( + '^.. start-no-pypi.*^.. end-no-pypi', '', fh.read(), flags=re.M | re.S) + + setup( name='django-session-timeout', version='0.0.3', description="Middleware to expire sessions after specific amount of time", - long_description=open('README.rst', 'r').read(), + long_description=long_description, url='https://github.com/LabD/django-session-timeout', author="Lab Digital", author_email="opensource@labdigital.nl", From f95acba37dca33ff6e5a20dacaa9ff8c11cf470f Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Mon, 1 Apr 2019 15:18:15 +0200 Subject: [PATCH 11/13] =?UTF-8?q?Bump=20version:=200.0.3=20=E2=86=92=200.0?= =?UTF-8?q?.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 4 ++-- setup.cfg | 2 +- setup.py | 2 +- src/django_session_timeout/__init__.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 7012e8f..7f1b2eb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -56,7 +56,7 @@ # |version| and |release|, also used in various other places throughout the # built documents. # -version = '0.0.3' +version = '0.0.4' release = version # The language for content autogenerated by Sphinx. Refer to documentation @@ -139,7 +139,7 @@ # The name for this set of Sphinx documents. # " v documentation" by default. # -# html_title = u'django-session-timeout v0.0.3' +# html_title = u'django-session-timeout v0.0.4' # A shorter title for the navigation bar. Default is the same as html_title. # diff --git a/setup.cfg b/setup.cfg index 99268f5..54b96d8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.0.3 +current_version = 0.0.4 commit = true tag = true tag_name = {new_version} diff --git a/setup.py b/setup.py index 02a1d2f..4475898 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ setup( name='django-session-timeout', - version='0.0.3', + version='0.0.4', description="Middleware to expire sessions after specific amount of time", long_description=long_description, url='https://github.com/LabD/django-session-timeout', diff --git a/src/django_session_timeout/__init__.py b/src/django_session_timeout/__init__.py index 27fdca4..81f0fde 100644 --- a/src/django_session_timeout/__init__.py +++ b/src/django_session_timeout/__init__.py @@ -1 +1 @@ -__version__ = "0.0.3" +__version__ = "0.0.4" From 8778785092a2b7dc29e6bea7f88d63f86bc85f1b Mon Sep 17 00:00:00 2001 From: Michiel Bijland Date: Tue, 9 Apr 2019 11:38:08 +0200 Subject: [PATCH 12/13] Updated changelog --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index e251929..10231d5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +0.0.4 (2019-04-01) +================== + - added grace period to SESSION_EXPIRE_AFTER_LAST_ACTIVITY + + 0.0.3 (2017-12-14) ================== - Redirect user to the login page after session timeout instead of the root page From c0c0fac0d244ecb40040e703a50a3c8714576c6c Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Fri, 27 Sep 2019 09:51:58 +0200 Subject: [PATCH 13/13] Add github action --- .github/workflows/python-package.yml | 68 ++++++++++++++++++++++++++++ tox.ini | 11 ++--- 2 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/python-package.yml diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml new file mode 100644 index 0000000..c2b8749 --- /dev/null +++ b/.github/workflows/python-package.yml @@ -0,0 +1,68 @@ +name: Python Tests + +on: [push] + +jobs: + test: + + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + tox_env: + - py36-django111 + - py37-django111 + - py36-django22 + - py37-django22 + include: + - python-version: "3.6" + tox_env: py36-django111 + - python-version: "3.7" + tox_env: py37-django111 + - python-version: "3.6" + tox_env: py36-django22 + - python-version: "3.7" + tox_env: py37-django22 + steps: + - name: Install system dependencies + run: | + sudo apt-get install libpq-dev + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip tox + - name: Test with tox + run: | + tox -e ${{ matrix.tox_env }} + - name: Prepare Coverage report + run: tox -e coverage-report + - name: Upload to codecov + uses: codecov/codecov-action@v1.0.2 + with: + token: ${{secrets.CODECOV_TOKEN}} + flags: unittests + + release: + runs-on: ubuntu-latest + needs: [test] + steps: + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: "3.7" + - name: Install build requirements + run: | + python -m pip install wheel + - uses: actions/checkout@v1 + - name: Build package + run: python setup.py sdist bdist_wheel + - name: Publish package + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.pypi_password }} diff --git a/tox.ini b/tox.ini index 7fa1554..5e71544 100644 --- a/tox.ini +++ b/tox.ini @@ -1,20 +1,19 @@ [tox] envlist = - py{27,36,37}-django111 - py{36,37}-django2 + py{36,37}-django111 + py{36,37}-django22 [testenv] -commands = coverage run --parallel -m pytest {posargs} +commands = coverage run --source django_session_timeout --parallel -m pytest {posargs} deps = django111: Django>=1.11,<1.12 - django2: Django>=2.0,<3 + django22: Django>=2.2,<2.3 extras = test -# Uses default basepython otherwise reporting doesn't work on Travis where -# Python 3.5 is only available in 3.5 jobs. [testenv:coverage-report] deps = coverage skip_install = true commands = coverage combine + coverage xml coverage report