From 89bbeab1ee06ba8e203e73881c1cc0593ccd6cc2 Mon Sep 17 00:00:00 2001 From: Patrick Lewis <4015312+locus313@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:37:03 -0700 Subject: [PATCH 1/2] refactor: replace get_all_pages with gh_api_paginate and use err() helper - Replace 52-line hand-rolled get_all_pages() paginator in github-close-archived-repo-security-alerts with gh_api_paginate streaming via 'while read'; non-array responses (e.g. Advanced Security not enabled) silently filtered by select(.number) - Replace print_error + exit 1 two-liners with err() across 9 scripts (17 sites); two multi-message sites merged into single err() calls - Merge CI shellcheck and unit-test jobs into one job to eliminate duplicate checkout + apt-get update; update ci-skip.yml to match - Merge two apt-get steps in copilot-setup-steps.yml into one - Remove ~96 lines of verbatim-duplicate content from AGENTS.md (script anatomy, helpers table, adding-a-script steps); replace with cross-reference to .github/copilot-instructions.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/ci-skip.yml | 13 ++- .github/workflows/ci.yml | 20 +--- .github/workflows/copilot-setup-steps.yml | 7 +- AGENTS.md | 106 +----------------- ...ub-add-enterprise-team-read-permissions.sh | 3 +- .../github-dockerfile-discovery.sh | 12 +- .../github-get-public-repos.sh | 9 +- .../github-install-enterprise-app.sh | 18 +-- ...ithub-add-repo-collaborators-by-pattern.sh | 3 +- .../github-add-repo-permissions.sh | 7 +- ...hub-close-archived-repo-security-alerts.sh | 95 +++------------- .../github-import-repo/github-import-repo.sh | 3 +- .../github-monthly-issues-report.sh | 6 +- 13 files changed, 55 insertions(+), 247 deletions(-) diff --git a/.github/workflows/ci-skip.yml b/.github/workflows/ci-skip.yml index 8a1742b..22ac6e2 100644 --- a/.github/workflows/ci-skip.yml +++ b/.github/workflows/ci-skip.yml @@ -1,10 +1,11 @@ name: CI # Companion to ci.yml. When a pull request only touches documentation or other -# path-ignored files, ci.yml is skipped entirely and its required "Shellcheck" -# check never reports — which blocks the PR from merging. This workflow runs on -# exactly those ignored paths and emits a passing check with the same job name, -# so the required status is always satisfied without a manual bypass. +# path-ignored files, ci.yml is skipped entirely and its required +# "Shellcheck + Unit Tests" check never reports — which blocks the PR from +# merging. This workflow runs on exactly those ignored paths and emits a passing +# check with the same job name, so the required status is always satisfied +# without a manual bypass. on: pull_request: @@ -14,8 +15,8 @@ on: - '.github/FUNDING.yml' jobs: - shellcheck: - name: Shellcheck + ci: + name: Shellcheck + Unit Tests runs-on: ubuntu-latest permissions: contents: read diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb6a722..2e97a4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,8 @@ on: - '.github/FUNDING.yml' jobs: - shellcheck: - name: Shellcheck + ci: + name: Shellcheck + Unit Tests runs-on: ubuntu-latest permissions: contents: read @@ -24,8 +24,8 @@ jobs: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: Install shellcheck - run: sudo apt-get update -qq && sudo apt-get install -y shellcheck + - name: Install shellcheck and bats + run: sudo apt-get update -qq && sudo apt-get install -y shellcheck bats - name: Run shellcheck on all scripts run: | @@ -34,17 +34,5 @@ jobs: --exclude=SC2034,SC1091 \ --shell=bash - test: - name: Unit Tests - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Install bats - run: sudo apt-get update -qq && sudo apt-get install -y bats - - name: Run unit tests run: bats tests/ diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index ea1787b..c8f3233 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -10,11 +10,8 @@ jobs: - name: Checkout code uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: Install jq - run: sudo apt-get update -qq && sudo apt-get install -y jq - - - name: Install shellcheck - run: sudo apt-get install -y shellcheck + - name: Install jq, shellcheck, and bats + run: sudo apt-get update -qq && sudo apt-get install -y jq shellcheck bats - name: Install gitleaks run: | diff --git a/AGENTS.md b/AGENTS.md index 5bc8f58..a5dcf98 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -136,106 +136,10 @@ Use `_mock_curl_200` (defined in `test_script_validation.bats`) when a test must ## Key Patterns and Conventions -### Script anatomy - -Every script begins with a `# ===` header (exactly 79 `=` chars), then immediately `set -euo pipefail`: - -```bash -#!/usr/bin/env bash -# ============================================================================= -# github-.sh -# -# -# -# Usage: -# export GITHUB_TOKEN=ghp_yourtoken -# export ORG=my-org -# ./github-.sh -# -# Environment variables: -# GITHUB_TOKEN Required. PAT with scope -# ORG Required. GitHub organization name -# API_URL_PREFIX Optional. GitHub API base URL (default: https://api.github.com) -# -# Requirements: -# - curl -# - jq -# ============================================================================= - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# shellcheck source=../../lib/github-common.sh -source "${SCRIPT_DIR}/../../lib/github-common.sh" -``` - -### Sourcing the shared library - -Always use `SCRIPT_DIR` to build the path to `lib/github-common.sh`. The library is two directory levels up from any script (`../../lib/github-common.sh`). Never hardcode absolute paths. - -### Authentication - -- Standard org/repo REST calls: `Authorization: token ${GITHUB_TOKEN}` -- Enterprise endpoints and GraphQL: `Authorization: Bearer ${GITHUB_TOKEN}` -- The `gh_api` helper in `lib/github-common.sh` always uses Bearer; pass `"bearer"` to `validate_github_token` for enterprise scripts - -### Shared library helpers - -| Function | Purpose | -|----------|---------| -| `print_status` / `print_success` / `print_warning` / `print_error` | Colored output | -| `err ` | `print_error` + `exit 1` in one call | -| `require_env_var ` | Exit with message if variable unset/empty | -| `require_command ` | Exit if binary not in PATH | -| `configure_gh_auth [scope_hint]` | Bridge GITHUB_TOKEN→GH_TOKEN or verify gh auth session | -| `validate_github_token [bearer]` | Verify GITHUB_TOKEN via /user endpoint | -| `validate_slug