Skip to content

Commit c350966

Browse files
authoredMar 10, 2021
Merge pull request #358 from jazzband/gha
Migrate to GitHub Actions.
2 parents 51be647 + 15adbe3 commit c350966

20 files changed

+194
-668
lines changed
 

‎.github/workflows/release.yml

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
jobs:
9+
build:
10+
if: github.repository == 'jazzband/django-newsletter'
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
with:
16+
fetch-depth: 0
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v2
20+
with:
21+
python-version: 3.8
22+
23+
- name: Get pip cache dir
24+
id: pip-cache
25+
run: |
26+
echo "::set-output name=dir::$(pip cache dir)"
27+
28+
- name: Cache
29+
uses: actions/cache@v2
30+
with:
31+
path: ${{ steps.pip-cache.outputs.dir }}
32+
key: release-${{ hashFiles('**/setup.py') }}-${{ hashFiles('**/tox.ini') }}
33+
restore-keys: |
34+
release-
35+
36+
- name: Install dependencies
37+
run: |
38+
python -m pip install -U pip
39+
python -m pip install -U setuptools twine wheel
40+
41+
- name: Build package
42+
run: |
43+
python setup.py --version
44+
python setup.py sdist --format=gztar bdist_wheel
45+
twine check dist/*
46+
47+
- name: Upload packages to Jazzband
48+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
49+
uses: pypa/gh-action-pypi-publish@master
50+
with:
51+
user: jazzband
52+
password: ${{ secrets.JAZZBAND_RELEASE_KEY }}
53+
repository_url: https://jazzband.co/projects/django-newsletter/upload

‎.github/workflows/test.yml

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Test
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
name: build (Python ${{ matrix.python-version }}, Django ${{ matrix.django-version }})
8+
runs-on: ubuntu-latest
9+
strategy:
10+
fail-fast: false
11+
max-parallel: 5
12+
matrix:
13+
python-version: ['3.6', '3.7', '3.8', '3.9']
14+
django-version: ['2.2', '3.0', '3.1', 'main']
15+
16+
steps:
17+
- uses: actions/checkout@v2
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v2
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
24+
- name: Get pip cache dir
25+
id: pip-cache
26+
run: |
27+
echo "::set-output name=dir::$(pip cache dir)"
28+
29+
- name: Cache
30+
uses: actions/cache@v2
31+
with:
32+
path: ${{ steps.pip-cache.outputs.dir }}
33+
key:
34+
${{ matrix.python-version }}-v1-${{ hashFiles('**/setup.py') }}-${{ hashFiles('**/tox.ini') }}
35+
restore-keys: |
36+
${{ matrix.python-version }}-v1-
37+
38+
- name: Install dependencies
39+
run: |
40+
python -m pip install --upgrade pip
41+
python -m pip install --upgrade tox tox-gh-actions
42+
43+
- name: Tox tests
44+
run: |
45+
tox -v
46+
env:
47+
DJANGO: ${{ matrix.django-version }}
48+
49+
- name: Upload coverage
50+
uses: codecov/codecov-action@v1
51+
with:
52+
name: Python ${{ matrix.python-version }}

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ django_setuptest*
1616
docs/_*
1717
.idea/
1818
venv/
19+
coverage.xml
20+
.tox

‎.landscape.yml

-2
This file was deleted.

‎.travis.yml

-41
This file was deleted.

‎CONTRIBUTING.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ Thanks for your awesome contrib! If you'd like to have your code included in mas
1313
couple of things you have to take care of though:
1414

1515
1. Ensure that the way you implemented the functionality is generic enough for other users to make use of and does not degrade the performance of existing users. If you unsure about this, create an issue with proposed functionality to discuss with the collaborators first.
16-
2. Make sure the tests are passing. In any case, Travis should report passing tests.
17-
3. Extended tests to cover any additional code included in your commit. In any case, the coveralls report should report equal or increased coverage.
16+
2. Make sure the tests are passing. In any case, GitHub Actions should report passing tests.
17+
3. Extended tests to cover any additional code included in your commit. In any case, the Codecov report should report equal or increased coverage.
1818
4. Make sure that any added or changed functionality is documented in the Sphinx documentation.

‎Pipfile

-24
This file was deleted.

‎Pipfile.lock

-451
This file was deleted.

‎README.rst

+6-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ django-newsletter
55
.. image:: https://img.shields.io/pypi/v/django-newsletter.svg
66
:target: https://pypi.python.org/pypi/django-newsletter
77

8-
.. image:: https://img.shields.io/travis/jazzband/django-newsletter/master.svg
9-
:target: http://travis-ci.org/jazzband/django-newsletter
8+
.. image:: https://github.com/jazzband/django-newsletter/workflows/Test/badge.svg
9+
:target: https://github.com/jazzband/django-newsletter/actions
10+
:alt: GitHub Actions
1011

11-
.. image:: https://coveralls.io/repos/github/jazzband/django-newsletter/badge.svg?branch=master
12-
:target: https://coveralls.io/github/jazzband/django-newsletter?branch=master
12+
.. image:: https://codecov.io/gh/jazzband/django-newsletter/branch/master/graph/badge.svg
13+
:target: https://codecov.io/gh/jazzband/django-newsletter
1314

1415
.. image:: https://jazzband.co/static/img/badge.svg
1516
:target: https://jazzband.co/
@@ -58,7 +59,7 @@ Fairly extensive tests are available for internal frameworks, web
5859
(un)subscription and mail sending. Sending a newsletter to large groups of recipients
5960
(+15k) has been confirmed to work in multiple production environments. Tests
6061
for pull req's and the master branch are automatically run through
61-
`Travis CI <http://travis-ci.org/jazzband/django-newsletter>`_.
62+
`GitHub Actions <https://github.com/jazzband/django-newsletter/actions>`_.
6263

6364
Contributing
6465
=============

‎docs/conf.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
# All configuration values have a default; values that are commented out
1212
# serve to show the default.
1313

14-
import sys, os
14+
import os
15+
import sys
16+
from pkg_resources import get_distribution
17+
1518

1619
# Determine whether rendering on RTD
1720
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
@@ -80,10 +83,9 @@
8083
# |version| and |release|, also used in various other places throughout the
8184
# built documents.
8285
#
83-
# The short X.Y version.
84-
version = '0.5'
85-
# The full version, including alpha/beta/rc tags.
86-
release = '0.5.1'
86+
release = get_distribution('django-newsletter').version
87+
# for example take major/minor
88+
version = '.'.join(release.split('.')[:2])
8789

8890
# The language for content autogenerated by Sphinx. Refer to documentation
8991
# for a list of supported languages.

‎newsletter/__init__.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from pkg_resources import get_distribution, DistributionNotFound
2+
3+
try:
4+
__version__ = get_distribution("django-newsletter").version
5+
except DistributionNotFound:
6+
# package is not installed
7+
__version__ = None

‎newsletter/admin_utils.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from django.contrib.admin.utils import unquote
44
from django.http import Http404
5-
from django.utils.encoding import force_text
5+
from django.utils.encoding import force_str
66
from django.utils.translation import gettext as _
77
from .models import Subscription
88

@@ -25,8 +25,8 @@ def _getobj(self, request, object_id):
2525
'%(name)s object with primary key '
2626
'\'%(key)s\' does not exist.'
2727
) % {
28-
'name': force_text(opts.verbose_name),
29-
'key': force_text(object_id)
28+
'name': force_str(opts.verbose_name),
29+
'key': force_str(object_id)
3030
}
3131
)
3232

‎requirements.txt

-6
This file was deleted.

‎requirements_test.txt

-8
This file was deleted.

‎runtests.py

-39
This file was deleted.

‎setup.py

+12-16
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,26 @@
3030
warnings.warn('Could not read README.rst and/or CHANGES.rst')
3131
README = None
3232

33-
try:
34-
REQUIREMENTS = open('requirements.txt').read()
35-
except:
36-
warnings.warn('Could not read requirements.txt')
37-
REQUIREMENTS = None
38-
39-
try:
40-
TEST_REQUIREMENTS = open('requirements_test.txt').read()
41-
except:
42-
warnings.warn('Could not read requirements_test.txt')
43-
TEST_REQUIREMENTS = None
4433

4534
setup(
4635
name='django-newsletter',
47-
version="1.0b1",
36+
use_scm_version={"version_scheme": "post-release"},
37+
setup_requires=["setuptools_scm"],
4838
description=(
4939
'Django app for managing multiple mass-mailing lists with both '
5040
'plaintext as well as HTML templates (and pluggable WYSIWYG editors '
5141
'for messages), images and a smart queueing system all right from '
5242
'the admin interface.'
5343
),
5444
long_description=README,
55-
install_requires=REQUIREMENTS,
45+
install_requires=[
46+
"Django>=2.2.16",
47+
"python-card-me<1.0",
48+
"ldif3<3.2",
49+
"chardet",
50+
"unicodecsv<0.15",
51+
"Pillow",
52+
],
5653
author='Mathijs de Bruin',
5754
author_email='mathijs@mathijsfietst.nl',
5855
url='http://github.com/jazzband/django-newsletter/',
@@ -66,12 +63,11 @@
6663
'License :: OSI Approved :: GNU Affero General Public License v3',
6764
'Operating System :: OS Independent',
6865
'Programming Language :: Python',
69-
'Programming Language :: Python :: 3.5',
66+
'Programming Language :: Python :: 3',
7067
'Programming Language :: Python :: 3.6',
7168
'Programming Language :: Python :: 3.7',
7269
'Programming Language :: Python :: 3.8',
70+
'Programming Language :: Python :: 3.9',
7371
'Topic :: Utilities'
7472
],
75-
test_suite='runtests.run_tests',
76-
tests_require=TEST_REQUIREMENTS
7773
)

‎tests/test_admin.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
from newsletter.admin_utils import make_subscription
1414
from newsletter.models import Message, Newsletter, Submission, Subscription, Attachment, attachment_upload_to
1515

16-
from .utils import AssertLogsMixin
17-
1816
test_files_dir = os.path.join(os.path.dirname(__file__), 'files')
1917

2018

@@ -42,7 +40,7 @@ def setUp(self):
4240
message=self.message_with_attachment)
4341

4442

45-
class AdminTestCase(AdminTestMixin, AssertLogsMixin, TestCase):
43+
class AdminTestCase(AdminTestMixin, TestCase):
4644
def admin_import_file(self, source_file, ignore_errors=''):
4745
""" Upload an address file for import to admin. """
4846

‎tests/test_web.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from django.core import mail
1010
from django.contrib.auth import get_user_model
1111
from django.utils import timezone
12-
from django.utils.encoding import force_text
12+
from django.utils.encoding import force_str
1313
from django.test.utils import override_settings
1414
from django.urls import reverse
1515

@@ -458,7 +458,7 @@ def test_unsubscribe_not_subscribed_view(self):
458458

459459
self.assertIn(
460460
'You are not subscribed to',
461-
force_text(list(response.context['messages'])[0])
461+
force_str(list(response.context['messages'])[0])
462462
)
463463

464464
def test_unsubscribe_post(self):

‎tests/utils.py

+3-61
Original file line numberDiff line numberDiff line change
@@ -12,69 +12,11 @@
1212

1313
from django.test import TestCase
1414

15-
1615
from django.template import loader, TemplateDoesNotExist
1716

1817
from django_webtest import WebTest
1918

2019

21-
class AssertLogsMixin:
22-
"""Mixin to enable assertLogs method in Python 2.7.
23-
24-
patch_logger has similar functionality for Python 2.7, but is
25-
removed in Django 3.0. This mixin reworks patch_logger so that
26-
the assertLogs method can be used for any supported Django
27-
version.
28-
"""
29-
# TODO: Remove use of mixin when Django 1.11 support dropped
30-
def assertLogs(self, logger=None, level=None):
31-
# Use assertLogs context manager if present
32-
try:
33-
from unittest.case import _AssertLogsContext
34-
35-
return _AssertLogsContext(self, logger, level)
36-
except ImportError:
37-
# Fallback if Django version does not support assertLogs
38-
import logging
39-
from django.test.utils import patch_logger
40-
41-
class PatchLoggerResponse:
42-
"""Object to mimic AssertLogsContext response."""
43-
def __init__(self, messages):
44-
self.output = messages
45-
46-
@contextmanager
47-
def patch_logger(logger_name, log_level, log_kwargs=False):
48-
"""Replicating patch_logger functionality from Django 1.11.
49-
50-
Cannot use original Django patch_logger because of how
51-
it returns its response. Have copied and modified it
52-
to return an object that mimics the assertLogs response.
53-
"""
54-
logger_response = PatchLoggerResponse([])
55-
56-
def replacement(msg, *args, **kwargs):
57-
call = msg % args
58-
logger_response.output.append((call, kwargs) if log_kwargs else call)
59-
60-
logger = logging.getLogger(logger_name)
61-
orig = getattr(logger, log_level)
62-
setattr(logger, log_level, replacement)
63-
64-
try:
65-
yield logger_response
66-
finally:
67-
setattr(logger, log_level, orig)
68-
69-
if len(logger_response.output) == 0:
70-
raise self.failureException(
71-
"no logs of level {} or higher triggered on {}".format(
72-
log_level, logger_name
73-
)
74-
)
75-
76-
return patch_logger(logger, level.lower())
77-
7820
class WebTestCase(WebTest):
7921
def setUp(self):
8022
self.site = Site.objects.get_current()
@@ -98,7 +40,7 @@ def assertInContext(self, response, variable,
9840
self.assertEqual(instance, value)
9941

10042

101-
class MailTestCase(AssertLogsMixin, TestCase):
43+
class MailTestCase(TestCase):
10244
def get_email_list(self, email):
10345
if email:
10446
return (email,)
@@ -160,7 +102,7 @@ def assertEmailHasHeader(self, header, content=None, email=None):
160102
self.assertEqual(my_email.extra_headers[header], content)
161103

162104

163-
class UserTestCase(AssertLogsMixin, TestCase):
105+
class UserTestCase(TestCase):
164106
def setUp(self):
165107
super().setUp()
166108

@@ -185,7 +127,7 @@ def tearDown(self):
185127
self.user.delete()
186128

187129

188-
class ComparingTestCase(AssertLogsMixin, TestCase):
130+
class ComparingTestCase(TestCase):
189131
def assertLessThan(self, value1, value2):
190132
self.assertTrue(value1 < value2)
191133

‎tox.ini

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[tox]
2+
envlist =
3+
py{36,37,38,39}-dj{22,30,31}
4+
py{38,39}-djmain
5+
6+
[testenv]
7+
deps =
8+
coverage
9+
django-imperavi
10+
# TinyMCE above 3 doesn't support Python 3.5 anymore.
11+
# TODO: Remove version freeze when Django 2.2 LTS support is dropped, early 2022.
12+
django-tinymce<3
13+
pytz
14+
webtest
15+
django-webtest
16+
mock
17+
dj22: Django>=2.2,<3.0
18+
dj30: Django>=3.0,<3.1
19+
dj31: Django>=3.1,<3.2
20+
djmain: https://github.com/django/django/archive/main.tar.gz
21+
usedevelop = True
22+
ignore_outcome =
23+
djmain: True
24+
commands =
25+
coverage run {envbindir}/django-admin test
26+
coverage report
27+
coverage xml
28+
setenv =
29+
DJANGO_SETTINGS_MODULE=test_project.settings
30+
PYTHONPATH={toxinidir}/test_project
31+
32+
[gh-actions]
33+
python =
34+
3.6: py36
35+
3.7: py37
36+
3.8: py38
37+
3.9: py39
38+
39+
[gh-actions:env]
40+
DJANGO =
41+
2.2: dj22
42+
3.0: dj30
43+
3.1: dj31
44+
main: djmain

0 commit comments

Comments
 (0)
Please sign in to comment.