Backport PRs to stable branches workflow (cocotb/cocotb)
The Backport PRs to stable branches workflow from cocotb/cocotb, explained and optimized by Latchkey.
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 Backport PRs to stable branches workflow from the cocotb/cocotb 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
# Copyright cocotb contributors
# Licensed under the Revised BSD License, see LICENSE for details.
# SPDX-License-Identifier: BSD-3-Clause
# A workflow to automatically backport pull requests to a stable branch.
#
# This workflow uses the Backport CLI (https://github.com/sorenlouv/backport)
# under the hood, which is configured in `.backportrc.json` in the repository
# root.
#
# See https://github.com/sorenlouv/backport-github-action for documentation
# on the used action.
name: Backport PRs to stable branches
on:
pull_request_target:
# Run this workflow when a label on a PR is added, or if it's closed.
types: ["labeled", "closed"]
jobs:
backport:
name: Backport PR
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
# Run the backport action only on PRs with one of the `backport-to:`
# labels applied.
#
# Also update `branchLabelMapping` in `.backportrc.json` when changing the
# label here.
#
# Implementation note: GitHub's contains() is matching the full string
# when operating on an array (and startsWith() does not operate on arrays
# at all). Do the label matching with jq instead.
- name: Check for backport labels
id: check_labels
run: |-
labels='${{ toJSON(github.event.pull_request.labels.*.name) }}'
matched=$(echo $labels | jq '.|map(select(startswith("backport-to:"))) | length')
echo "matched=$matched"
echo "matched=$matched" >> $GITHUB_OUTPUT
- name: Backport Action
if: fromJSON(steps.check_labels.outputs.matched) > 0
uses: sorenlouv/backport-github-action@8a6c0381851f43f9f1fddc7303f0e9015eb57b62 # v12.0.4
with:
# GITHUB_TOKEN is available by default, but the powers it has are
# configurable. Follow the GitHub documentation at
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#setting-the-permissions-of-the-github_token-for-your-repository
# to "Allow GitHub Actions to create and approve pull requests".
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Info log
if: ${{ fromJSON(steps.check_labels.outputs.matched) > 0 && success() }}
run: cat ~/.backport/backport.info.log
- name: Debug log
if: ${{ fromJSON(steps.check_labels.outputs.matched) > 0 && failure() }}
run: cat ~/.backport/backport.debug.log
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
# Copyright cocotb contributors # Licensed under the Revised BSD License, see LICENSE for details. # SPDX-License-Identifier: BSD-3-Clause # A workflow to automatically backport pull requests to a stable branch. # # This workflow uses the Backport CLI (https://github.com/sorenlouv/backport) # under the hood, which is configured in `.backportrc.json` in the repository # root. # # See https://github.com/sorenlouv/backport-github-action for documentation # on the used action. name: Backport PRs to stable branches on: pull_request_target: # Run this workflow when a label on a PR is added, or if it's closed. types: ["labeled", "closed"] jobs: backport: timeout-minutes: 30 name: Backport PR if: github.event.pull_request.merged == true runs-on: latchkey-small steps: # Run the backport action only on PRs with one of the `backport-to:` # labels applied. # # Also update `branchLabelMapping` in `.backportrc.json` when changing the # label here. # # Implementation note: GitHub's contains() is matching the full string # when operating on an array (and startsWith() does not operate on arrays # at all). Do the label matching with jq instead. - name: Check for backport labels id: check_labels run: |- labels='${{ toJSON(github.event.pull_request.labels.*.name) }}' matched=$(echo $labels | jq '.|map(select(startswith("backport-to:"))) | length') echo "matched=$matched" echo "matched=$matched" >> $GITHUB_OUTPUT - name: Backport Action if: fromJSON(steps.check_labels.outputs.matched) > 0 uses: sorenlouv/backport-github-action@8a6c0381851f43f9f1fddc7303f0e9015eb57b62 # v12.0.4 with: # GITHUB_TOKEN is available by default, but the powers it has are # configurable. Follow the GitHub documentation at # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#setting-the-permissions-of-the-github_token-for-your-repository # to "Allow GitHub Actions to create and approve pull requests". github_token: ${{ secrets.GITHUB_TOKEN }} - name: Info log if: ${{ fromJSON(steps.check_labels.outputs.matched) > 0 && success() }} run: cat ~/.backport/backport.info.log - name: Debug log if: ${{ fromJSON(steps.check_labels.outputs.matched) > 0 && failure() }} run: cat ~/.backport/backport.debug.log
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.