Prepare Release workflow (tox-dev/tox)
The Prepare Release workflow from tox-dev/tox, explained and optimized by Latchkey.
A
CI health: A - excellent
Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Prepare Release workflow from the tox-dev/tox 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: Prepare Release
on:
workflow_dispatch:
inputs:
bump:
description: "Version bump type"
required: true
type: choice
options:
- auto
- major
- minor
- patch
default: auto
permissions:
contents: write
env:
FORCE_COLOR: 1
jobs:
prepare-release:
runs-on: ubuntu-24.04
environment: release-auth
permissions:
contents: write
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
token: ${{ secrets.RELEASE_PAT }}
persist-credentials: true
- name: Install the latest version of uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: true
cache-dependency-glob: "pyproject.toml"
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
- name: Set up remote tracking
run: |
git remote -v
git fetch origin
git branch -a
- name: Calculate next version
id: version
run: |
current=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0")
echo "Current version: $current"
IFS='.' read -r major minor patch <<< "$current"
bump_type="${{ inputs.bump }}"
if [ "$bump_type" = "auto" ]; then
feature_count=$(find docs/changelog -name "*.feature.rst" 2>/dev/null | wc -l)
if [ "$feature_count" -gt 0 ]; then
bump_type="minor"
echo "Auto-detected: minor bump (found $feature_count feature changelog(s))"
else
bump_type="patch"
echo "Auto-detected: patch bump (no feature changelogs)"
fi
fi
case "$bump_type" in
major)
next="$((major + 1)).0.0"
;;
minor)
next="$major.$((minor + 1)).0"
;;
patch)
next="$major.$minor.$((patch + 1))"
;;
esac
echo "Next version: $next"
echo "version=$next" >> $GITHUB_OUTPUT
- name: Install tox
run: uv tool install --python-preference only-managed --python 3.14 tox@.
- name: Run release process
run: tox run -e release -- ${STEPS_VERSION_OUTPUTS_VERSION}
env:
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
- name: Display completion message
run: echo "Release ${STEPS_VERSION_OUTPUTS_VERSION} prepared and pushed successfully!"
env:
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Prepare Release on: workflow_dispatch: inputs: bump: description: "Version bump type" required: true type: choice options: - auto - major - minor - patch default: auto permissions: contents: write env: FORCE_COLOR: 1 jobs: prepare-release: timeout-minutes: 30 runs-on: latchkey-small environment: release-auth permissions: contents: write steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 token: ${{ secrets.RELEASE_PAT }} persist-credentials: true - name: Install the latest version of uv uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true cache-dependency-glob: "pyproject.toml" github-token: ${{ secrets.GITHUB_TOKEN }} - name: Configure git run: | git config user.name "${GITHUB_ACTOR}" git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" - name: Set up remote tracking run: | git remote -v git fetch origin git branch -a - name: Calculate next version id: version run: | current=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0") echo "Current version: $current" IFS='.' read -r major minor patch <<< "$current" bump_type="${{ inputs.bump }}" if [ "$bump_type" = "auto" ]; then feature_count=$(find docs/changelog -name "*.feature.rst" 2>/dev/null | wc -l) if [ "$feature_count" -gt 0 ]; then bump_type="minor" echo "Auto-detected: minor bump (found $feature_count feature changelog(s))" else bump_type="patch" echo "Auto-detected: patch bump (no feature changelogs)" fi fi case "$bump_type" in major) next="$((major + 1)).0.0" ;; minor) next="$major.$((minor + 1)).0" ;; patch) next="$major.$minor.$((patch + 1))" ;; esac echo "Next version: $next" echo "version=$next" >> $GITHUB_OUTPUT - name: Install tox run: uv tool install --python-preference only-managed --python 3.14 tox@. - name: Run release process run: tox run -e release -- ${STEPS_VERSION_OUTPUTS_VERSION} env: GH_TOKEN: ${{ secrets.RELEASE_PAT }} STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }} - name: Display completion message run: echo "Release ${STEPS_VERSION_OUTPUTS_VERSION} prepared and pushed successfully!" env: STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
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. - Add a job timeout so a hung step cannot burn hours of runner time.
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.