diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ee36052 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + push: + tags: + - '*' + +jobs: + build: + if: github.repository == 'jazzband/django-downloadview' + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install dependencies + run: | + python -m pip install -U pip + python -m pip install -U setuptools twine wheel + + - name: Build package + run: | + python setup.py --version + python setup.py sdist --format=gztar bdist_wheel + twine check dist/* + + - name: Upload packages to Jazzband + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@master + with: + user: jazzband + password: ${{ secrets.JAZZBAND_RELEASE_KEY }} + repository_url: https://jazzband.co/projects/django-downloadview/upload diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..c611845 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,52 @@ +name: Test + +on: [push, pull_request] + +jobs: + build: + name: build (Python ${{ matrix.python-version }}, Django ${{ matrix.django-version }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: 5 + matrix: + python-version: ['3.6', '3.7', '3.8', '3.9'] + django-version: ['2.2', '3.0', '3.1', 'master'] + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: Cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: + ${{ matrix.python-version }}-v1-${{ hashFiles('**/setup.py') }} + restore-keys: | + ${{ matrix.python-version }}-v1- + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install --upgrade tox tox-gh-actions + + - name: Tox tests + run: | + tox -v + env: + DJANGO: ${{ matrix.django-version }} + + - name: Upload coverage + uses: codecov/codecov-action@v1 + with: + name: Python ${{ matrix.python-version }} diff --git a/.gitignore b/.gitignore index 07da98d..c134a57 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ # Data files. /var/ +coverage.xml +.coverage/ # Python files. *.pyc @@ -14,6 +16,8 @@ # Tox files. /.tox/ +.eggs +*.egg-info # Virtualenv files (created by tox). /build/ diff --git a/.isort.cfg b/.isort.cfg index eb3d723..b565e95 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -6,7 +6,7 @@ force_grid_wrap=0 line_length=88 combine_as_imports=True -# List sections with django and +# List sections with django and known_django=django known_downloadview=django_downloadview diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 015ef21..0000000 --- a/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -language: python -dist: bionic -python: -- 3.6 -- 3.7 -- 3.8 -- 3.9-dev -install: -- pip install tox tox-travis -script: -- tox -v -jobs: - fast_finish: true - include: - - stage: deploy - env: - python: 3.7 - script: skip - deploy: - provider: pypi - user: jazzband - server: https://jazzband.co/projects/django-downloadview/upload - distributions: sdist bdist_wheel - password: - secure: TYFfz5OkSH0YwTKh0lc0PbddcuZh5oL2H1AVIXHs2dODQ46PNgLYgDRe9k9PItAenxm7QCnGRONJo2o1GNuiCcAOWK84jbrmufHZ5EeKTOVtssyrffSA/Oxfs5mFJ/Kgy3o8FC1hGRKXrXFN3bvedmVHERGQimQESPxHQ9sPWhc= - skip_existing: true - skip_cleanup: true - on: - tags: true - repo: jazzband/django-downloadview - python: 3.7 -after_success: - - pip install coveralls - - coveralls diff --git a/MANIFEST.in b/MANIFEST.in index d52c1c3..51f35b3 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,4 +6,3 @@ include CONTRIBUTING.rst include INSTALL include LICENSE include README.rst -include VERSION diff --git a/Makefile b/Makefile index 35d1647..9cb2a4d 100644 --- a/Makefile +++ b/Makefile @@ -92,12 +92,6 @@ demo: runserver: demo demo runserver - -#: release - Tag and push to PyPI. -.PHONY: release -release: - $(TOX) -e release - .PHONY: black black: $(BLACK) demo tests django_downloadview diff --git a/README.rst b/README.rst index d7e52b4..4be52d3 100644 --- a/README.rst +++ b/README.rst @@ -3,22 +3,26 @@ django-downloadview ################### .. image:: https://jazzband.co/static/img/badge.svg - :target: https://jazzband.co/ - :alt: Jazzband + :target: https://jazzband.co/ + :alt: Jazzband .. image:: https://img.shields.io/pypi/v/django-downloadview.svg - :target: https://pypi.python.org/pypi/django-downloadview + :target: https://pypi.python.org/pypi/django-downloadview .. image:: https://img.shields.io/pypi/pyversions/django-downloadview.svg - :target: https://pypi.python.org/pypi/django-downloadview + :target: https://pypi.python.org/pypi/django-downloadview + .. image:: https://img.shields.io/pypi/dm/django-downloadview.svg - :target: https://pypi.python.org/pypi/django-downloadview -.. image:: https://travis-ci.org/jazzband/django-downloadview.svg?branch=master - :target: https://travis-ci.org/jazzband/django-downloadview -.. image:: https://coveralls.io/repos/github/jazzband/django-downloadview/badge.svg?branch=master - :target: https://coveralls.io/github/jazzband/django-downloadview?branch=master + :target: https://pypi.python.org/pypi/django-downloadview + +.. image:: https://github.com/jazzband/django-downloadview/workflows/Test/badge.svg + :target: https://github.com/jazzband/django-downloadview/actions + :alt: GitHub Actions + +.. image:: https://codecov.io/gh/jazzband/django-downloadview/branch/master/graph/badge.svg + :target: https://codecov.io/gh/jazzband/django-downloadview + :alt: Coverage - `django-downloadview` makes it easy to serve files with `Django`_: * you manage files with Django (permissions, filters, generation, ...); @@ -60,8 +64,7 @@ Resources * PyPI page: http://pypi.python.org/pypi/django-downloadview * Code repository: https://github.com/jazzband/django-downloadview * Bugtracker: https://github.com/jazzband/django-downloadview/issues -* Continuous integration: https://travis-ci.org/jazzband/django-downloadview +* Continuous integration: https://github.com/jazzband/django-downloadview/actions * Roadmap: https://github.com/jazzband/django-downloadview/milestones - .. _`Django`: https://djangoproject.com diff --git a/VERSION b/VERSION deleted file mode 100644 index 7299f57..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.3.dev0 diff --git a/demo/setup.py b/demo/setup.py index 99593b5..1055fa7 100644 --- a/demo/setup.py +++ b/demo/setup.py @@ -1,46 +1,26 @@ -"""Python packaging.""" import os - from setuptools import setup here = os.path.abspath(os.path.dirname(__file__)) -project_root = os.path.dirname(here) - - -NAME = "django-downloadview-demo" -DESCRIPTION = "Serve files with Django and reverse-proxies." -README = open(os.path.join(here, "README.rst")).read() -VERSION = open(os.path.join(project_root, "VERSION")).read().strip() -AUTHOR = "Benoît Bryon" -EMAIL = "benoit@marmelune.net" -URL = "https://django-downloadview.readthedocs.io/" -CLASSIFIERS = [ - "Development Status :: 5 - Production/Stable", - "License :: OSI Approved :: BSD License", - "Programming Language :: Python :: 2.7", - "Framework :: Django", -] -KEYWORDS = [] -PACKAGES = ["demoproject"] -REQUIREMENTS = ["django-downloadview", "django-nose"] -ENTRY_POINTS = {"console_scripts": ["demo = demoproject.manage:main"]} - -if __name__ == "__main__": # Don't run setup() when we import this module. - setup( - name=NAME, - version=VERSION, - description=DESCRIPTION, - long_description=README, - classifiers=CLASSIFIERS, - keywords=" ".join(KEYWORDS), - author=AUTHOR, - author_email=EMAIL, - url=URL, - license="BSD", - packages=PACKAGES, - include_package_data=True, - zip_safe=False, - install_requires=REQUIREMENTS, - entry_points=ENTRY_POINTS, - ) +setup( + name="django-downloadview-demo", + version="1.0", + description="Serve files with Django and reverse-proxies.", + long_description=open(os.path.join(here, "README.rst")).read(), + classifiers=[ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python :: 3", + "Framework :: Django", + ], + author="Benoît Bryon", + author_email="benoit@marmelune.net", + url="https://django-downloadview.readthedocs.io/", + license="BSD", + packages=["demoproject"], + include_package_data=True, + zip_safe=False, + install_requires=["django-downloadview", "django-nose"], + entry_points={"console_scripts": ["demo = demoproject.manage:main"]}, +) diff --git a/docs/conf.py b/docs/conf.py index 3c77bb7..ef3a7ab 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,6 +2,7 @@ """django-downloadview documentation build configuration file.""" import os import re +from pkg_resources import get_distribution # Minimal Django settings. Required to use sphinx.ext.autodoc, because # django-downloadview depends on Django... @@ -45,14 +46,11 @@ # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -configuration_dir = os.path.dirname(__file__) -documentation_dir = configuration_dir -version_file = os.path.normpath(os.path.join(documentation_dir, "../VERSION")) # The full version, including alpha/beta/rc tags. -release = open(version_file).read().strip() +release = get_distribution("django-downloadview").version # The short X.Y version. -version = ".".join(release.split(".")[0:1]) +version = '.'.join(release.split('.')[:2]) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index 8ad5aa1..10622dd 100644 --- a/setup.py +++ b/setup.py @@ -1,98 +1,62 @@ -#!/usr/bin/env python -"""Python packaging.""" import os -import sys - from setuptools import setup -from setuptools.command.test import test as TestCommand - - -class Tox(TestCommand): - """Test command that runs tox.""" - - def finalize_options(self): - TestCommand.finalize_options(self) - self.test_args = [] - self.test_suite = True - - def run_tests(self): - import tox # import here, cause outside the eggs aren't loaded. - - errno = tox.cmdline(self.test_args) - sys.exit(errno) - #: Absolute path to directory containing setup.py file. here = os.path.abspath(os.path.dirname(__file__)) - -NAME = "django-downloadview" -DESCRIPTION = "Serve files with Django and reverse-proxies." -README = open(os.path.join(here, "README.rst")).read() -VERSION = open(os.path.join(here, "VERSION")).read().strip() -AUTHOR = "Benoît Bryon" -EMAIL = "benoit@marmelune.net" -LICENSE = "BSD" -URL = "https://{name}.readthedocs.io/".format(name=NAME) -CLASSIFIERS = [ - "Development Status :: 5 - Production/Stable", - "Framework :: Django", - "License :: OSI Approved :: BSD License", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", -] -KEYWORDS = [ - "file", - "stream", - "download", - "FileField", - "ImageField", - "x-accel", - "x-accel-redirect", - "x-sendfile", - "sendfile", - "mod_xsendfile", - "offload", -] -PACKAGES = [NAME.replace("-", "_")] -REQUIREMENTS = [ - # BEGIN requirements - "Django>=1.11", - "requests", - "setuptools", - # END requirements -] -ENTRY_POINTS = {} -SETUP_REQUIREMENTS = ["setuptools"] -TEST_REQUIREMENTS = ["tox"] -CMDCLASS = {"test": Tox} -EXTRA_REQUIREMENTS = { - "test": TEST_REQUIREMENTS, -} - - -if __name__ == "__main__": # Don't run setup() when we import this module. - setup( - name=NAME, - version=VERSION, - description=DESCRIPTION, - long_description=README, - classifiers=CLASSIFIERS, - keywords=" ".join(KEYWORDS), - author=AUTHOR, - author_email=EMAIL, - url=URL, - license=LICENSE, - packages=PACKAGES, - include_package_data=True, - zip_safe=False, - install_requires=REQUIREMENTS, - entry_points=ENTRY_POINTS, - tests_require=TEST_REQUIREMENTS, - cmdclass=CMDCLASS, - setup_requires=SETUP_REQUIREMENTS, - extras_require=EXTRA_REQUIREMENTS, - ) +setup( + name="django-downloadview", + use_scm_version={"version_scheme": "post-release"}, + setup_requires=["setuptools_scm"], + description="Serve files with Django and reverse-proxies.", + long_description=open(os.path.join(here, "README.rst")).read(), + long_description_content_type='text/x-rst', + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Framework :: Django", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + ], + keywords=" ".join( + [ + "file", + "stream", + "download", + "FileField", + "ImageField", + "x-accel", + "x-accel-redirect", + "x-sendfile", + "sendfile", + "mod_xsendfile", + "offload", + ] + ), + author="Benoît Bryon", + author_email="benoit@marmelune.net", + url="https://django-downloadview.readthedocs.io/", + license="BSD", + packages=[ + "django_downloadview", + "django_downloadview.apache", + "django_downloadview.lighttpd", + "django_downloadview.nginx", + "django_downloadview.views", + ], + include_package_data=True, + zip_safe=False, + install_requires=[ + # BEGIN requirements + "Django>=1.11", + "requests", + "setuptools", + # END requirements + ], + extras_require={ + "test": ["tox"], + }, +) diff --git a/tests/packaging.py b/tests/packaging.py index 1b79bdb..b8fbced 100644 --- a/tests/packaging.py +++ b/tests/packaging.py @@ -44,17 +44,3 @@ def test_version_match(self): "installed version in development environment." % (self.get_version(), installed_version), ) - - def test_version_file(self): - """django_downloadview.__version__ matches VERSION file info.""" - version_file = os.path.join(project_dir, "VERSION") - file_version = open(version_file).read().strip() - self.assertEqual( - file_version, - self.get_version(), - "Version mismatch: django_downloadview.__version__ " - 'is "%s" whereas VERSION file tells "%s". ' - "You may need to run ``make develop`` to update the " - "installed version in development environment." - % (self.get_version(), file_version), - ) diff --git a/tox.ini b/tox.ini index 531f53b..9e48ed5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,34 +1,49 @@ [tox] -envlist = py{36,37,38,39}-django{22,30,31}, - flake8, sphinx, readme +envlist = + py{36,37,38,39}-dj{22,30,31,master} + lint + sphinx + readme -[travis] -python= - 3.8: py38, flake8, sphinx, readme +[gh-actions] +python = + 3.6: py36 + 3.7: py37 + 3.8: py38, lint, sphinx, readme + 3.9: py39 + +[gh-actions:env] +DJANGO = + 2.2: dj22 + 3.0: dj30 + 3.1: dj31 + master: djmaster [testenv] deps = coverage - django22: Django>=2.2,<3.0 - django30: Django>=3.0,<3.1 - django31: Django>=3.1,<3.2 + dj22: Django>=2.2,<3.0 + dj30: Django>=3.0,<3.1 + dj31: Django>=3.1,<3.2 + djmaster: https://github.com/django/django/archive/master.tar.gz nose - py27: mock commands = pip install -e . pip install -e demo - python -Wd {envbindir}/demo test --cover-package=django_downloadview --cover-package=demoproject {posargs: tests demoproject} + python -Wd {envbindir}/demo test --cover-package=django_downloadview --cover-package=demoproject --cover-xml {posargs: tests demoproject} pip freeze +ignore_outcome = + djmaster: True -[testenv:flake8] +[testenv:lint] deps = flake8 - black - isort + black + isort commands = flake8 demo django_downloadview tests - black --check demo django_downloadview tests - isort --check-only --recursive demo django_downloadview tests + black --check demo django_downloadview tests + isort --check-only --recursive demo django_downloadview tests [testenv:sphinx] deps = @@ -40,22 +55,11 @@ whitelist_externals = make [testenv:readme] -deps = - docutils - pygments -commands = - mkdir -p var/docs - rst2html.py --exit-status=2 README.rst var/docs/README.html - rst2html.py --exit-status=2 CONTRIBUTING.rst var/docs/CONTRIBUTING.html -whitelist_externals = - mkdir - -[testenv:release] -deps = - wheel - zest.releaser +description = Ensure README renders on PyPI +deps = twine commands = - fullrelease + {envpython} setup.py -q sdist bdist_wheel + twine check dist/* [flake8] max-line-length = 88