From d872bdc626dff02ed2bfb76203dad7905e7930a5 Mon Sep 17 00:00:00 2001 From: Chris Farhood Date: Sun, 3 May 2026 18:08:56 +0000 Subject: [PATCH 1/2] ci-health-check.sh: replace hardcoded repos with dynamic GitHub API discovery Use gh api --paginate to dynamically fetch all non-archived public repos matching ^headlamp-.+ from the privilegedescalation org. This eliminates the need to manually update the repo list when new plugins are added. NOTE: --paginate must come before the endpoint arg, not after --jq. The previous commit had 'gh api paginate' which is incorrect syntax. Co-Authored-By: Paperclip --- .github/scripts/ci-health-check.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/scripts/ci-health-check.sh b/.github/scripts/ci-health-check.sh index 3b003d4..40ceef5 100755 --- a/.github/scripts/ci-health-check.sh +++ b/.github/scripts/ci-health-check.sh @@ -6,17 +6,17 @@ set -euo pipefail ORG="privilegedescalation" -PLUGIN_REPOS=( - headlamp-polaris-plugin - headlamp-rook-plugin - headlamp-sealed-secrets-plugin - headlamp-intel-gpu-plugin - headlamp-tns-csi-plugin - headlamp-kube-vip-plugin - headlamp-argocd-plugin - headlamp-plugin-template +mapfile -t PLUGIN_REPOS < <( + gh api --paginate "orgs/${ORG}/repos" \ + --jq '.[] | select(.archived == false and .visibility == "public") | .name' \ + 2>/dev/null | grep -E '^headlamp-.+' | sort ) +if [ ${#PLUGIN_REPOS[@]} -eq 0 ]; then + echo "ERROR: No repos discovered for ${ORG}" >&2 + exit 1 +fi + echo "=== CI/CD Health Check — $(date -u '+%Y-%m-%d %H:%M UTC') ===" echo "" From 0ff52c20fdc13a3fa6605da35040a7abbe998440 Mon Sep 17 00:00:00 2001 From: Chris Farhood Date: Sun, 3 May 2026 18:17:53 +0000 Subject: [PATCH 2/2] ci-health-check: complete dynamic repo discovery (PRI-331) PR #115's first commit landed dynamic discovery via gh api but missed three of the five issue requirements. This commit completes them: - Move headlamp- prefix filtering into jq via startswith() and add explicit exclusion for headlamp-agent-skills (skills bundle, not a plugin), instead of relying on grep -E '^headlamp-.+'. - Add PLUGIN_REPOS_FALLBACK with the previously hardcoded list and use it when discovery returns empty, instead of exiting with error. - Add header comment documenting the discovery filter and the headlamp-agent-skills exclusion. Verified jq filter against live API: returns 8 plugin repos, all prefixed headlamp-, headlamp-agent-skills correctly excluded. Co-Authored-By: Paperclip --- .github/scripts/ci-health-check.sh | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/.github/scripts/ci-health-check.sh b/.github/scripts/ci-health-check.sh index 40ceef5..094a19c 100755 --- a/.github/scripts/ci-health-check.sh +++ b/.github/scripts/ci-health-check.sh @@ -2,19 +2,41 @@ # ci-health-check.sh — Scan all privilegedescalation repos for CI/CD health # Run from: /paperclip/privilegedescalation/engineering/hugh # Requires: GH_TOKEN set (use: export GH_TOKEN=$(bash ./get-github-token.sh)) +# +# Plugin repo discovery +# --------------------- +# PLUGIN_REPOS is populated dynamically from the GitHub org so newly created +# plugin repos are picked up automatically. The filter is: +# - non-archived, public repos in the privilegedescalation org +# - name starts with "headlamp-" +# - excludes "headlamp-agent-skills" (skills bundle, not a Headlamp plugin) +# If discovery fails (network error, GH_TOKEN missing, API outage), we fall +# back to a hardcoded list so the health check still produces a useful report. set -euo pipefail ORG="privilegedescalation" +# Hardcoded fallback — kept in sync manually as a safety net for discovery failures. +PLUGIN_REPOS_FALLBACK=( + headlamp-polaris-plugin + headlamp-rook-plugin + headlamp-sealed-secrets-plugin + headlamp-intel-gpu-plugin + headlamp-tns-csi-plugin + headlamp-kube-vip-plugin + headlamp-plugin-template + headlamp-argocd-plugin +) + mapfile -t PLUGIN_REPOS < <( gh api --paginate "orgs/${ORG}/repos" \ - --jq '.[] | select(.archived == false and .visibility == "public") | .name' \ - 2>/dev/null | grep -E '^headlamp-.+' | sort + --jq '.[] | select(.archived == false and .visibility == "public" and (.name | startswith("headlamp-")) and .name != "headlamp-agent-skills") | .name' \ + 2>/dev/null | sort ) if [ ${#PLUGIN_REPOS[@]} -eq 0 ]; then - echo "ERROR: No repos discovered for ${ORG}" >&2 - exit 1 + echo "WARNING: dynamic repo discovery returned no results — using hardcoded fallback" >&2 + PLUGIN_REPOS=("${PLUGIN_REPOS_FALLBACK[@]}") fi echo "=== CI/CD Health Check — $(date -u '+%Y-%m-%d %H:%M UTC') ==="