Generate runners status #1415
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |