Publish Python π distribution π¦ to PyPI and TestPyPI workflow (pyannote/pyannote-database)
The Publish Python π distribution π¦ to PyPI and TestPyPI workflow from pyannote/pyannote-database, explained and optimized by Latchkey.
CI health: F - at risk
Point runs-on at Latchkey and get caching, run de-duplication, job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Publish Python π distribution π¦ to PyPI and TestPyPI workflow from the pyannote/pyannote-database repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Publish Python π distribution π¦ to PyPI and TestPyPI
on: push
jobs:
build:
name: Build distribution π¦
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: uv.lock
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: ".python-version"
- name: Build
run: uv build
- name: Store the distribution packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
publish-to-pypi:
name: >-
Publish Python π distribution π¦ to PyPI
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
needs:
- build
runs-on: ubuntu-latest
environment:
name: pypi
permissions:
id-token: write
steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: uv.lock
- name: Publish distribution π¦ to PyPI
run: uv publish --trusted-publishing always --publish-url https://upload.pypi.org/legacy/
github-release:
name: >-
Sign the Python π distribution π¦ with Sigstore
and upload them to GitHub Release
needs:
- publish-to-pypi
runs-on: ubuntu-latest
permissions:
contents: write # IMPORTANT: mandatory for making GitHub Releases
id-token: write # IMPORTANT: mandatory for sigstore
steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Sign the dists with Sigstore
uses: sigstore/gh-action-sigstore-python@v3.0.0
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release create
"$GITHUB_REF_NAME"
--repo "$GITHUB_REPOSITORY"
--notes ""
- name: Upload artifact signatures to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
# Upload to GitHub Release using the `gh` CLI.
# `dist/` contains the built packages, and the
# sigstore-produced signatures and certificates.
run: >-
gh release upload
"$GITHUB_REF_NAME" dist/**
--repo "$GITHUB_REPOSITORY"
# publish-to-testpypi:
# name: Publish Python π distribution π¦ to TestPyPI
# needs:
# - build
# runs-on: ubuntu-latest
#
# environment:
# name: testpypi
#
# permissions:
# id-token: write # IMPORTANT: mandatory for trusted publishing
#
# steps:
# - name: Download all the dists
# uses: actions/download-artifact@v4
# with:
# name: python-package-distributions
# path: dist/
# - name: Install uv
# uses: astral-sh/setup-uv@v5
# with:
# enable-cache: true
# cache-dependency-glob: uv.lock
# - name: Publish distribution π¦ to PyPI
# run: uv publish --trusted-publishing always --publish-url https://test.pypi.org/legacy/
The same workflow, on Latchkey
Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.
name: Publish Python π distribution π¦ to PyPI and TestPyPI on: push concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: timeout-minutes: 30 name: Build distribution π¦ runs-on: latchkey-small steps: - uses: actions/checkout@v4 with: persist-credentials: false fetch-depth: 0 - name: Install uv uses: astral-sh/setup-uv@v5 with: enable-cache: true cache-dependency-glob: uv.lock - name: Set up Python uses: actions/setup-python@v5 with: cache: 'pip' python-version-file: ".python-version" - name: Build run: uv build - name: Store the distribution packages uses: actions/upload-artifact@v4 with: name: python-package-distributions path: dist/ publish-to-pypi: timeout-minutes: 30 name: >- Publish Python π distribution π¦ to PyPI if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes needs: - build runs-on: latchkey-small environment: name: pypi permissions: id-token: write steps: - name: Download all the dists uses: actions/download-artifact@v4 with: name: python-package-distributions path: dist/ - name: Install uv uses: astral-sh/setup-uv@v5 with: enable-cache: true cache-dependency-glob: uv.lock - name: Publish distribution π¦ to PyPI run: uv publish --trusted-publishing always --publish-url https://upload.pypi.org/legacy/ github-release: timeout-minutes: 30 name: >- Sign the Python π distribution π¦ with Sigstore and upload them to GitHub Release needs: - publish-to-pypi runs-on: latchkey-small permissions: contents: write # IMPORTANT: mandatory for making GitHub Releases id-token: write # IMPORTANT: mandatory for sigstore steps: - name: Download all the dists uses: actions/download-artifact@v4 with: name: python-package-distributions path: dist/ - name: Sign the dists with Sigstore uses: sigstore/gh-action-sigstore-python@v3.0.0 with: inputs: >- ./dist/*.tar.gz ./dist/*.whl - name: Create GitHub Release env: GITHUB_TOKEN: ${{ github.token }} run: >- gh release create "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --notes "" - name: Upload artifact signatures to GitHub Release env: GITHUB_TOKEN: ${{ github.token }} # Upload to GitHub Release using the `gh` CLI. # `dist/` contains the built packages, and the # sigstore-produced signatures and certificates. run: >- gh release upload "$GITHUB_REF_NAME" dist/** --repo "$GITHUB_REPOSITORY" # publish-to-testpypi: # name: Publish Python π distribution π¦ to TestPyPI # needs: # - build # runs-on: latchkey-small # # environment: # name: testpypi # # permissions: # id-token: write # IMPORTANT: mandatory for trusted publishing # # steps: # - name: Download all the dists # uses: actions/download-artifact@v4 # with: # name: python-package-distributions # path: dist/ # - name: Install uv # uses: astral-sh/setup-uv@v5 # with: # enable-cache: true # cache-dependency-glob: uv.lock # - name: Publish distribution π¦ to PyPI # run: uv publish --trusted-publishing always --publish-url https://test.pypi.org/legacy/
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Cache dependency installs on the setup step so they are served from cache.
- Add a job timeout so a hung step cannot burn hours of runner time.
2 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
This workflow runs 3 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.