Repository: Princeton-CDH/django-pucas (language: python)

Issue:
Clarify only python 3 is supported in setup.py
Add `'Programming Language :: Python :: 3 :: Only'` to `setup.py`
Ldap bind credential related setting keys fixed.
Ldap bind credential related setting keys fixed.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml
new file mode 100644
index 0000000..4e1ef42
--- /dev/null
+++ b/.github/workflows/python-publish.yml
@@ -0,0 +1,31 @@
+# This workflows will upload a Python Package using Twine when a release is created
+# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
+
+name: Upload Python Package
+
+on:
+  release:
+    types: [created]
+
+jobs:
+  deploy:
+
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: Set up Python
+      uses: actions/setup-python@v2
+      with:
+        python-version: '3.x'
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip
+        pip install setuptools wheel twine
+    - name: Build and publish
+      env:
+        TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
+        TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
+      run: |
+        python setup.py sdist bdist_wheel
+        twine upload dist/*
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 9e584b9..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-language: python
-
-dist: "xenial"
-
-python:
-  - "3.5"
-  - "3.6"
-  - "3.7"
-  - "3.8"
-
-env:
-  - DJANGO=1.11
-  - DJANGO=2.0
-  - DJANGO=2.1
-  - DJANGO=2.2
-  - DJANGO=3.0
-  - DJANGO=3.1
-
-matrix:
-  exclude:
-    - python: "3.5"
-      env: DJANGO=3.0
-    - python: "3.5"
-      env: DJANGO=3.1
-
-before_install:
-  - pip install --upgrade pytest
-
-install:
-  - pip install -q Django==$DJANGO
-  - pip install -e .
-  - pip install -e '.[test]'
-  - pip install codecov
-  - cp ci/testsettings.py testsettings.py
-  - python -c "import uuid; print('SECRET_KEY = \'%s\'' % uuid.uuid4())" >> testsettings.py
-
-script:
-  - py.test --cov=pucas
-
-after_success:
-- codecov
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index f817fec..0f2a0ac 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,12 @@
 CHANGELOG
 =========
 
+0.8
+---
+* Now tested against Django 3.2-4.2
+* Add testing for Python 3.9-3.11
+* Using GitHub Actions for continuous integration
+
 0.7
 ----
 * Drop support for Python 2.7
diff --git a/README.rst b/README.rst
index afa642c..d94c4be 100644
--- a/README.rst
+++ b/README.rst
@@ -1,11 +1,11 @@
 django-pucas
 ============
 
-.. image:: https://travis-ci.org/Princeton-CDH/django-pucas.svg?branch=master
-   :target: https://travis-ci.org/Princeton-CDH/django-pucas
+.. image:: https://github.com/Princeton-CDH/django-pucas/actions/workflows/unit_tests.yml/badge.svg
+   :target: https://github.com/Princeton-CDH/django-pucas/actions/workflows/unit_tests.yml
    :alt: Build status
 
-.. image:: https://codecov.io/gh/Princeton-CDH/django-pucas/branch/master/graph/badge.svg
+.. image:: https://codecov.io/gh/Princeton-CDH/django-pucas/branch/main/graph/badge.svg
   :target: https://codecov.io/gh/Princeton-CDH/django-pucas
   :alt: Code Coverage
 
@@ -13,10 +13,6 @@ django-pucas
    :target: https://www.codefactor.io/repository/github/princeton-cdh/django-pucas
    :alt: CodeFactor
 
-.. image:: https://requires.io/github/Princeton-CDH/django-pucas/requirements.svg?branch=master
-     :target: https://requires.io/github/Princeton-CDH/django-pucas/requirements/?branch=master
-     :alt: Requirements Status
-
 .. image:: https://img.shields.io/pypi/pyversions/viapy
    :alt: PyPI - Python Version
 
@@ -35,8 +31,8 @@ support for prepopulating user account data based on an LDAP search.
 
 **django-pucas** is tested against:
 
-* Django ``1.11-3.1``
-* Python ``3.5-3.8``
+* Django ``3.2-4.0``
+* Python ``3.9-3.11``
 
 **django-pucas** requires **django-cas-ng** 3.6 or greater.
 
@@ -112,11 +108,11 @@ Add required configurations to ``settings.py``:
         # not handled by attribute map.  Method should take a user
         # object and ldap search result.
         'EXTRA_USER_INIT': 'myproj.myapp.models.init_profile_from_ldap'
-        'BASE_DN': 'uid=username,o=your org,c=country_code',
-        'BASE_PASSWORD': 'secreupasswordforyourldap',
+        'BIND_DN': 'uid=username,o=your org,c=country_code',
+        'BIND_PASSWORD': 'secreupasswordforyourldap',
     }
 
-* Note: ``BASE_DN`` and ``BASE_PASSWORD`` are optional if you want
+* Note: ``BIND_DN`` and ``BIND_PASSWORD`` are optional if you want
         to bind anonymously. Add them if they are required by your LDAP.
         This supports user/pass authentication.
 
diff --git a/pucas/__init__.py b/pucas/__init__.py
index 45c6091..fb7b783 100644
--- a/pucas/__init__.py
+++ b/pucas/__init__.py
@@ -1,8 +1,6 @@
-default_app_config = 'pucas.apps.PucasConfig'
-
-__version_info__ = (0, 8, 0, 'dev')
+__version_info__ = (0, 8, 0, "dev")
 
 # Dot-connect all but the last. Last is dash-connected if not None.
-__version__ = '.'.join([str(i) for i in __version_info__[:-1]])
+__version__ = ".".join([str(i) for i in __version_info__[:-1]])
 if __version_info__[-1] is not None:
-    __version__ += ('-%s' % (__version_info__[-1],))
+    __version__ += "-%s" % (__version_info__[-1],)
diff --git a/pucas/cas_urls.py b/pucas/cas_urls.py
index 4e8135a..074250f 100644
--- a/pucas/cas_urls.py
+++ b/pucas/cas_urls.py
@@ -1,8 +1,8 @@
-from django.conf.urls import url
+from django.urls import path
 from django_cas_ng.views import LoginView, LogoutView, CallbackView
 
 urlpatterns = [
-    url(r'^login/$', LoginView.as_view(), name='cas_ng_login'),
-    url(r'^logout/$', LogoutView.as_view(), name='cas_ng_logout'),
-    url(r'^callback/$', CallbackView.as_view(), name='cas_ng_proxy_callback'),
+    path("login/", LoginView.as_view(), name="cas_ng_login"),
+    path("logout/", LogoutView.as_view(), name="cas_ng_logout"),
+    path("callback/", CallbackView.as_view(), name="cas_ng_proxy_callback"),
 ]
diff --git a/setup.py b/setup.py
index 2aa6215..4e47b5e 100644
--- a/setup.py
+++ b/setup.py
@@ -3,56 +3,52 @@
 from setuptools import find_packages, setup
 from pucas import __version__
 
-with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
+with open(os.path.join(os.path.dirname(__file__), "README.rst")) as readme:
     README = readme.read()
 
 # allow setup.py to be run from any path
 os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
 
-REQUIREMENTS = ['django>=1.8', 'django-cas-ng>=3.6', 'ldap3']
-TEST_REQUIREMENTS = ['pytest', 'pytest-django', 'pytest-cov']
+REQUIREMENTS = ["django>=1.8", "django-cas-ng>=3.6", "ldap3"]
+TEST_REQUIREMENTS = ["pytest", "pytest-django", "pytest-cov"]
 if sys.version_info < (3, 0):
-    TEST_REQUIREMENTS.append('mock')
+    TEST_REQUIREMENTS.append("mock")
 
 
 setup(
-    name='pucas',
+    name="pucas",
     version=__version__,
     packages=find_packages(),
     include_package_data=True,
-    license='Apache License, Version 2.0',
-    description='Django app to login with CAS and populate user accounts with LDAP.',
+    license="Apache License, Version 2.0",
+    description="Django app to login with CAS and populate user accounts with LDAP.",
     long_description=README,
-    url='https://github.com/Princeton-CDH/django-pucas',
+    url="https://github.com/Princeton-CDH/django-pucas",
     install_requires=REQUIREMENTS,
-    setup_requires=['pytest-runner'],
+    setup_requires=["pytest-runner"],
     tests_require=TEST_REQUIREMENTS,
     extras_require={
-        'test': TEST_REQUIREMENTS,
+        "test": TEST_REQUIREMENTS,
     },
-    author='CDH @ Princeton',
-    author_email='digitalhumanities@princeton.edu',
+    author="CDH @ Princeton",
+    author_email="digitalhumanities@princeton.edu",
     classifiers=[
-        'Environment :: Web Environment',
-        'Framework :: Django',
-        'Framework :: Django :: 1.11',
-        'Framework :: Django :: 2.0',
-        'Framework :: Django :: 2.1',
-        'Framework :: Django :: 2.2',
-        'Framework :: Django :: 3.0',
-        'Framework :: Django :: 3.1',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: Apache Software License',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.5',
-        'Programming Language :: Python :: 3.6',
-        'Programming Language :: Python :: 3.7',
-        'Programming Language :: Python :: 3.8',
-        'Programming Language :: Python :: 3 :: Only',
-        'Topic :: Internet :: WWW/HTTP',
-        'Topic :: System :: Systems Administration :: Authentication/Directory',
-        'Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP',
+        "Environment :: Web Environment",
+        "Framework :: Django",
+        "Framework :: Django :: 3.2",
+        "Framework :: Django :: 4.0",
+        "Framework :: Django :: 4.1",
+        "Intended Audience :: Developers",
+        "License :: OSI Approved :: Apache Software License",
+        "Operating System :: OS Independent",
+        "Programming Language :: Python",
+        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 3.9",
+        "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3.11",
+        "Programming Language :: Python :: 3 :: Only",
+        "Topic :: Internet :: WWW/HTTP",
+        "Topic :: System :: Systems Administration :: Authentication/Directory",
+        "Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP",
     ],
 )


Test patch:
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
new file mode 100644
index 0000000..c8e253a
--- /dev/null
+++ b/.github/workflows/unit_tests.yml
@@ -0,0 +1,52 @@
+name: unit tests
+
+on:
+  push: # run on every push or PR to any branch
+  pull_request:
+  schedule: # run automatically on main branch each Tuesday at 11am
+    - cron: "0 16 * * 2"
+
+jobs:
+  python-unit:
+    name: Python unit tests
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python: ["3.9", "3.10", "3.11"]
+        django: ["3.2", "4.0", "4.1", "4.2"]
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+
+      - name: Setup Python
+        uses: actions/setup-python@v4
+        with:
+          python-version: ${{ matrix.python }}
+
+      # We base the python cache on the hash of all requirements files, so that
+      # if any change, the cache is invalidated.
+      - name: Cache pip
+        uses: actions/cache@v3
+        with:
+          path: ~/.cache/pip
+          key: pip-${{ hashFiles('setup.py') }}
+          restore-keys: |
+            pip-${{ hashFiles('setup.py') }}
+            pip-
+
+      - name: Install package with dependencies
+        run: |
+          pip install -e .
+          pip install -e '.[test]'
+          pip install codecov
+
+      - name: Setup test settings
+        run: |
+          cp ci/testsettings.py testsettings.py
+          python -c "import uuid; print('SECRET_KEY = \'%s\'' % uuid.uuid4())" >> testsettings.py
+
+      - name: Run pytest
+        run: python -m pytest --cov=pucas --cov-report=xml
+
+      - name: Upload test coverage to Codecov
+        uses: codecov/codecov-action@v3