Skip to content
Latchkey

release-pipeline workflow (ml-tooling/lazydocs)

The release-pipeline workflow from ml-tooling/lazydocs, explained and optimized by Latchkey.

B

CI health: B - good

Point runs-on at Latchkey and get 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: ml-tooling/lazydocs.github/workflows/release-pipeline.ymlLicense MITView source

What it does

This is the release-pipeline workflow from the ml-tooling/lazydocs 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)
# Based on https://github.com/ml-tooling/universal-build/blob/v0.6.12/workflows/build-pipeline.yml
name: release-pipeline

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Version of this release"
        required: true
  milestone:
    types: [closed]

env:
  VERSION: ${{ secrets.VERSION }}
  BRANCH_PREFIX: "release/v"
  DEFAULT_BRANCH: main

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - if: ${{ github.event.milestone != null  &&  github.event.milestone.title != null }}
        name: set-milestone-version
        run: |
          echo "VERSION=$(sed "s/^v//" <<< "${{ github.event.milestone.title }}")" >> $GITHUB_ENV
          echo "PR_MILESTONE_LINK=-M ${{ github.event.milestone.title }}" >> $GITHUB_ENV
      - if: ${{ github.event.inputs != null  &&  github.event.inputs.version != null }}
        name: set-input-version
        run: echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
      - name: check-version
        run: 'if [[ ! "${{ env.VERSION }}" =~ ^([0-9]+\.[0-9]+\.[0-9]+.*)$ ]]; then echo "The version is not valid: ${{ env.VERSION }}"; exit 1; fi'
      - name: set-github-token
        run: echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
      # Set host ip to env variable to be uside within container actions
      - name: set-host-ip
        run: echo "_HOST_IP=$(hostname -I | cut -d ' ' -f 1)" >> $GITHUB_ENV
      # Fix git version for act if github token is provided
      - if: ${{ env.GITHUB_ACTOR == 'nektos/act' && env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: install-latest-git
        run: |
          # Required for local checkout
          apt-get update
          apt-get install -y git
      - if: ${{ env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: create-release-branch
        uses: peterjgrainger/action-create-branch@v2.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          branch: "${{ env.BRANCH_PREFIX }}${{ env.VERSION }}"
      - if: ${{ ! (env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '')  }}
        uses: actions/checkout@v2
      - if: ${{ env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
          ref: ${{ env.BRANCH_PREFIX }}${{ env.VERSION }}
          token: ${{ env.GITHUB_TOKEN }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: run-component-builds
        uses: ./.github/actions/build-environment
        with:
          build_args: --make --force --version=${{ env.VERSION  }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: run-linting-and-style-checks
        uses: ./.github/actions/build-environment
        with:
          build_args: --check --force --version=${{ env.VERSION  }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: run-component-tests
        uses: ./.github/actions/build-environment
        with:
          build_args: --test --force --test-marker=slow --version=${{ env.VERSION  }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: release-components
        uses: ./.github/actions/build-environment
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
          PYPI_REPOSITORY: ${{ secrets.PYPI_REPOSITORY }}
        with:
          build_args: --release --force --version=${{ env.VERSION }}
          container_registry_url: ${{ secrets.CONTAINER_REGISTRY_URL }}
          container_registry_username: ${{ secrets.CONTAINER_REGISTRY_USERNAME }}
          container_registry_password: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
      - if: ${{ env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: push-changes
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          branch: ${{ env.BRANCH_PREFIX }}${{ env.VERSION  }}
          commit_user_name: Release Bot
          commit_user_email: actions@github.com
          commit_message: Apply automatic release changes for v${{ env.VERSION  }}
          tagging_message: v${{ env.VERSION  }}
          skip_dirty_check: true
          commit_options: "--allow-empty"
      - if: ${{ env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: create-pull-request
        shell: bash
        run: |
          # Stops script execution if a command has an error
          set -e
          curl -fsSL https://github.com/github/hub/raw/master/script/get | bash -s 2.14.2
          # TODO: Milestone link currently does not work with closed milestones: ${{ env.PR_MILESTONE_LINK  }} (problem with hub cli)
          bin/hub pull-request -b ${{ env.DEFAULT_BRANCH }} -h ${{ env.BRANCH_PREFIX }}${{ env.VERSION  }} --no-edit -m "Finalize release for version ${{ env.VERSION  }}" -m "Automated pull request for release version ${{ env.VERSION  }}" -l "skip changelog" || true
          rm bin/hub
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      # Fix of release drafter to allow different events to trigger the release
      # TODO: currently does not work with act
      - if: ${{ env.GITHUB_ACTOR == 'nektos/act' && env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: no-relese-drafter-support
        run: echo "The release drafter currently does not work with act, please create the release from the Github UI."
      - if: ${{ env.GITHUB_ACTOR != 'nektos/act' && env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: checkout-fixed-release-drafter
        uses: actions/checkout@v2
        with:
          repository: ml-tooling/release-drafter
          path: ./.git/cloned-actions/release-drafter
      - if: ${{ env.GITHUB_ACTOR != 'nektos/act' && env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: create-release-draft
        uses: ./.git/cloned-actions/release-drafter
        with:
          version: ${{ env.VERSION }}
          tag: v${{ env.VERSION  }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      # Optional: upload release assets via actions/upload-release-asset@v1 and via upload_url from release drafter

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

# Based on https://github.com/ml-tooling/universal-build/blob/v0.6.12/workflows/build-pipeline.yml
name: release-pipeline
 
on:
  workflow_dispatch:
    inputs:
      version:
        description: "Version of this release"
        required: true
  milestone:
    types: [closed]
 
env:
  VERSION: ${{ secrets.VERSION }}
  BRANCH_PREFIX: "release/v"
  DEFAULT_BRANCH: main
 
jobs:
  release:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - if: ${{ github.event.milestone != null  &&  github.event.milestone.title != null }}
        name: set-milestone-version
        run: |
          echo "VERSION=$(sed "s/^v//" <<< "${{ github.event.milestone.title }}")" >> $GITHUB_ENV
          echo "PR_MILESTONE_LINK=-M ${{ github.event.milestone.title }}" >> $GITHUB_ENV
      - if: ${{ github.event.inputs != null  &&  github.event.inputs.version != null }}
        name: set-input-version
        run: echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
      - name: check-version
        run: 'if [[ ! "${{ env.VERSION }}" =~ ^([0-9]+\.[0-9]+\.[0-9]+.*)$ ]]; then echo "The version is not valid: ${{ env.VERSION }}"; exit 1; fi'
      - name: set-github-token
        run: echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
      # Set host ip to env variable to be uside within container actions
      - name: set-host-ip
        run: echo "_HOST_IP=$(hostname -I | cut -d ' ' -f 1)" >> $GITHUB_ENV
      # Fix git version for act if github token is provided
      - if: ${{ env.GITHUB_ACTOR == 'nektos/act' && env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: install-latest-git
        run: |
          # Required for local checkout
          apt-get update
          apt-get install -y git
      - if: ${{ env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: create-release-branch
        uses: peterjgrainger/action-create-branch@v2.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          branch: "${{ env.BRANCH_PREFIX }}${{ env.VERSION }}"
      - if: ${{ ! (env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '')  }}
        uses: actions/checkout@v2
      - if: ${{ env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
          ref: ${{ env.BRANCH_PREFIX }}${{ env.VERSION }}
          token: ${{ env.GITHUB_TOKEN }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: run-component-builds
        uses: ./.github/actions/build-environment
        with:
          build_args: --make --force --version=${{ env.VERSION  }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: run-linting-and-style-checks
        uses: ./.github/actions/build-environment
        with:
          build_args: --check --force --version=${{ env.VERSION  }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: run-component-tests
        uses: ./.github/actions/build-environment
        with:
          build_args: --test --force --test-marker=slow --version=${{ env.VERSION  }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: release-components
        uses: ./.github/actions/build-environment
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
          PYPI_REPOSITORY: ${{ secrets.PYPI_REPOSITORY }}
        with:
          build_args: --release --force --version=${{ env.VERSION }}
          container_registry_url: ${{ secrets.CONTAINER_REGISTRY_URL }}
          container_registry_username: ${{ secrets.CONTAINER_REGISTRY_USERNAME }}
          container_registry_password: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
      - if: ${{ env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: push-changes
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          branch: ${{ env.BRANCH_PREFIX }}${{ env.VERSION  }}
          commit_user_name: Release Bot
          commit_user_email: actions@github.com
          commit_message: Apply automatic release changes for v${{ env.VERSION  }}
          tagging_message: v${{ env.VERSION  }}
          skip_dirty_check: true
          commit_options: "--allow-empty"
      - if: ${{ env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: create-pull-request
        shell: bash
        run: |
          # Stops script execution if a command has an error
          set -e
          curl -fsSL https://github.com/github/hub/raw/master/script/get | bash -s 2.14.2
          # TODO: Milestone link currently does not work with closed milestones: ${{ env.PR_MILESTONE_LINK  }} (problem with hub cli)
          bin/hub pull-request -b ${{ env.DEFAULT_BRANCH }} -h ${{ env.BRANCH_PREFIX }}${{ env.VERSION  }} --no-edit -m "Finalize release for version ${{ env.VERSION  }}" -m "Automated pull request for release version ${{ env.VERSION  }}" -l "skip changelog" || true
          rm bin/hub
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      # Fix of release drafter to allow different events to trigger the release
      # TODO: currently does not work with act
      - if: ${{ env.GITHUB_ACTOR == 'nektos/act' && env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: no-relese-drafter-support
        run: echo "The release drafter currently does not work with act, please create the release from the Github UI."
      - if: ${{ env.GITHUB_ACTOR != 'nektos/act' && env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: checkout-fixed-release-drafter
        uses: actions/checkout@v2
        with:
          repository: ml-tooling/release-drafter
          path: ./.git/cloned-actions/release-drafter
      - if: ${{ env.GITHUB_ACTOR != 'nektos/act' && env.GITHUB_TOKEN != null && env.GITHUB_TOKEN != '' }}
        name: create-release-draft
        uses: ./.git/cloned-actions/release-drafter
        with:
          version: ${{ env.VERSION }}
          tag: v${{ env.VERSION  }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      # Optional: upload release assets via actions/upload-release-asset@v1 and via upload_url from release drafter
 

What changed

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.

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 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow