Skip to content
Latchkey

Publish Python distribution to PyPI and TestPyPI workflow (probml/dynamax)

The Publish Python distribution to PyPI and TestPyPI workflow from probml/dynamax, explained and optimized by Latchkey.

C

CI health: C - fair

Point runs-on at Latchkey and get caching, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: probml/dynamax.github/workflows/publish-to-pypi.ymlLicense MITView source

What it does

This is the Publish Python distribution to PyPI and TestPyPI workflow from the probml/dynamax 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

workflow (.yml)
name: Publish Python distribution to PyPI and TestPyPI

on: 
  workflow_dispatch:
  
  release:
    types:
      - created

jobs:
  build:
    name: Build distribution
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      with:
        persist-credentials: false
    - name: Set up Python
      uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
      with:
        python-version: "3.x"
    - name: Install pypa/build
      run: >-
        python3 -m
        pip install
        build
        --user
    - name: Build a binary wheel and a source tarball
      run: python3 -m build
    - name: Store the distribution packages
      uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
      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
      url: https://pypi.org/p/dynamax  # Replace <package-name> with your PyPI project name
    permissions:
      id-token: write  # IMPORTANT: mandatory for trusted publishing

    steps:
    - name: Download all the dists
      uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
      with:
        name: python-package-distributions
        path: dist/
    - name: Publish distribution πŸ“¦ to PyPI
      uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0

  publish-to-testpypi:
    name: Publish Python 🐍 distribution πŸ“¦ to TestPyPI
    needs:
    - build
    runs-on: ubuntu-latest

    environment:
      name: testpypi
      url: https://test.pypi.org/p/dynamax

    permissions:
      id-token: write  # IMPORTANT: mandatory for trusted publishing

    steps:
    - name: Download all the dists
      uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
      with:
        name: python-package-distributions
        path: dist/
    - name: Publish distribution πŸ“¦ to TestPyPI
      uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
      with:
        repository-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: 
  workflow_dispatch:
  
  release:
    types:
      - created
 
jobs:
  build:
    timeout-minutes: 30
    name: Build distribution
    runs-on: latchkey-small
 
    steps:
    - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
      with:
        persist-credentials: false
    - name: Set up Python
      uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
      with:
        cache: 'pip'
        python-version: "3.x"
    - name: Install pypa/build
      run: >-
        python3 -m
        pip install
        build
        --user
    - name: Build a binary wheel and a source tarball
      run: python3 -m build
    - name: Store the distribution packages
      uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
      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
      url: https://pypi.org/p/dynamax  # Replace <package-name> with your PyPI project name
    permissions:
      id-token: write  # IMPORTANT: mandatory for trusted publishing
 
    steps:
    - name: Download all the dists
      uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
      with:
        name: python-package-distributions
        path: dist/
    - name: Publish distribution πŸ“¦ to PyPI
      uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
 
  publish-to-testpypi:
    timeout-minutes: 30
    name: Publish Python 🐍 distribution πŸ“¦ to TestPyPI
    needs:
    - build
    runs-on: latchkey-small
 
    environment:
      name: testpypi
      url: https://test.pypi.org/p/dynamax
 
    permissions:
      id-token: write  # IMPORTANT: mandatory for trusted publishing
 
    steps:
    - name: Download all the dists
      uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
      with:
        name: python-package-distributions
        path: dist/
    - name: Publish distribution πŸ“¦ to TestPyPI
      uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
      with:
        repository-url: https://test.pypi.org/legacy/
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 3 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow