You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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>
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.
175
-
176
-
### Authentication
177
-
178
-
- Standard org/repo REST calls: `Authorization: token ${GITHUB_TOKEN}`
179
-
- Enterprise endpoints and GraphQL: `Authorization: Bearer ${GITHUB_TOKEN}`
180
-
- The `gh_api` helper in `lib/github-common.sh` always uses Bearer; pass `"bearer"` to `validate_github_token` for enterprise scripts
|`err <message>`|`print_error` + `exit 1` in one call |
188
-
|`require_env_var <VAR>`| Exit with message if variable unset/empty |
189
-
|`require_command <cmd>`| Exit if binary not in PATH |
190
-
|`configure_gh_auth [scope_hint]`| Bridge GITHUB_TOKEN→GH_TOKEN or verify gh auth session |
191
-
|`validate_github_token [bearer]`| Verify GITHUB_TOKEN via /user endpoint |
192
-
|`validate_slug <value> <label>`| Reject values with non-alphanumeric/hyphen/underscore chars |
193
-
|`gh_api <path> [--api-version V] [curl args...]`| Bearer-auth REST helper with 5-retry rate-limit handling; optional `--api-version` overrides the default `2022-11-28` header; returns literal `__404__` or `__422__` for those HTTP statuses — callers must check for these sentinels |
194
-
|`gh_api_paginate <path> [filter] [version]`| Paginated REST helper, follows Link headers, streams items; returns silently with empty output on 404/422 |
|`get_repo_page_count <url>`| Returns total pages for a paginated endpoint |
197
-
198
-
### Error handling sequence
199
-
200
-
1.`require_env_var` all required variables
201
-
2.`validate_github_token` (or `validate_token` for secondary tokens)
202
-
3. Validate additional inputs with `validate_slug` where needed
203
-
4. Proceed with main logic
204
-
205
-
> **Note on token auto-resolution:** Sourcing `lib/github-common.sh` automatically populates `GITHUB_TOKEN` from an active `gh` auth session if the variable is unset. This means `require_env_var GITHUB_TOKEN` may pass even when no explicit token was provided by the caller — the token was silently resolved from `gh auth token`. Script headers should document `GITHUB_TOKEN` as "Required (or provided by an active gh auth session)". Scripts that use the `gh` CLI instead of `curl` should call `configure_gh_auth` instead of step 2 above.
-`gh_api` auto-retries on HTTP 403/429 with 60s sleep
220
-
-`gh_api` returns the literal string `__404__` or `__422__` (exit 0) for those HTTP statuses — callers must check for these sentinels before passing output to `jq`
221
-
222
-
---
223
-
224
-
## Adding a New Script
225
-
226
-
1.**Create the directory:**`<domain>/github-<verb-noun>/`
227
-
2.**Create the script:**`github-<verb-noun>.sh` (name must match the directory)
228
-
3.**Copy the header template** from Script Anatomy above — fill in description, all env vars, requirements
229
-
4.**Source the shared library** using `SCRIPT_DIR`
230
-
5.**Validate all inputs** before any API calls
231
-
6.**Create `action.yml`** in the same directory — expose every env var as an input (required inputs first, optional inputs with defaults); map CLI flags (`--dry-run`, `--type`, etc.) to boolean/string inputs and construct the `ARGS` array in the `run:` step. See existing `action.yml` files for the pattern.
232
-
7.**Add tests to `tests/test_script_validation.bats`** — add a labelled section (`# ═══ github-<name> ═══`) with tests for: every required env var missing (exit 1), unknown CLI args (exit 1), `--help` exits 0, and any script-specific validation (enum guards, URL allowlists, positional args). See existing sections for the pattern.
233
-
8.**Add to README.md** — follow the existing format: use case, env var table, usage example, output format; add a row to the Available Actions table in the "Using Scripts in GitHub Actions" section
-**CI:** shellcheck runs on all `.sh` files on every PR (`.github/workflows/ci.yml`); bats unit tests run in a dedicated `test` job (`bats tests/`)
151
+
-**CI:** shellcheck + bats unit tests run together on every PR (`.github/workflows/ci.yml`)
248
152
-**Releases:** automated by Release Please (`.github/workflows/release.yml`) — pushes to `main` trigger a release PR; merging it publishes the GitHub Release and tag
0 commit comments