From 9e11cfcc9c66221165123b19f285131fd6002b93 Mon Sep 17 00:00:00 2001 From: Eiichi YAMAMOTO Date: Sat, 1 Aug 2026 12:53:28 +0900 Subject: [PATCH] ci: release with python semantic release --- .github/workflows/pypi.yml | 41 +++++++++++++++++++++---------------- docs/source/development.rst | 27 ++++++++++++++---------- pyproject.toml | 6 ++++++ 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 514e5ac..0cddd7b 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -1,46 +1,51 @@ -name: Publish to PyPI +name: Release on: push: - tags: - - "v*" + branches: + - main + workflow_dispatch: permissions: contents: read jobs: - build: - name: Build distributions + release: + name: Python Semantic Release runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: false + permissions: + contents: write steps: - name: Check out repository uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 with: - python-version: "3.12" - cache: pip + fetch-depth: 0 - - name: Build and check distributions - run: | - python -m pip install --upgrade pip - python -m pip install build twine - python -m build - python -m twine check dist/* + - name: Run Python Semantic Release + id: release + uses: python-semantic-release/python-semantic-release@v10.5.3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} - name: Upload distributions + if: steps.release.outputs.released == 'true' uses: actions/upload-artifact@v4 with: name: python-package-distributions path: dist/ if-no-files-found: error + outputs: + released: ${{ steps.release.outputs.released }} publish: - name: Publish distributions + name: Publish to PyPI needs: - - build + - release + if: needs.release.outputs.released == 'true' runs-on: ubuntu-latest environment: name: pypi diff --git a/docs/source/development.rst b/docs/source/development.rst index 4d56f78..490ca62 100644 --- a/docs/source/development.rst +++ b/docs/source/development.rst @@ -24,9 +24,14 @@ The generated HTML files will be in `docs/build/html`. Release publishing ------------------ -PyPI publishing is handled by GitHub Actions when a version tag is pushed. -The workflow uses PyPI Trusted Publishing, so no long-lived PyPI API token is -stored in GitHub. +Release versioning and tagging are handled by Python Semantic Release in +GitHub Actions. When commits land on ``main``, Semantic Release evaluates the +commit history, updates ``pyproject.toml`` and ``CHANGELOG.rst`` when a new +version is due, creates the version tag and GitHub release, and builds the +package distributions. + +PyPI publishing then uses PyPI Trusted Publishing, so no long-lived PyPI API +token is stored in GitHub. Before the first automated publish, configure a Trusted Publisher for the ``csvsmith`` project on PyPI with these values: @@ -36,16 +41,16 @@ Before the first automated publish, configure a Trusted Publisher for the - Workflow name: ``pypi.yml`` - Environment name: ``pypi`` -To publish a release, make sure ``pyproject.toml`` contains the intended -version, then create and push the matching tag: - -.. code-block:: bash +To publish a release, merge commits using Conventional Commit messages such as +``feat: ...`` or ``fix: ...``. The release workflow runs after the merge to +``main``: - git tag v0.10.0 - git push origin v0.10.0 +- ``feat`` creates a minor release. +- ``fix`` creates a patch release. +- breaking changes create a major release. -The PyPI workflow builds the source distribution and wheel, checks them with -Twine, and publishes them to PyPI. +If no release-worthy commits are present, the workflow exits without creating +a release or publishing to PyPI. Contributing ------------ diff --git a/pyproject.toml b/pyproject.toml index 1031590..104a985 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,8 +54,14 @@ where = ["src"] [tool.semantic_release] allow_zero_version = true +build_command = "python -m pip install build twine && python -m build && python -m twine check dist/*" tag_format = "v{version}" version_toml = ["pyproject.toml:project.version"] +[tool.semantic_release.changelog] +mode = "update" +insertion_flag = "..\n version list" + [tool.semantic_release.changelog.default_templates] changelog_file = "CHANGELOG.rst" +output_format = "rst"