HistoryBenchmark workflow (Neoteroi/BlackSheep)
The HistoryBenchmark workflow from Neoteroi/BlackSheep, explained and optimized by Latchkey.
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.
What it does
This is the HistoryBenchmark workflow from the Neoteroi/BlackSheep 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
####################################################################################
# Runs benchmarks for BlackSheep source code at various points of the commit history,
# on Ubuntu and Windows for a single version of Python.
#
# This workflow supports both manual and automatic triggers.
# If triggered manually, it is possible to select commits hashes or tags to checkout.
#
# The minimum supported BlackSheep version by the benchmarks is v2.0.1!
####################################################################################
name: HistoryBenchmark
on:
# push:
# paths:
# - '.github/**'
# - 'perf/**'
workflow_dispatch:
inputs:
commits:
description: "List of commits or tags to benchmark (space-separated)"
required: true
default: "v2.0.1 v2.2.0 v2.3.0 current"
memory:
description: "Include memory benchmark (Y|N). Time consuming."
required: true
default: "N"
env:
DEFAULT_MEMORY: "N"
DEFAULT_COMMITS: "v2.0.1 v2.2.0 v2.3.0 current"
jobs:
perf-tests:
strategy:
fail-fast: false
matrix:
python-version: ["3.13"]
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
- name: Use Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install -r requirements.txt
cd perf
pip install -r req.txt
- name: Run benchmark
shell: bash
env:
MEMORY: ${{ github.event.inputs.memory || env.DEFAULT_MEMORY }}
COMMITS: ${{ github.event.inputs.commits || env.DEFAULT_COMMITS }}
run: |
echo "Running benchmarks for commits: $COMMITS"
export PYTHONPATH="."
if [ $MEMORY == "Y" ]; then
echo "β Including memory benchmarks π’"
python perf/historyrun.py --commits $COMMITS --times 3 --memory
else
echo "β Excluding memory benchmarks π΄"
python perf/historyrun.py --commits $COMMITS --times 3 --no-memory
fi
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: benchmark-results-${{ matrix.os }}-${{ matrix.python-version }}
path: benchmark_results
genreport:
runs-on: ubuntu-latest
needs: [perf-tests]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
- name: Download a distribution artifact
uses: actions/download-artifact@v4
with:
pattern: benchmark-results-*
merge-multiple: true
path: benchmark_results
- name: Use Python 3.13
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install dependencies
run: |
cd perf
pip install -r req.txt
- name: Generate report
shell: bash
run: |
ls -R benchmark_results
chmod -R 755 benchmark_results
export PYTHONPATH="."
python perf/genreport.py
python perf/genreport.py --output windows-results.xlsx --platform Windows
python perf/genreport.py --output linux-results.xlsx --platform Linux
- name: Upload reports
uses: actions/upload-artifact@v4
with:
name: benchmark-reports
path: "**/*.xlsx" # Upload all .xlsx files
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.
#################################################################################### # Runs benchmarks for BlackSheep source code at various points of the commit history, # on Ubuntu and Windows for a single version of Python. # # This workflow supports both manual and automatic triggers. # If triggered manually, it is possible to select commits hashes or tags to checkout. # # The minimum supported BlackSheep version by the benchmarks is v2.0.1! #################################################################################### name: HistoryBenchmark on: # push: # paths: # - '.github/**' # - 'perf/**' workflow_dispatch: inputs: commits: description: "List of commits or tags to benchmark (space-separated)" required: true default: "v2.0.1 v2.2.0 v2.3.0 current" memory: description: "Include memory benchmark (Y|N). Time consuming." required: true default: "N" env: DEFAULT_MEMORY: "N" DEFAULT_COMMITS: "v2.0.1 v2.2.0 v2.3.0 current" jobs: perf-tests: timeout-minutes: 30 strategy: fail-fast: false matrix: python-version: ["3.13"] os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: false - name: Use Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: cache: 'pip' python-version: ${{ matrix.python-version }} - name: Install dependencies run: | pip install -r requirements.txt cd perf pip install -r req.txt - name: Run benchmark shell: bash env: MEMORY: ${{ github.event.inputs.memory || env.DEFAULT_MEMORY }} COMMITS: ${{ github.event.inputs.commits || env.DEFAULT_COMMITS }} run: | echo "Running benchmarks for commits: $COMMITS" export PYTHONPATH="." if [ $MEMORY == "Y" ]; then echo "β Including memory benchmarks π’" python perf/historyrun.py --commits $COMMITS --times 3 --memory else echo "β Excluding memory benchmarks π΄" python perf/historyrun.py --commits $COMMITS --times 3 --no-memory fi - name: Upload results uses: actions/upload-artifact@v4 with: name: benchmark-results-${{ matrix.os }}-${{ matrix.python-version }} path: benchmark_results genreport: timeout-minutes: 30 runs-on: latchkey-small needs: [perf-tests] steps: - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: false - name: Download a distribution artifact uses: actions/download-artifact@v4 with: pattern: benchmark-results-* merge-multiple: true path: benchmark_results - name: Use Python 3.13 uses: actions/setup-python@v5 with: cache: 'pip' python-version: '3.13' - name: Install dependencies run: | cd perf pip install -r req.txt - name: Generate report shell: bash run: | ls -R benchmark_results chmod -R 755 benchmark_results export PYTHONPATH="." python perf/genreport.py python perf/genreport.py --output windows-results.xlsx --platform Windows python perf/genreport.py --output linux-results.xlsx --platform Linux - name: Upload reports uses: actions/upload-artifact@v4 with: name: benchmark-reports path: "**/*.xlsx" # Upload all .xlsx files
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.
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:
- Dependency installs
This workflow runs 2 jobs (3 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.