Skip to content
Latchkey

packages workflow (holoviz/holoviews)

The packages workflow from holoviz/holoviews, 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: holoviz/holoviews.github/workflows/build.yamlLicense BSD-3-ClauseView source

What it does

This is the packages workflow from the holoviz/holoviews 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

workflow (.yml)
name: packages
on:
  push:
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+"
      - "v[0-9]+.[0-9]+.[0-9]+a[0-9]+"
      - "v[0-9]+.[0-9]+.[0-9]+b[0-9]+"
      - "v[0-9]+.[0-9]+.[0-9]+rc[0-9]+"
  workflow_dispatch:
  schedule:
    - cron: "0 14 * * SUN"

permissions: {}

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  PACKAGE: "holoviews"
  PYTHON_VERSION: "3.10"

jobs:
  waiting_room:
    name: Waiting Room
    runs-on: ubuntu-latest
    needs: [conda_build, pip_install]
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    environment:
      name: publish
    steps:
      - run: echo "All builds have finished, have been approved, and ready to publish"

  pixi_lock:
    name: Pixi lock
    runs-on: ubuntu-latest
    steps:
      - uses: holoviz-dev/holoviz_tasks/pixi-lock@1a9884850782b0b80ba2e91b573e7d63d9d3c3dc # v1.0.1

  conda_build:
    name: Build Conda
    needs: [pixi_lock]
    runs-on: "ubuntu-latest"
    steps:
      - uses: holoviz-dev/holoviz_tasks/pixi-install@1a9884850782b0b80ba2e91b573e7d63d9d3c3dc # v1.0.1
        with:
          environments: "build"
          download-data: false
          install: false
      - name: conda build
        run: pixi run -e build build-conda
      - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        if: always()
        with:
          name: artifacts-conda
          path: dist/*.conda
          if-no-files-found: error

  conda_publish:
    name: Publish Conda
    runs-on: ubuntu-latest
    needs: [conda_build, waiting_room]
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    steps:
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: artifacts-conda
          path: dist/
      - name: anaconda setup
        run: |
          pipx install anaconda-client
          binstar --version || binstar --help  # version broke with typer 0.26.0 and click 8.4.0
      - name: anaconda dev upload
        if: contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc')
        run: |
          binstar --token ${{ secrets.CONDA_UPLOAD_TOKEN }} upload --user pyviz --label=dev dist/*.conda
      - name: anaconda upload
        if: (!(contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc')))
        run: |
          binstar --token ${{ secrets.CONDA_UPLOAD_TOKEN }} upload --user pyviz --label=dev --label=main dist/*.conda

  pip_build:
    name: Build PyPI
    needs: [pixi_lock]
    runs-on: "ubuntu-latest"
    steps:
      - uses: holoviz-dev/holoviz_tasks/pixi-install@1a9884850782b0b80ba2e91b573e7d63d9d3c3dc # v1.0.1
        with:
          environments: "build"
          download-data: false
          install: false
      - name: Build package
        run: pixi run -e build build-pip
      - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        if: always()
        with:
          name: artifacts-pip
          path: dist/
          if-no-files-found: error
      - name: Annotate PyPI URL
        run: |
          echo "::notice::PyPI URL: https://pypi.org/p/$PACKAGE"

  pip_install:
    name: Install PyPI
    runs-on: "ubuntu-latest"
    needs: [pip_build]
    steps:
      - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: artifacts-pip
          path: dist/
      - name: Install package
        run: python -m pip install dist/*.whl
      - name: Import package
        run: python -c "import $PACKAGE; print($PACKAGE._version.__version__)"

  pip_publish:
    name: Publish PyPI
    runs-on: ubuntu-latest
    needs: [pip_build, waiting_room]
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    permissions:
      id-token: write
    steps:
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: artifacts-pip
          path: dist/
      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1.14

  announce:
    name: Announce GitHub
    runs-on: ubuntu-latest
    needs: [waiting_room]
    permissions:
      contents: write
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    env:
      TAG: ${{ github.ref_name }}
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          persist-credentials: false
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          pattern: artifacts-*
          path: artifacts/
          merge-multiple: true
      - name: Extract changelog section
        run: |
          awk -v ver="### Version ${TAG#v}" '
            $0 == ver {flag=1; next}
            /^#{2,3} Version / && flag {exit}
            flag && !/^(\*\*.*\*\*)$/
          ' doc/releases.md | tee RELEASE_BODY.md
      - name: Create draft GitHub release with dist artifacts
        if: (!(contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc')))
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create "$TAG" \
            --title "Version ${TAG#v}" \
            --notes-file RELEASE_BODY.md \
            --draft \
            artifacts/*

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: packages
on:
  push:
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+"
      - "v[0-9]+.[0-9]+.[0-9]+a[0-9]+"
      - "v[0-9]+.[0-9]+.[0-9]+b[0-9]+"
      - "v[0-9]+.[0-9]+.[0-9]+rc[0-9]+"
  workflow_dispatch:
  schedule:
    - cron: "0 14 * * SUN"
 
permissions: {}
 
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
 
env:
  PACKAGE: "holoviews"
  PYTHON_VERSION: "3.10"
 
jobs:
  waiting_room:
    timeout-minutes: 30
    name: Waiting Room
    runs-on: latchkey-small
    needs: [conda_build, pip_install]
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    environment:
      name: publish
    steps:
      - run: echo "All builds have finished, have been approved, and ready to publish"
 
  pixi_lock:
    timeout-minutes: 30
    name: Pixi lock
    runs-on: latchkey-small
    steps:
      - uses: holoviz-dev/holoviz_tasks/pixi-lock@1a9884850782b0b80ba2e91b573e7d63d9d3c3dc # v1.0.1
 
  conda_build:
    timeout-minutes: 30
    name: Build Conda
    needs: [pixi_lock]
    runs-on: "ubuntu-latest"
    steps:
      - uses: holoviz-dev/holoviz_tasks/pixi-install@1a9884850782b0b80ba2e91b573e7d63d9d3c3dc # v1.0.1
        with:
          environments: "build"
          download-data: false
          install: false
      - name: conda build
        run: pixi run -e build build-conda
      - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        if: always()
        with:
          name: artifacts-conda
          path: dist/*.conda
          if-no-files-found: error
 
  conda_publish:
    timeout-minutes: 30
    name: Publish Conda
    runs-on: latchkey-small
    needs: [conda_build, waiting_room]
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    steps:
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: artifacts-conda
          path: dist/
      - name: anaconda setup
        run: |
          pipx install anaconda-client
          binstar --version || binstar --help  # version broke with typer 0.26.0 and click 8.4.0
      - name: anaconda dev upload
        if: contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc')
        run: |
          binstar --token ${{ secrets.CONDA_UPLOAD_TOKEN }} upload --user pyviz --label=dev dist/*.conda
      - name: anaconda upload
        if: (!(contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc')))
        run: |
          binstar --token ${{ secrets.CONDA_UPLOAD_TOKEN }} upload --user pyviz --label=dev --label=main dist/*.conda
 
  pip_build:
    timeout-minutes: 30
    name: Build PyPI
    needs: [pixi_lock]
    runs-on: "ubuntu-latest"
    steps:
      - uses: holoviz-dev/holoviz_tasks/pixi-install@1a9884850782b0b80ba2e91b573e7d63d9d3c3dc # v1.0.1
        with:
          environments: "build"
          download-data: false
          install: false
      - name: Build package
        run: pixi run -e build build-pip
      - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        if: always()
        with:
          name: artifacts-pip
          path: dist/
          if-no-files-found: error
      - name: Annotate PyPI URL
        run: |
          echo "::notice::PyPI URL: https://pypi.org/p/$PACKAGE"
 
  pip_install:
    timeout-minutes: 30
    name: Install PyPI
    runs-on: "ubuntu-latest"
    needs: [pip_build]
    steps:
      - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        with:
          cache: 'pip'
          python-version: ${{ env.PYTHON_VERSION }}
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: artifacts-pip
          path: dist/
      - name: Install package
        run: python -m pip install dist/*.whl
      - name: Import package
        run: python -c "import $PACKAGE; print($PACKAGE._version.__version__)"
 
  pip_publish:
    timeout-minutes: 30
    name: Publish PyPI
    runs-on: latchkey-small
    needs: [pip_build, waiting_room]
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    permissions:
      id-token: write
    steps:
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: artifacts-pip
          path: dist/
      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1.14
 
  announce:
    timeout-minutes: 30
    name: Announce GitHub
    runs-on: latchkey-small
    needs: [waiting_room]
    permissions:
      contents: write
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    env:
      TAG: ${{ github.ref_name }}
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          persist-credentials: false
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          pattern: artifacts-*
          path: artifacts/
          merge-multiple: true
      - name: Extract changelog section
        run: |
          awk -v ver="### Version ${TAG#v}" '
            $0 == ver {flag=1; next}
            /^#{2,3} Version / && flag {exit}
            flag && !/^(\*\*.*\*\*)$/
          ' doc/releases.md | tee RELEASE_BODY.md
      - name: Create draft GitHub release with dist artifacts
        if: (!(contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc')))
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create "$TAG" \
            --title "Version ${TAG#v}" \
            --notes-file RELEASE_BODY.md \
            --draft \
            artifacts/*
 

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 8 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