Publish Python Package workflow (scverse/scanpy)
The Publish Python Package workflow from scverse/scanpy, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get caching, 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 Package workflow from the scverse/scanpy repository, a real project running GitHub Actions. It is shown here with attribution under its BSD-3-Clause license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Publish Python Package
on:
release:
types: [published]
env:
FORCE_COLOR: "1"
jobs:
publish:
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write # to authenticate as Trusted Publisher to pypi.org
steps:
- uses: actions/checkout@v7
with: { filter: 'blob:none', fetch-depth: 0 }
- uses: actions/setup-python@v6
with:
python-version: "3.x"
- uses: astral-sh/setup-uv@v8.3.2
- run: uvx --from build pyproject-build --sdist --wheel .
- run: uvx twine check dist/*
- uses: pypa/gh-action-pypi-publish@release/v1
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 Package on: release: types: [published] env: FORCE_COLOR: "1" jobs: publish: timeout-minutes: 30 runs-on: latchkey-small environment: pypi permissions: id-token: write # to authenticate as Trusted Publisher to pypi.org steps: - uses: actions/checkout@v7 with: { filter: 'blob:none', fetch-depth: 0 } - uses: actions/setup-python@v6 with: cache: 'pip' python-version: "3.x" - uses: astral-sh/setup-uv@v8.3.2 - run: uvx --from build pyproject-build --sdist --wheel . - run: uvx twine check dist/* - uses: pypa/gh-action-pypi-publish@release/v1
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. - 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 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.