Skip to content
Latchkey

Manual Release to PyPI workflow (rsheftel/pandas_market_calendars)

The Manual Release to PyPI workflow from rsheftel/pandas_market_calendars, explained and optimized by Latchkey.

C

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.

Grade your own workflow free or run it on Latchkey →
Source: rsheftel/pandas_market_calendars.github/workflows/release.ymlLicense MITView source

What it does

This is the Manual Release to PyPI workflow from the rsheftel/pandas_market_calendars 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: Manual Release to PyPI

on:
  workflow_dispatch:

permissions:
  id-token: write   # Required for Trusted Publishing OIDC
  contents: write   # Added: Enables pushing tags (and branches if needed)

jobs:
  test-and-release:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: true
      matrix:
        os: [ ubuntu-latest, windows-latest, macos-latest ]
        python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install uv
        uses: astral-sh/setup-uv@v7  # Latest as of 2025; pin to specific tag if needed
        with:
          enable-cache: true  # Optional: caches uv packages across runs for faster sync
          # cache-dependency-glob: "uv.lock"  # Invalidate on lockfile changes

      - name: Install dependencies and project
        run: uv sync --all-extras --dev

      - name: Run tests
        run: uv run pytest

      - name: Extract package name and version from pyproject.toml
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        id: metadata
        run: |
          PACKAGE_NAME=$(uv run python -c "import tomllib; data = tomllib.load(open('pyproject.toml','rb')); print(data['project']['name'])")
          VERSION=$(uv run python -c "import tomllib; data = tomllib.load(open('pyproject.toml','rb')); print(data['project']['version'])")
          echo "package_name=$PACKAGE_NAME" >> $GITHUB_OUTPUT
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Check if local version > current PyPI version
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        run: |
          PACKAGE_NAME="${{ steps.metadata.outputs.package_name }}"
          LOCAL_VERSION="${{ steps.metadata.outputs.version }}"
          
          echo "Package name: $PACKAGE_NAME"
          echo "Local version: $LOCAL_VERSION"
          
          # Fetch latest version from PyPI JSON API
          RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" https://pypi.org/pypi/$PACKAGE_NAME/json)
          
          if [ "$RESPONSE" -eq 404 ]; then
            echo "Package not found on PyPI - assuming first release, proceeding."
            exit 0
          fi
          
          if [ "$RESPONSE" -ne 200 ]; then
            echo "Failed to query PyPI (HTTP $RESPONSE)"
            exit 1
          fi
          
          PYPI_VERSION=$(curl -s https://pypi.org/pypi/$PACKAGE_NAME/json | jq -r '.info.version')
          echo "Current PyPI version: $PYPI_VERSION"
          
          # Compare versions using Python's packaging module
          uv run python - <<EOF
          from packaging.version import Version
          local = Version("$LOCAL_VERSION")
          pypi = Version("$PYPI_VERSION")
          if local <= pypi:
              raise SystemExit(f"Error: Local version {local} is not greater than PyPI version {pypi}")
          print("Version check passed: $LOCAL_VERSION > $PYPI_VERSION")
          EOF

      - name: Tag the commit
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        run: |
          git config user.name "github-actions"
          git config user.email "github-actions@github.com"
          git tag v${{ steps.metadata.outputs.version }}
          git push origin v${{ steps.metadata.outputs.version }}

      - name: Build package with uv
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        run: uv build

      - name: Publish to PyPI using Trusted Publishing
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        run: uv publish

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: Manual Release to PyPI
 
on:
  workflow_dispatch:
 
permissions:
  id-token: write   # Required for Trusted Publishing OIDC
  contents: write   # Added: Enables pushing tags (and branches if needed)
 
jobs:
  test-and-release:
    timeout-minutes: 30
    runs-on: latchkey-small
    strategy:
      fail-fast: true
      matrix:
        os: [ ubuntu-latest, windows-latest, macos-latest ]
        python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]
 
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
 
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          cache: 'pip'
          python-version: ${{ matrix.python-version }}
 
      - name: Install uv
        uses: astral-sh/setup-uv@v7  # Latest as of 2025; pin to specific tag if needed
        with:
          enable-cache: true  # Optional: caches uv packages across runs for faster sync
          # cache-dependency-glob: "uv.lock"  # Invalidate on lockfile changes
 
      - name: Install dependencies and project
        run: uv sync --all-extras --dev
 
      - name: Run tests
        run: uv run pytest
 
      - name: Extract package name and version from pyproject.toml
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        id: metadata
        run: |
          PACKAGE_NAME=$(uv run python -c "import tomllib; data = tomllib.load(open('pyproject.toml','rb')); print(data['project']['name'])")
          VERSION=$(uv run python -c "import tomllib; data = tomllib.load(open('pyproject.toml','rb')); print(data['project']['version'])")
          echo "package_name=$PACKAGE_NAME" >> $GITHUB_OUTPUT
          echo "version=$VERSION" >> $GITHUB_OUTPUT
 
      - name: Check if local version > current PyPI version
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        run: |
          PACKAGE_NAME="${{ steps.metadata.outputs.package_name }}"
          LOCAL_VERSION="${{ steps.metadata.outputs.version }}"
          
          echo "Package name: $PACKAGE_NAME"
          echo "Local version: $LOCAL_VERSION"
          
          # Fetch latest version from PyPI JSON API
          RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" https://pypi.org/pypi/$PACKAGE_NAME/json)
          
          if [ "$RESPONSE" -eq 404 ]; then
            echo "Package not found on PyPI - assuming first release, proceeding."
            exit 0
          fi
          
          if [ "$RESPONSE" -ne 200 ]; then
            echo "Failed to query PyPI (HTTP $RESPONSE)"
            exit 1
          fi
          
          PYPI_VERSION=$(curl -s https://pypi.org/pypi/$PACKAGE_NAME/json | jq -r '.info.version')
          echo "Current PyPI version: $PYPI_VERSION"
          
          # Compare versions using Python's packaging module
          uv run python - <<EOF
          from packaging.version import Version
          local = Version("$LOCAL_VERSION")
          pypi = Version("$PYPI_VERSION")
          if local <= pypi:
              raise SystemExit(f"Error: Local version {local} is not greater than PyPI version {pypi}")
          print("Version check passed: $LOCAL_VERSION > $PYPI_VERSION")
          EOF
 
      - name: Tag the commit
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        run: |
          git config user.name "github-actions"
          git config user.email "github-actions@github.com"
          git tag v${{ steps.metadata.outputs.version }}
          git push origin v${{ steps.metadata.outputs.version }}
 
      - name: Build package with uv
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        run: uv build
 
      - name: Publish to PyPI using Trusted Publishing
        if: matrix.python-version == '3.14' && matrix.os == 'ubuntu-latest'
        run: uv publish
 

What changed

1 third-party action is referenced by a movable tag. Pin it to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.

This workflow runs 1 job (15 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow