diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 695439d..0a03466 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -4,16 +4,17 @@ on: push jobs: test: - runs-on: ubuntu-latest strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -24,23 +25,25 @@ jobs: run: tox -e py deploy: - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') runs-on: ubuntu-latest + needs: test steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: - python-version: '3.7' + python-version: '3.9' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twine + python -m pip install build twine - name: Build and publish env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - python setup.py sdist bdist_wheel + python -m build twine upload dist/* diff --git a/.gitignore b/.gitignore index 4fc39fb..d88b343 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,4 @@ dmypy.json .pyre/ # Offline version file -mlx/__version__.py +mlx/jira_traceability/_version.py diff --git a/mlx/__init__.py b/mlx/__init__.py deleted file mode 100644 index 7933d72..0000000 --- a/mlx/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -__import__('pkg_resources').declare_namespace(__name__) diff --git a/mlx/jira_traceability/__init__.py b/mlx/jira_traceability/__init__.py new file mode 100644 index 0000000..2879fab --- /dev/null +++ b/mlx/jira_traceability/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +"""Sphinx plugin to create Jira tickets based on traceable items.""" + +from .jira_traceability import setup + +try: + from ._version import __version__ +except ImportError: + __version__ = "unknown" + +__all__ = ['setup', '__version__'] diff --git a/mlx/jira_interaction.py b/mlx/jira_traceability/jira_interaction.py similarity index 100% rename from mlx/jira_interaction.py rename to mlx/jira_traceability/jira_interaction.py diff --git a/mlx/jira_traceability.py b/mlx/jira_traceability/jira_traceability.py similarity index 100% rename from mlx/jira_traceability.py rename to mlx/jira_traceability/jira_traceability.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..85f1ae5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,61 @@ +[build-system] +requires = ["setuptools>=77.0", "setuptools-scm>=8.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "mlx.jira-traceability" +dynamic = ["version"] +authors = [ + {name = "Jasper Craeghs", email = "jce@melexis.com"}, +] +description = "Sphinx plugin to create Jira tickets based on traceable items" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.9" +classifiers = [ + "Development Status :: 4 - Beta", + "Framework :: Sphinx :: Extension", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Documentation :: Sphinx", + "Topic :: Software Development :: Bug Tracking", + "Topic :: Utilities", +] +keywords = ["traceability", "jira", "sphinx"] +dependencies = [ + "Sphinx>=2.1", + "jira>=3.2.0", + "mlx.traceability>=11.0.0", +] + +[project.urls] +Homepage = "https://github.com/melexis/jira-traceability" +Repository = "https://github.com/melexis/jira-traceability" +Issues = "https://github.com/melexis/jira-traceability/issues" + +[tool.setuptools] +zip-safe = false +include-package-data = true + +[tool.setuptools.packages.find] +namespaces = true + +[tool.setuptools_scm] +write_to = "mlx/jira_traceability/_version.py" +version_scheme = "no-guess-dev" + +[tool.pytest.ini_options] +norecursedirs = ".tox" + +[tool.flake8] +exclude = [".git", "*conf.py", "build", "dist"] +max-line-length = 120 + +[tool.check-manifest] +ignore = ["*.yml"] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 51e81d9..0000000 --- a/setup.cfg +++ /dev/null @@ -1,16 +0,0 @@ -[metadata] -description-file = README.rst - -[bdist_wheel] -universal=1 - -[tool:pytest] -norecursedirs= .tox - -[flake8] -exclude = .git,*conf.py,build,dist -max-line-length = 120 - -[check-manifest] -ignore= - *.yml diff --git a/setup.py b/setup.py deleted file mode 100644 index d6cac11..0000000 --- a/setup.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- - -from setuptools import setup, find_packages - -project_url = 'https://github.com/melexis/jira-traceability' - -requires = ['Sphinx>=2.1', 'jira>=3.1.1', 'mlx.traceability>=9.0.0'] - -setup( - name='mlx.jira-traceability', - use_scm_version={ - 'write_to': 'mlx/__version__.py' - }, - setup_requires=['setuptools_scm'], - url=project_url, - license='Apache License, Version 2.0', - author='Jasper Craeghs', - author_email='jce@melexis.com', - description='Sphinx plugin to create Jira tickets based on traceable items', - long_description=open("README.rst").read(), - long_description_content_type='text/x-rst', - zip_safe=False, - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Framework :: Sphinx :: Extension', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', - 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Topic :: Documentation :: Sphinx', - 'Topic :: Software Development :: Bug Tracking', - 'Topic :: Utilities', - ], - platforms='any', - packages=find_packages(exclude=['tests', 'doc']), - include_package_data=True, - install_requires=requires, - python_requires='>=3.7', - namespace_packages=['mlx'], - keywords=[ - 'traceability', - 'jira', - 'sphinx', - ], -) diff --git a/tests/test_jira_interaction.py b/tests/test_jira_interaction.py index 047d8c7..b617146 100644 --- a/tests/test_jira_interaction.py +++ b/tests/test_jira_interaction.py @@ -4,10 +4,8 @@ from jira import JIRAError -from mlx.traceable_attribute import TraceableAttribute -from mlx.traceable_collection import TraceableCollection -from mlx.traceable_item import TraceableItem -import mlx.jira_interaction as dut +from mlx.traceability import TraceableAttribute, TraceableCollection, TraceableItem +import mlx.jira_traceability.jira_interaction as dut def produce_fake_users(**kwargs): @@ -21,7 +19,7 @@ def produce_fake_users(**kwargs): return users -@mock.patch('mlx.jira_interaction.JIRA') +@mock.patch('mlx.jira_traceability.jira_interaction.JIRA') class TestJiraInteraction(TestCase): def setUp(self): self.general_fields = { @@ -86,7 +84,7 @@ def test_missing_endpoint(self, *_): dut.create_jira_issues(self.settings, None) self.assertEqual( cm.output, - ["WARNING:sphinx.mlx.jira_interaction:Jira interaction failed: configuration is " + ["WARNING:sphinx.mlx.jira_traceability.jira_interaction:Jira interaction failed: configuration is " "missing mandatory values for keys ['api_endpoint']"] ) @@ -96,7 +94,7 @@ def test_missing_username(self, *_): dut.create_jira_issues(self.settings, None) self.assertEqual( cm.output, - ["WARNING:sphinx.mlx.jira_interaction:Jira interaction failed: configuration is " + ["WARNING:sphinx.mlx.jira_traceability.jira_interaction:Jira interaction failed: configuration is " "missing mandatory values for keys ['username']"] ) @@ -108,7 +106,7 @@ def test_missing_all_mandatory(self, *_): dut.create_jira_issues(self.settings, None) self.assertEqual( cm.output, - ["WARNING:sphinx.mlx.jira_interaction:Jira interaction failed: configuration is " + ["WARNING:sphinx.mlx.jira_traceability.jira_interaction:Jira interaction failed: configuration is " "missing mandatory values for keys {}".format(mandatory_keys)] ) @@ -121,7 +119,7 @@ def test_missing_all_optional_one_mandatory(self, *_): dut.create_jira_issues(self.settings, None) self.assertEqual( cm.output, - ["WARNING:sphinx.mlx.jira_interaction:Jira interaction failed: configuration is " + ["WARNING:sphinx.mlx.jira_traceability.jira_interaction:Jira interaction failed: configuration is " "missing mandatory values for keys ['password']"] ) @@ -244,10 +242,10 @@ def test_prevent_duplication(self, jira): self.assertEqual( cm.output, - ["WARNING:sphinx.mlx.jira_interaction:Won't create a Task for item " + ["WARNING:sphinx.mlx.jira_traceability.jira_interaction:Won't create a Task for item " "'ACTION-12345_ACTION_1' because the Jira API query to check to prevent " "duplication returned ['Jira already contains this ticket']", - "WARNING:sphinx.mlx.jira_interaction:Won't create a Task for item " + "WARNING:sphinx.mlx.jira_traceability.jira_interaction:Won't create a Task for item " "'ACTION-12345_ACTION_2' because the Jira API query to check to prevent " "duplication returned ['Jira already contains this ticket']"] ) @@ -307,8 +305,8 @@ def jira_add_watcher_mock(*_): with self.assertLogs(level=WARNING) as cm: dut.create_jira_issues(self.settings, self.coll) - error_msg = ("WARNING:sphinx.mlx.jira_interaction:Jira interaction failed: item ACTION-12345_ACTION_1: " - "error code 401: dummy msg") + error_msg = ("WARNING:sphinx.mlx.jira_traceability.jira_interaction:Jira interaction failed: " + "item ACTION-12345_ACTION_1: error code 401: dummy msg") self.assertEqual( cm.output, [error_msg, error_msg] diff --git a/tox.ini b/tox.ini index a0309f0..e87bf7e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,34 +1,36 @@ [tox] envlist = - py37, py38, py39, py10 + py39, py310, py311, py312, py313 clean, check, - {py37}, + {py39}, requires = pip>=20.3.4 [gh-actions] python = - 3.7: py37 - 3.8: py38 3.9: py39 3.10: py310 + 3.11: py311 + 3.12: py312 + 3.13: py313 [testenv] basepython = py: python3 pypy: {env:TOXPYTHON:pypy} - py37: {env:TOXPYTHON:python3.7} - py38: {env:TOXPYTHON:python3.8} py39: {env:TOXPYTHON:python3.9} py310: {env:TOXPYTHON:python3.10} + py311: {env:TOXPYTHON:python3.11} + py312: {env:TOXPYTHON:python3.12} + py313: {env:TOXPYTHON:python3.13} {clean,check,report,coveralls,codecov}: python3 setenv = PYTHONPATH={toxinidir}/tests PYTHONUNBUFFERED=yes passenv = * -usedevelop = false +usedevelop = true deps= mock pytest @@ -42,16 +44,16 @@ commands= [testenv:check] deps = - docutils + build twine check-manifest flake8 skip_install = true commands = - python setup.py sdist + python -m build twine check dist/* check-manifest {toxinidir} -u - flake8 mlx tests setup.py + flake8 mlx tests [testenv:coveralls] deps =