_get-active-branches workflow (kumahq/kuma)
The _get-active-branches workflow from kumahq/kuma, explained and optimized by Latchkey.
A
CI health: A - excellent
Run this on Latchkey for self-healing, caching, and up to 58% lower cost.
Grade your own workflow free or run it on Latchkey →What it does
This is the _get-active-branches workflow from the kumahq/kuma repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
workflow (.yml)
on:
workflow_call:
inputs:
excludeDefault:
description: "Exclude the repository default branch from the results"
type: boolean
required: false
default: false
summary:
description: "Show branches summary in the job summary (true = always; false = only when debug is enabled)"
type: boolean
required: false
default: false
beforeBranch:
description: "If set, return only branches that appear before this branch in the config order"
type: string
required: false
default: ""
branches:
description: "If set, return only this comma-separated list of branches"
type: string
required: false
default: ""
outputs:
out:
description: "JSON array of active branch patterns (filtered if requested)"
value: ${{ jobs.get.outputs.out }}
permissions:
contents: read
jobs:
get:
runs-on: ${{ vars.RUNS_ON_MASTER_AMD64 || vars.RUNS_ON_AMD64 || 'ubuntu-24.04' }}
outputs:
out: ${{ steps.main.outputs.out }}
steps:
- name: Get active branches
id: main
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GH_DEBUG: ${{ runner.debug == '1' }}
REPOSITORY: ${{ github.repository }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
EXCLUDE_DEFAULT: ${{ inputs.excludeDefault }}
SHOW_SUMMARY: ${{ inputs.summary }}
BEFORE_BRANCH: ${{ inputs.beforeBranch }}
BRANCHES: ${{ inputs.branches }}
run: |
# shellcheck shell=bash
[[ "${GH_DEBUG}" == "true" ]] && set -x
set -euo pipefail
readonly REPOSITORY="${REPOSITORY:?REPOSITORY is required}"
readonly GITHUB_OUTPUT="${GITHUB_OUTPUT:?GITHUB_OUTPUT is required}"
readonly GITHUB_STEP_SUMMARY="${GITHUB_STEP_SUMMARY:-/dev/null}"
readonly EXCLUDE_DEFAULT="${EXCLUDE_DEFAULT:-false}"
readonly DEFAULT_BRANCH="${DEFAULT_BRANCH:-master}"
readonly SHOW_SUMMARY="${SHOW_SUMMARY:-${GH_DEBUG:-0}}"
readonly BEFORE_BRANCH="${BEFORE_BRANCH:-}"
readonly BRANCHES="${BRANCHES:-}"
# If branches input is provided, short-circuit and return it as JSON array
if [[ -n "${BRANCHES}" ]]; then
echo "out=$(printf '%s' "${BRANCHES}" | jq --raw-input --compact-output '
split(",")
| map(gsub("^[[:space:]]+|[[:space:]]+$";""))
| map(select(. != ""))
')" >> "$GITHUB_OUTPUT"
exit 0
fi
# Write summary to $GITHUB_STEP_SUMMARY when enabled
write_summary() {
local json="${1:-[]}"
# treat 1/true/TRUE/yes as truthy
case "${SHOW_SUMMARY}" in
1 | true | TRUE | yes | YES) ;;
*) return 0 ;;
esac
local header="Active Branches"
local parts=()
if [[ "${EXCLUDE_DEFAULT}" == "true" ]]; then
parts+=("without ${DEFAULT_BRANCH}")
fi
if [[ -n "${BEFORE_BRANCH}" ]]; then
parts+=("before ${BEFORE_BRANCH}")
fi
if ((${#parts[@]})); then
local IFS=', '
header+=" (${parts[*]})"
fi
{
echo "${header}:"
echo '```json'
echo "${json}"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
}
# Read raw file to avoid manual base64 decoding
if ! content="$(
gh api -H 'Accept: application/vnd.github.raw' \
"/repos/${REPOSITORY}/contents/active-branches.json" 2> /dev/null
)"; then
echo 'out=[]' >> "$GITHUB_OUTPUT"
exit 0
fi
# Parse both legacy and new formats in a single jq pass, with optional filtering
# Supported input formats:
# - New: {"baseBranchPatterns": ["release-...","master"]}
# - Old: ["release-...","master"]
filtered="$(
jq -c \
--arg exclude "${EXCLUDE_DEFAULT}" \
--arg default "${DEFAULT_BRANCH}" \
--arg before "${BEFORE_BRANCH}" '
def trim: gsub("^[[:space:]]+|[[:space:]]+$";"");
def as_array: if type=="array" then . else (.baseBranchPatterns // []) end;
def uniq_preserve(a): reduce a[] as $i ([]; if index($i) then . else . + [$i] end);
def sort_key($def):
if test("^release-[0-9]+\\.[0-9]+$") then
(capture("^release-(?<maj>[0-9]+)\\.(?<min>[0-9]+)$")
| [0, (.maj|tonumber), (.min|tonumber), ""])
elif ($def|length)>0 and . == $def then
[2, 0, 0, .] # default branch last
else
[1, 0, 0, .] # other branches between releases and default
end;
(try as_array catch [])
| map(select(type=="string") | trim)
| map(select(length>0))
| if ($exclude=="true" and ($default|length)>0) then map(select(. != $default)) else . end
| uniq_preserve(.)
| (if ($before|length)>0 and (index($before) != null)
then .[:index($before)]
else . end)
| sort_by(sort_key($default))
' <<< "$content"
)"
echo "out=${filtered}" >> "$GITHUB_OUTPUT"
# usage:
write_summary "$filtered"
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
on: workflow_call: inputs: excludeDefault: description: "Exclude the repository default branch from the results" type: boolean required: false default: false summary: description: "Show branches summary in the job summary (true = always; false = only when debug is enabled)" type: boolean required: false default: false beforeBranch: description: "If set, return only branches that appear before this branch in the config order" type: string required: false default: "" branches: description: "If set, return only this comma-separated list of branches" type: string required: false default: "" outputs: out: description: "JSON array of active branch patterns (filtered if requested)" value: ${{ jobs.get.outputs.out }} permissions: contents: read jobs: get: timeout-minutes: 30 runs-on: ${{ vars.RUNS_ON_MASTER_AMD64 || vars.RUNS_ON_AMD64 || 'ubuntu-24.04' }} outputs: out: ${{ steps.main.outputs.out }} steps: - name: Get active branches id: main shell: bash env: GH_TOKEN: ${{ github.token }} GH_DEBUG: ${{ runner.debug == '1' }} REPOSITORY: ${{ github.repository }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} EXCLUDE_DEFAULT: ${{ inputs.excludeDefault }} SHOW_SUMMARY: ${{ inputs.summary }} BEFORE_BRANCH: ${{ inputs.beforeBranch }} BRANCHES: ${{ inputs.branches }} run: | # shellcheck shell=bash [[ "${GH_DEBUG}" == "true" ]] && set -x set -euo pipefail readonly REPOSITORY="${REPOSITORY:?REPOSITORY is required}" readonly GITHUB_OUTPUT="${GITHUB_OUTPUT:?GITHUB_OUTPUT is required}" readonly GITHUB_STEP_SUMMARY="${GITHUB_STEP_SUMMARY:-/dev/null}" readonly EXCLUDE_DEFAULT="${EXCLUDE_DEFAULT:-false}" readonly DEFAULT_BRANCH="${DEFAULT_BRANCH:-master}" readonly SHOW_SUMMARY="${SHOW_SUMMARY:-${GH_DEBUG:-0}}" readonly BEFORE_BRANCH="${BEFORE_BRANCH:-}" readonly BRANCHES="${BRANCHES:-}" # If branches input is provided, short-circuit and return it as JSON array if [[ -n "${BRANCHES}" ]]; then echo "out=$(printf '%s' "${BRANCHES}" | jq --raw-input --compact-output ' split(",") | map(gsub("^[[:space:]]+|[[:space:]]+$";"")) | map(select(. != "")) ')" >> "$GITHUB_OUTPUT" exit 0 fi # Write summary to $GITHUB_STEP_SUMMARY when enabled write_summary() { local json="${1:-[]}" # treat 1/true/TRUE/yes as truthy case "${SHOW_SUMMARY}" in 1 | true | TRUE | yes | YES) ;; *) return 0 ;; esac local header="Active Branches" local parts=() if [[ "${EXCLUDE_DEFAULT}" == "true" ]]; then parts+=("without ${DEFAULT_BRANCH}") fi if [[ -n "${BEFORE_BRANCH}" ]]; then parts+=("before ${BEFORE_BRANCH}") fi if ((${#parts[@]})); then local IFS=', ' header+=" (${parts[*]})" fi { echo "${header}:" echo '```json' echo "${json}" echo '```' } >> "$GITHUB_STEP_SUMMARY" } # Read raw file to avoid manual base64 decoding if ! content="$( gh api -H 'Accept: application/vnd.github.raw' \ "/repos/${REPOSITORY}/contents/active-branches.json" 2> /dev/null )"; then echo 'out=[]' >> "$GITHUB_OUTPUT" exit 0 fi # Parse both legacy and new formats in a single jq pass, with optional filtering # Supported input formats: # - New: {"baseBranchPatterns": ["release-...","master"]} # - Old: ["release-...","master"] filtered="$( jq -c \ --arg exclude "${EXCLUDE_DEFAULT}" \ --arg default "${DEFAULT_BRANCH}" \ --arg before "${BEFORE_BRANCH}" ' def trim: gsub("^[[:space:]]+|[[:space:]]+$";""); def as_array: if type=="array" then . else (.baseBranchPatterns // []) end; def uniq_preserve(a): reduce a[] as $i ([]; if index($i) then . else . + [$i] end); def sort_key($def): if test("^release-[0-9]+\\.[0-9]+$") then (capture("^release-(?<maj>[0-9]+)\\.(?<min>[0-9]+)$") | [0, (.maj|tonumber), (.min|tonumber), ""]) elif ($def|length)>0 and . == $def then [2, 0, 0, .] # default branch last else [1, 0, 0, .] # other branches between releases and default end; (try as_array catch []) | map(select(type=="string") | trim) | map(select(length>0)) | if ($exclude=="true" and ($default|length)>0) then map(select(. != $default)) else . end | uniq_preserve(.) | (if ($before|length)>0 and (index($before) != null) then .[:index($before)] else . end) | sort_by(sort_key($default)) ' <<< "$content" )" echo "out=${filtered}" >> "$GITHUB_OUTPUT" # usage: write_summary "$filtered"
What changed
- 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.