diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 1280a01..01784ec 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -7,34 +7,33 @@ on: branches: [main] jobs: - build: - + lint: runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Install Hatch + run: pipx install hatch + - name: Lint + run: hatch run dev:lint + - name: Type Check + run: hatch run dev:typecheck + tests: + runs-on: ${{ matrix.os }} strategy: matrix: python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] - + os: [ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install .[tests] - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 delphin --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. PEP-8 says 99 chars is a good width - flake8 delphin --count --exit-zero --extend-ignore E221 --max-line-length=99 --statistics - # E221 = whitespace before operator - # disabled for now: --max-complexity=10 - - name: Test with pytest - run: | - pytest . - - name: Type-check with mypy - run: | - mypy delphin --namespace-packages --explicit-package-bases --ignore-missing-imports + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install Hatch + run: pipx install hatch + - name: Test + run: hatch run dev:test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..76754b9 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,68 @@ +name: Build and Publish to PyPI or TestPyPI + +# Adapted from https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/ + +on: + push + +jobs: + build: + name: Build distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + - name: Install Hatch + run: pipx install hatch + - name: Build + run: hatch build + - name: Store the distribution packages + uses: actions/upload-artifact@v3 + with: + name: python-package-distributions + path: dist/ + + publish-to-pypi: + name: Publish distributions to PyPI + if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes + needs: + - build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/PyDelphin + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + steps: + - name: Download the dists + uses: actions/download-artifact@v3 + with: + name: python-package-distributions + path: dist/ + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + publish-to-testpypi: + name: Publish distributions to TestPyPI + needs: + - build + runs-on: ubuntu-latest + environment: + name: testpypi + url: https://test.pypi.org/p/PyDelphin + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + steps: + - name: Download the dists + uses: actions/download-artifact@v3 + with: + name: python-package-distributions + path: dist/ + - name: Publish to TestPyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + skip-existing: true diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml deleted file mode 100644 index 0bc0d48..0000000 --- a/.github/workflows/pythonpublish.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Upload Python Package - -on: - release: - types: [created] - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install "setuptools >= 67" "wheel >= 0.40" "twine >= 4" - - 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/pyproject.toml b/pyproject.toml index 2f21011..4c45c91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,86 @@ [build-system] -requires = ["setuptools>=40.8.0", "wheel"] -build-backend = "setuptools.build_meta" +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "PyDelphin" +dynamic = ["version"] +description = "Libraries and scripts for DELPH-IN data" +readme = "README.md" +requires-python = ">=3.8" +license = "MIT" +authors = [ + {name = "Michael Wayne Goodman", email = "goodman.m.w@gmail.com"} +] +keywords = ["nlp", "semantics", "hpsg", "delph-in", "linguistics"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Developers", + "Intended Audience :: Information Technology", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Text Processing :: Linguistic", + "Topic :: Utilities", +] +dependencies = [ + "penman", + "progress", + "Pygments", +] + +[project.optional-dependencies] +web = [ + "falcon", + "requests", +] +repp = [ + "regex" +] + +[projects.scripts] +delphin = "delphin.main:main" + +[project.urls] +Homepage = "https://github.com/delph-in/pydelphin" +Documentation = "https://pydelphin.readthedocs.io" +Changelog = "https://github.com/delph-in/pydelphin/blob/main/CHANGELOG.md" + +[tool.hatch.version] +path = "delphin/__about__.py" + +[tool.hatch.build.targets.sdist] +exclude = [ + "/.github", +] + +[tool.hatch.envs.dev] +dependencies = [ + "pytest", + "flake8", + "mypy", + "types-requests", +] +[tool.hatch.envs.dev.scripts] +test = "pytest {args:.}" +lint = "flake8 delphin --count --exit-zero --extend-ignore=E221 --max-line-length=99 --statistics" +typecheck = "mypy delphin --namespace-packages --explicit-package-bases --ignore-missing-imports" + +[tool.hatch.envs.docs] +dependencies = [ + "sphinx", + "sphinx-rtd-theme", + "requests", + "falcon", +] +[tool.hatch.envs.docs.scripts] +build = "make -C docs html" +clean = "make -C docs clean" diff --git a/setup.py b/setup.py deleted file mode 100755 index f1152dd..0000000 --- a/setup.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python3 - -import os -from setuptools import setup - -base_dir = os.path.dirname(__file__) -about = {} -with open(os.path.join(base_dir, "delphin", "__about__.py")) as f: - exec(f.read(), about) - -with open(os.path.join(base_dir, 'README.md'), encoding='utf-8') as f: - long_description = f.read() - -repp_requires = ['regex==2020.1.8'] -web_requires = ['requests==2.22.0', 'falcon==2.0.0'] - -# thanks: https://snarky.ca/clarifying-pep-518/ -doc_requirements = os.path.join(base_dir, 'docs', 'requirements.txt') -if os.path.isfile(doc_requirements): - with open(doc_requirements) as f: - docs_require = f.readlines() -else: - docs_require = [] - -tests_require = repp_requires + web_requires + [ - 'pytest', - 'flake8', - 'mypy', - 'types-requests', -] - -setup( - name=about['__title__'], - version=about['__version__'], - description=about['__summary__'], - long_description=long_description, - long_description_content_type='text/markdown', - url=about['__uri__'], - author=about['__author__'], - author_email=about['__email__'], - license=about['__license__'], - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Topic :: Scientific/Engineering :: Information Analysis', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: Text Processing :: Linguistic', - 'Topic :: Utilities' - ], - keywords='nlp semantics hpsg delph-in linguistics', - packages=[ - 'delphin', - 'delphin.cli', - 'delphin.codecs', - 'delphin.mrs', - 'delphin.eds', - 'delphin.dmrs', - 'delphin.web', - ], - install_requires=[ - 'penman==1.1.0', - 'progress==1.5', - 'Pygments >= 2.3.1', - ], - extras_require={ - 'docs': docs_require, - 'tests': tests_require, - 'dev': docs_require + tests_require + [ - # https://packaging.python.org/guides/making-a-pypi-friendly-readme - 'setuptools >= 38.6.0', - 'wheel >= 0.31.0', - 'twine >= 1.11.0' - ], - 'web': web_requires, - 'repp': repp_requires, - }, - entry_points={ - 'console_scripts': [ - 'delphin=delphin.main:main' - ], - }, -)