From 8d6622d8d40d2f94915079c0bd05b19efac52518 Mon Sep 17 00:00:00 2001 From: Peter Bittner Date: Tue, 18 Jun 2024 21:24:16 +0200 Subject: [PATCH] Modernize packaging and CI (pyproject.toml, Tox, GHA) --- .github/workflows/pipeline.yml | 65 ++++++++++++++++++++++++++++++++++ .travis.yml | 32 ----------------- AUTHORS.rst | 10 ++++-- README.rst | 44 +++++++++++++++++------ bootstrap/__init__.py | 9 ++--- fontawesome/__init__.py | 9 ++--- pyproject.toml | 58 ++++++++++++++++++++++++++++++ setup.cfg | 2 -- setup.py | 43 ---------------------- tests/test_packaging.py | 11 ++++++ tox.ini | 50 ++++++++++++++++++++++++++ 11 files changed, 231 insertions(+), 102 deletions(-) create mode 100644 .github/workflows/pipeline.yml delete mode 100644 .travis.yml create mode 100644 pyproject.toml delete mode 100644 setup.cfg delete mode 100644 setup.py create mode 100644 tests/test_packaging.py create mode 100644 tox.ini diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml new file mode 100644 index 0000000..4cac471 --- /dev/null +++ b/.github/workflows/pipeline.yml @@ -0,0 +1,65 @@ +name: Pipeline +on: + pull_request: + branches: + - main + push: + branches: + - main + tags: + - '[0-9]+.[0-9]+.[0-9]+' + +jobs: + check: + runs-on: ubuntu-latest + strategy: + matrix: + env: + - lint + - format + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - run: pip install tox + - run: tox run -e ${{ matrix.env }} + + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - '3.10' + - '3.11' + - '3.12' + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - run: pip install tox + - run: tox run -e py + + publish: + if: startsWith(github.ref, 'refs/tags/') + needs: + - check + - test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Install build tools + run: pip install tox + - name: Verify package version is same as Git tag + run: tox run -qe ensure_version_matches -- $GIT_TAG + env: + GIT_TAG: ${{ github.ref_name }} + - name: Build package and upload to PyPI + run: tox run -e package -- upload + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dc6975a..0000000 --- a/.travis.yml +++ /dev/null @@ -1,32 +0,0 @@ -os: linux -dist: xenial - -language: python -python: 3.7 - -stages: -- lint readme -- deploy package - -jobs: - include: - - - stage: lint readme - install: - - pip install twine - script: - - python setup.py -q sdist bdist_wheel - - twine check dist/* - - - stage: deploy package - if: tag is present - deploy: - provider: pypi - distributions: sdist bdist_wheel - username: bittner - password: - secure: bjU1AfMX/fzvBdBA1kcTZIpFoc8cQw7WnVrflSesS452rueiS+aXEk9uFaGTXffWJdP793tmkLMQh1b1hwkwC5GCNf+tEHop9E4A6n+6IS0tDAuApcRCbrIlENhzyR/yNnsBOY6aa0KpVwOFMS94SMlT+q8ZkEw4IQHcNaej9ys= - on: - tags: true - install: skip - script: skip diff --git a/AUTHORS.rst b/AUTHORS.rst index 11bed2e..e27b761 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -1,8 +1,7 @@ Maintainers ----------- -* Derek Stegelman (@dstegelman), original author -* Peter Bittner (@bittner), current maintainer +* Peter Bittner (@bittner) Contributors ------------ @@ -11,3 +10,10 @@ Contributors * Aaron VanDerlip (@aaronvanderlip) * Travis Swicegood (@tswicegood) * Pablo Castellano (@PabloCastellano) +* Amit Kumar (@umrao-ak47) +* Wolfgang Herget (@wherget) + +Original Author +--------------- + +* Derek Stegelman (@dstegelman) diff --git a/README.rst b/README.rst index b6cc284..bd637bd 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ Django Bootstrap Static Files |latest-version| ============================================== -|bootstrap| |jquery| |fontawesome| |build-status| +|bootstrap| |jquery| |fontawesome| |pipeline| Bootstrap and optional Font Awesome static files ready for the picking. @@ -20,9 +20,9 @@ Also ships the latest jQuery compatible with Bootstrap, for optional inclusion. .. |fontawesome| image:: https://img.shields.io/badge/Font_Awesome-v6.5.2-1c9a71.svg :alt: Font Awesome 6.5.2 :target: https://fontawesome.com/icons?m=free -.. |build-status| image:: https://img.shields.io/travis/bittner/django-bootstrap-static/master.svg?logo=travis +.. |pipeline| image:: https://github.com/bittner/django-bootstrap-static/actions/workflows/pipeline.yml/badge.svg :alt: Build status - :target: https://travis-ci.org/bittner/django-bootstrap-static + :target: https://github.com/bittner/django-bootstrap-static/actions/workflows/pipeline.yml Install ======= @@ -75,7 +75,7 @@ to save a few kilobytes of bandwidth. More details on integration may be available from each of the two projects: -- https://getbootstrap.com/docs/5.0/getting-started/introduction/ +- https://getbootstrap.com/docs/5.3/getting-started/introduction/ - https://fontawesome.com/get-started (`Upgrading from Version 4 of Font Awesome`_) .. _Upgrading from Version 4 of Font Awesome: @@ -91,18 +91,35 @@ Sources and Procedures ---------------------- Bootstrap: (all files from dist package) - `Bootstrap website / Download`_ -> drop into ``bootstrap/static/bootstrap/`` + `Bootstrap website / Download`_ ➜ drop into ``bootstrap/static/bootstrap/`` jQuery: (compressed, uncompressed, map) - `jQuery website / Download`_ -> rename and mix into ``bootstrap/static/bootstrap/js/`` + `jQuery website / Download`_ ➜ rename and mix into ``bootstrap/static/bootstrap/js/`` Pick the latest version denoted as a dependency in ``bower.json`` (see `Dependencies`_). Font Awesome: (content of the ``on-server/`` folder only) - `Font Awesome website / Download Free`_ -> drop into ``fontawesome/static/fontawesome/`` + `Font Awesome website / Download Free`_ ➜ drop into ``fontawesome/static/fontawesome/`` -.. _Bootstrap website / Download: https://getbootstrap.com/ -.. _jQuery website / Download: https://jquery.com/download/ -.. _Dependencies: https://getbootstrap.com/docs/5.0/getting-started/javascript/ -.. _Font Awesome website / Download Free: https://fontawesome.com/ +Tests +----- + +Tests are great! And necessary. Please, add more. More is better! +We use `Tox`_. + +.. code-block:: console + + pip install tox + +Run all the linting and tests locally using Tox like this: + +.. code-block:: console + + tox + +.. code-block:: console + + tox list + tox package + tox clean Releases ======== @@ -115,4 +132,9 @@ a new change within this package itself, e.g. ``django-bootstrap-static==3.3.1.1`` == Bootstrap ``3.3.1`` with an additional package change. +.. _Bootstrap website / Download: https://getbootstrap.com/ +.. _jQuery website / Download: https://jquery.com/download/ +.. _Dependencies: https://getbootstrap.com/docs/5.0/getting-started/javascript/ +.. _Font Awesome website / Download Free: https://fontawesome.com/ +.. _Tox: https://tox.wiki/ .. _semver: https://semver.org/ diff --git a/bootstrap/__init__.py b/bootstrap/__init__.py index ab56915..b4d310e 100644 --- a/bootstrap/__init__.py +++ b/bootstrap/__init__.py @@ -1,8 +1,5 @@ """ -A collection of Bootstrap static files. +A collection of Bootstrap static files. Font Awesome. """ -__author__ = 'Peter Bittner' -__email__ = 'django@bittner.it' -__license__ = 'MIT' -__url__ = 'https://github.com/bittner/django-bootstrap-static' -__version__ = '5.3.3' + +__version__ = "5.3.3" diff --git a/fontawesome/__init__.py b/fontawesome/__init__.py index 63dfef9..de93aed 100644 --- a/fontawesome/__init__.py +++ b/fontawesome/__init__.py @@ -1,8 +1,5 @@ """ -A collection of Bootstrap static files. +A collection of Bootstrap static files. Font Awesome. """ -__author__ = 'Peter Bittner' -__email__ = 'django@bittner.it' -__license__ = 'MIT' -__url__ = 'https://github.com/bittner/django-bootstrap-static' -__version__ = '6.5.2' + +__version__ = "6.5.2" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d5e93432 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,58 @@ +[build-system] +build-backend = "setuptools.build_meta" +requires = ["setuptools>=64", "setuptools_scm>=8"] + +[project] +name = "django-bootstrap-static" +dynamic = ["version"] +description = "A collection of Bootstrap static files." +readme = "README.rst" +license = {file = "LICENSE"} +authors = [ + {name = "Peter Bittner", email = "django@bittner.it"}, +] +maintainers = [ + {name = "Peter Bittner", email = "django@bittner.it"}, +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "Natural Language :: English", + "Operating System :: OS Independent", + "Framework :: Django", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 3", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries", + "Topic :: Utilities", + "License :: OSI Approved :: MIT License", +] +keywords=[ + "django", + "staticfiles", + "bootstrap", + "jquery", + "fontawesome", +] + +[project.urls] +source = "https://github.com/bittner/django-bootstrap-static" + +[tool.ruff] +extend-exclude = [] +extend-include = [] + +[tool.ruff.lint] +extend-select = ["ALL"] +extend-ignore = ["ANN", "D", "FBT002", "INP001", "Q000", "TRY200", "UP"] + +[tool.ruff.lint.per-file-ignores] +"tests/*.py" = ["S101"] + +[tool.setuptools] +include-package-data = true +packages = ["bootstrap", "fontawesome"] + +[tool.setuptools_scm] +local_scheme = "no-local-version" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 2a9acf1..0000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[bdist_wheel] -universal = 1 diff --git a/setup.py b/setup.py deleted file mode 100644 index 3f4c30b..0000000 --- a/setup.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Packaging setup for Django-Bootstrap-Static -""" -from setuptools import setup, find_packages - -import bootstrap as package - -setup( - name='django-bootstrap-static', - version=package.__version__, - license=package.__license__, - author=package.__author__, - author_email=package.__email__, - description=package.__doc__.strip(), - long_description=open("README.rst", "r").read(), - long_description_content_type='text/x-rst', - url=package.__url__, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "Natural Language :: English", - "Operating System :: OS Independent", - "Framework :: Django", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries", - "Topic :: Utilities", - "License :: OSI Approved :: MIT License", - ], - keywords=[ - 'django', - 'staticfiles', - 'bootstrap', - 'jquery', - 'fontawesome', - ], - packages=find_packages(), - install_requires=[], - include_package_data=True, - zip_safe=False, -) diff --git a/tests/test_packaging.py b/tests/test_packaging.py new file mode 100644 index 0000000..aa097b3 --- /dev/null +++ b/tests/test_packaging.py @@ -0,0 +1,11 @@ +"""Functional tests.""" + + +def test_imports(): + """Importing the package should work as described in the README.""" + + import bootstrap + import fontawesome + + assert bootstrap.__version__ == "5.3.3" + assert fontawesome.__version__ == "6.5.2" diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..7f4a723 --- /dev/null +++ b/tox.ini @@ -0,0 +1,50 @@ +[tox] +envlist = + lint + format + py + +[testenv] +description = Unit tests and test coverage +deps = pytest +commands = pytest {posargs} + +[testenv:clean] +description = Remove bytecode and other debris +skip_install = true +deps = pyclean +commands = pyclean {posargs:--debris .} + +[testenv:ensure_version_matches] +description = Verify package version is same as Git tag +deps = +commands = python -c 'import os; from importlib.metadata import version; pkg, tag = os.environ["PKG_NAME"], os.environ["GIT_TAG"]; ver = version(pkg); error = f"`{ver}` != `{tag}`"; abort = f"Package version does not match the Git tag ({error}). ABORTING."; raise SystemExit(0 if ver and tag and ver == tag else abort)' +setenv = + PKG_NAME=django-bootstrap-static + GIT_TAG={posargs} + +[testenv:format] +description = Ensure consistent code style (Ruff) +skip_install = true +deps = ruff +commands = ruff format {posargs:--check --diff .} + +[testenv:lint] +description = Lightening-fast linting (Ruff) +skip_install = true +deps = ruff +commands = ruff check {posargs:--output-format=full .} + +[testenv:package] +description = Build package and check metadata (or upload package) +skip_install = true +deps = + build + twine +commands = + python -m build + twine {posargs:check --strict} dist/* +passenv = + TWINE_USERNAME + TWINE_PASSWORD + TWINE_REPOSITORY_URL