Skip to content

Generate runners status #1415

Generate runners status

Generate runners status #1415

name: "Generate runners status"
on:
push:
schedule:
- cron: '0 * * * *' # Run every hour
workflow_dispatch: # Manually triggered via GitHub Actions UI
#concurrency:
# group: redirector
# cancel-in-progress: false
jobs:
Check:
name: "Check permissions"
runs-on: "ubuntu-22.04"
steps:
- name: "Check permissions"
uses: armbian/actions/team-check@main
with:
ORG_MEMBERS: ${{ secrets.ORG_MEMBERS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TEAM: "Release manager"
build:
name: "Get self hosted runners status"
runs-on: ubuntu-24.04
needs: Check
steps:
- name: "Install dependencies: jq"
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: jq
version: 1.0
- name: "Get runners from ORG"
env:
GH_TOKEN: ${{ secrets.RUNNERS }}
run: |
GH_TOKEN=${{ secrets.RUNNERS }}
NETBOX_TOKEN=${{ secrets.NETBOX_TOKEN }}
NETBOX_API=${{ secrets.NETBOX_API }}
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
runners_nd="$tmp/runners.ndjson"
out_html="$tmp/runners_summary.html"
: > "$runners_nd"
# Fetch ALL GitHub org runners (prefer gh; fallback to curl)
if command -v gh >/dev/null 2>&1; then
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
--paginate /orgs/armbian/actions/runners \
-q '.runners[]' > "$runners_nd"
else
curl -fsSL \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/orgs/armbian/actions/runners?per_page=100" \
| jq -c '.runners[]' > "$runners_nd"
fi
# Build lookup maps
declare -A RUNNER_STATUS RUNNER_BUSY
while IFS=$'\t' read -r name status busy; do
RUNNER_STATUS["$name"]="$status"
RUNNER_BUSY["$name"]="$busy"
done < <(jq -r '[.name, .status, (.busy|tostring)] | @tsv' "$runners_nd")
# Fetch NetBox VMs
nb_json="$tmp/netbox.json"
curl -s \
-H "Authorization: Token ${NETBOX_TOKEN}" \
-H "Accept: application/json; indent=4" \
"${NETBOX_API}/virtualization/virtual-machines/?limit=500&name__empty=false&tag=github-runner&status=active" \
> "$nb_json"
# Render to stdout and to HTML file
echo "<table border=0>" >> $GITHUB_STEP_SUMMARY
echo "<tr><th align=left>Server</th><th align=left>Runner label</th><th align=right>CPU cores</th><th align=right>Memory GB</th><th align=right>Storage GB</th><th align=right>Runners</th></tr>" >> $GITHUB_STEP_SUMMARY
# init totals
total_cpu=0
total_mem_gb=0
total_storage_gb=0
total_runners=0
while IFS=$'\t' read -r NAME CPU MEM_MB DISK_GB RUNNERS LABELS ID; do
CALC_MEM=$(( (MEM_MB + 512) / 1024 ))
printf "<tr><td>%s</td><td>%s</td><td align=right>%d</td><td align=right>%d</td><td align=right>%d</td><td align=right>%d</td></tr>\n" \
"$NAME" "$LABELS" "$CPU" "$CALC_MEM" "$DISK_GB" "$RUNNERS" >> $GITHUB_STEP_SUMMARY
echo "<tr><td colspan=6>" >> $GITHUB_STEP_SUMMARY
if [[ "$RUNNERS" -gt 0 ]]; then
for i in $(seq -f "%02g" 1 "$RUNNERS"); do
rn="${LABELS}-${i}"
if [[ -n "${RUNNER_STATUS[$rn]:-}" || "$LABELS" == "github" ]]; then
printf "🟢" >> $GITHUB_STEP_SUMMARY
else
printf "🔴 <small>(%s)</small> " "$i" >> $GITHUB_STEP_SUMMARY
fi
done
fi
echo "</td></tr>" >> $GITHUB_STEP_SUMMARY
# accumulate totals (note: no $ needed for CPU/RUNNERS inside arithmetic)
total_cpu=$(( total_cpu + CPU ))
total_mem_gb=$(( total_mem_gb + CALC_MEM ))
total_storage_gb=$(( total_storage_gb + DISK_GB ))
total_runners=$(( total_runners + RUNNERS ))
done < <(jq -r '
.results[] |
[
.name,
((.vcpus // 0) | floor),
((.memory // 0) | floor),
((.disk // 0) | floor),
(.custom_fields["runners"] // 0),
(.custom_fields["labels"] // "null"),
.id
] | @tsv
' "$nb_json")
# summary row
printf "<tr><th colspan=2 align=right>Totals:</th><th align=right>%d</th><th align=right>%d</th><th align=right>%d</th><th align=right>%d</th></tr>\n" \
"$total_cpu" "$total_mem_gb" "$total_storage_gb" "$total_runners" >> $GITHUB_STEP_SUMMARY
echo "</table>" >> $GITHUB_STEP_SUMMARY