diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml new file mode 100644 index 0000000..bbd0831 --- /dev/null +++ b/.github/workflows/pypi.yml @@ -0,0 +1,82 @@ +name: Publish Python distribution to PyPI and TestPyPI +# Source: +# https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/ +on: + push: + branches: + - main + tags: + - 'v*' +jobs: + build: + name: Build distribution package + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + - name: Install pypa/build + run: python3 -m pip install build --user + - name: Add untagged version suffix + if: ${{ ! startsWith(github.ref, 'refs/tags/v') }} + run: python3 version.py update ${{ github.sha }} + - name: Build a binary wheel and a source tarball + run: python3 -m build + - name: Store the distribution packages + uses: actions/upload-artifact@v4 + with: + name: python-package-distributions + path: dist/ + version-check: + name: Check for version match in git tag and unmagic.__version__ + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + - name: Install pytest-unmagic + run: python3 -m pip install --user -e . + - name: Check version + run: python3 version.py check "${{ github.ref }}" + pypi-publish: + name: Upload release to PyPI + needs: [build, version-check] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + environment: + name: pypi + url: https://pypi.org/p/pytest-unmagic + permissions: + id-token: write + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + pypi-test-publish: + name: Upload release to test PyPI + needs: [build] + runs-on: ubuntu-latest + environment: + name: testpypi + url: https://test.pypi.org/p/pytest-unmagic + permissions: + id-token: write + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ diff --git a/.gitignore b/.gitignore index bee8a64..098b60f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__ +/dist diff --git a/README.md b/README.md index 3a3ac0a..a2321c9 100644 --- a/README.md +++ b/README.md @@ -193,3 +193,14 @@ cd path/to/pytest-unmagic pip install -e . pytest ``` + + +## Publishing a new verison to PyPI + +Push a new tag to Github using the format vX.Y.Z where X.Y.Z matches the version +in [`__init__.py`](src/unmagic/__init__.py). + +A new version is published to https://test.pypi.org/p/pytest-unmagic on every +push to the *main* branch. + +Publishing is automated with [Github Actions](.github/workflows/pypi.yml). diff --git a/pyproject.toml b/pyproject.toml index 7b1c3c4..6e2569b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,6 +2,7 @@ name = "pytest-unmagic" authors = [{name = "Daniel Miller", email = "millerdev@gmail.com"}] license = {file = "LICENSE"} +readme = {file = "README.md", content-type = "text/markdown"} dynamic = ["version", "description"] requires-python = ">= 3.9" classifiers = [ @@ -10,6 +11,10 @@ classifiers = [ "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3", "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 :: Software Development :: Libraries", "Topic :: Software Development :: Testing", ] diff --git a/version.py b/version.py new file mode 100644 index 0000000..3ba509d --- /dev/null +++ b/version.py @@ -0,0 +1,39 @@ +"""Check for version match between github tag and __init__.py""" +import re +import sys +import unmagic + + +def main(argv=sys.argv): + if len(argv) < 3: + sys.exit(f"usage: {argv[0]} (check|set-dev) ARG") + cmd, arg, *ignore = sys.argv[1:] + if cmd == "check": + check(arg) + elif cmd == "update": + update(arg) + else: + sys.exit(f"unknown arguments: {argv[1:]}") + + +def check(ref): + if not ref.startswith("refs/tags/v"): + sys.exit(f"unexpected ref: {ref}") + version = ref.removeprefix("refs/tags/v") + if version != unmagic.__version__: + sys.exit(f"version mismatch: {version} != {unmagic.__version__}") + + +def update(commit_hash): + version = f"{unmagic.__version__}+{commit_hash}" + print("new version:", version) + vexpr = re.compile(r"(?<=^__version__ = ).+$", flags=re.MULTILINE) + with open(unmagic.__file__, "r+") as file: + text = file.read() + file.seek(0) + file.write(vexpr.sub(repr(version), text)) + file.truncate() + + +if __name__ == "__main__": + main()