From fcaec1a483314180c7f3ef0bd8798440154a23be Mon Sep 17 00:00:00 2001 From: Isaac Schepp Date: Wed, 23 Sep 2026 14:09:15 -0500 Subject: [PATCH] Prepare for PyPI: publish workflow, SPDX license, pip install feastdate Part of #11. Nothing is published by this commit. - .github/workflows/publish.yml: a pushed v* tag builds, checks that the tag matches the pyproject version, runs twine check --strict and a smoke test of the built wheel, then publishes to PyPI by Trusted Publishing (environment "pypi"). Running it by hand publishes the same build to TestPyPI (environment "testpypi"). No token is stored. - pyproject.toml: license = "MIT" with license-files, the PEP 639 form. The TOML-table form and the license classifier are deprecated in setuptools and stop building after 2027-02-18. Needs setuptools>=77. - README: pip install feastdate, git form kept for main. The LICENSE link is absolute so it works on the PyPI page. --- .github/workflows/publish.yml | 69 +++++++++++++++++++++++++++++++++++ README.md | 8 +++- pyproject.toml | 6 +-- 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..3990f8a --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,69 @@ +name: publish + +# A pushed v* tag publishes to PyPI. Running the workflow by hand publishes to +# TestPyPI instead, to check a release before tagging it. Both use Trusted +# Publishing, so no token is stored: each index has a publisher registered for +# this repository, this file and the environment named below. + +on: + push: + tags: ["v*"] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + - run: pip install build twine + - name: tag must match the version in pyproject.toml + if: github.ref_type == 'tag' + shell: bash + run: | + version=$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])') + test "v$version" = "$GITHUB_REF_NAME" || { echo "tag $GITHUB_REF_NAME != version $version"; exit 1; } + - run: python -m build + - run: twine check --strict dist/* + - name: smoke-test the built wheel + shell: bash + run: | + python -m venv /tmp/smoke + /tmp/smoke/bin/pip install dist/*.whl + /tmp/smoke/bin/feastdate "Dom. Palm. 1656" | grep -F "= Sun 30 Mar 1656 (Julian)" + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + + testpypi: + if: github.event_name == 'workflow_dispatch' + needs: build + runs-on: ubuntu-latest + environment: testpypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + + pypi: + if: github.ref_type == 'tag' + needs: build + runs-on: ubuntu-latest + environment: pypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/README.md b/README.md index a6328cc..4ea85f2 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,12 @@ It is pure Python, uses only the standard library, and runs on Python 3.9 or lat ## Install +```console +pip install feastdate +``` + +Or the latest `main` straight from GitHub: + ```console pip install git+https://github.com/isaacschepp/feastdate ``` @@ -522,4 +528,4 @@ pytest ## License -MIT. See [LICENSE](LICENSE). +MIT. See [LICENSE](https://github.com/isaacschepp/feastdate/blob/main/LICENSE). diff --git a/pyproject.toml b/pyproject.toml index d805116..928b62a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=61"] +requires = ["setuptools>=77"] build-backend = "setuptools.build_meta" [project] @@ -7,7 +7,8 @@ name = "feastdate" version = "1.7.0" description = "Convert church-year feast names from old parish registers (Dom. Palm. 1656) into calendar dates, Julian or Gregorian." readme = "README.md" -license = { file = "LICENSE" } +license = "MIT" +license-files = ["LICENSE"] authors = [{ name = "isaacschepp" }] requires-python = ">=3.9" dependencies = [] @@ -15,7 +16,6 @@ keywords = ["genealogy", "calendar", "easter", "parish registers", "julian", "gr classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Science/Research", - "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Sociology :: Genealogy",