Skip to content

Commit 652f36d

Browse files
locus313Copilot
andauthored
docs: document gh_api sentinel contract and gh_api_paginate across all docs (#27)
- lib/github-common.sh: rewrite # Provides: header block — fix scrambled layout, add get_repo_page_count, document __404__/__422__ sentinel contract on gh_api, and note gh_api_paginate empty-output behaviour - README.md: add configure_gh_auth to its own Auth helpers section; add gh_api_paginate to API helpers; clarify gh_api sentinel contract; move validate_slug to Validation section - AGENTS.md: update gh_api and gh_api_paginate table rows to describe sentinel contract; add sentinel note to Rate limiting section - copilot-instructions.md: update gh_api rate-limiting bullet to include sentinel contract; update github-dockerfile-discovery description to document both gh_api call sites' sentinel handling; add gh_api_paginate row to maintenance matrix Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 772fd1f commit 652f36d

4 files changed

Lines changed: 28 additions & 18 deletions

File tree

.github/copilot-instructions.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ For enterprise-level org iteration (GraphQL), use cursor-based pagination — se
101101
Rate limiting delays are calibrated per operation type:
102102
- **Repo-level operations** (permission grants, archival): `sleep 5` between each repository.
103103
- **Code search** (`github-dockerfile-discovery`): configurable via `SEARCH_SLEEP` (default 2 s) and `CONTENT_SLEEP` (default 1 s).
104-
- **gh_api helper** (lib): auto-retries up to 5 times on HTTP 403/429, sleeping 60 s before each retry.
104+
- **gh_api helper** (lib): auto-retries up to 5 times on HTTP 403/429, sleeping 60 s before each retry. Returns the literal string `__404__` or `__422__` (exit 0) for those HTTP statuses instead of failing — every caller must check for these sentinels before passing the result to `jq`. `gh_api_paginate` returns silently with empty output on 404/422.
105105

106106
### Authentication Headers
107107

@@ -161,7 +161,7 @@ Dismisses open Dependabot, code-scanning, and secret-scanning alerts on all arch
161161

162162
### `github-dockerfile-discovery`
163163

164-
Uses GitHub code-search API to find Dockerfiles across all enterprise orgs, then fetches and parses each file to extract `FROM` instructions (including multi-stage builds). Produces three timestamped reports in `REPORT_DIR`: a detail CSV, a summary CSV, and a plain-text summary. Supports `ORGS` override, `ORG_FILTER`/`ORG_EXCLUDE` regex filters (validated as syntactically correct ERE before use), and configurable sleep intervals (`SEARCH_SLEEP`, `CONTENT_SLEEP`).
164+
Uses GitHub code-search API to find Dockerfiles across all enterprise orgs, then fetches and parses each file to extract `FROM` instructions (including multi-stage builds). Produces three timestamped reports in `REPORT_DIR`: a detail CSV, a summary CSV, and a plain-text summary. Supports `ORGS` override, `ORG_FILTER`/`ORG_EXCLUDE` regex filters (validated as syntactically correct ERE before use), and configurable sleep intervals (`SEARCH_SLEEP`, `CONTENT_SLEEP`). Both `gh_api` call sites handle sentinels: `__422__` or `__404__` on the code-search endpoint skips that org with a warning; `__404__` or `__422__` on the file-contents endpoint skips that individual file.
165165

166166
### `github-enable-issues`
167167

@@ -270,6 +270,7 @@ When you change one of these files, you must also update the files in the "Also
270270
|------------------|-------------|
271271
| `lib/github-common.sh` — any public function signature or behaviour | All 18 scripts that source it; verify each caller still passes the right arguments. Check with: `grep -r "github-common" . --include="*.sh"` |
272272
| `lib/github-common.sh` — add a new helper function | `AGENTS.md` shared library table; `README.md` if the function affects usage |
273+
| `gh_api_paginate` signature or pagination behaviour | `github-repo-permissions-report.sh` (3 call sites), `github-copilot-report.sh` (`fetch_seats`) — both pipe output through `jq -s '.'` and depend on the `jq_filter`/`api_version` parameter order |
273274
| Any script's required env vars | That script's `# ===` header comment; the corresponding README.md section's env var table; that script's `action.yml` inputs (add/remove required inputs to match) |
274275
| Any script's optional env vars or defaults | Same as above; update the `action.yml` optional inputs and their defaults |
275276
| Any script's `--dry-run` or CLI flag behaviour | README.md usage example for that script; that script's `action.yml` inputs and `run:` step flag construction |

AGENTS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ Always use `SCRIPT_DIR` to build the path to `lib/github-common.sh`. The library
145145
| `configure_gh_auth [scope_hint]` | Bridge GITHUB_TOKEN→GH_TOKEN or verify gh auth session |
146146
| `validate_github_token [bearer]` | Verify GITHUB_TOKEN via /user endpoint |
147147
| `validate_slug <value> <label>` | Reject values with non-alphanumeric/hyphen/underscore chars |
148-
| `gh_api <path> [curl args...]` | Bearer-auth REST helper with 5-retry rate-limit handling |
149-
| `gh_api_paginate <path> [filter] [version]` | Paginated REST helper, follows Link headers, streams items |
148+
| `gh_api <path> [curl args...]` | Bearer-auth REST helper with 5-retry rate-limit handling; returns literal `__404__` or `__422__` for those HTTP statuses — callers must check for these sentinels |
149+
| `gh_api_paginate <path> [filter] [version]` | Paginated REST helper, follows Link headers, streams items; returns silently with empty output on 404/422 |
150150
| `get_enterprise_orgs` | Three-tier enterprise org resolver (REST → GraphQL → /user/orgs) |
151151
| `get_repo_page_count <url>` | Returns total pages for a paginated endpoint |
152152

@@ -172,6 +172,7 @@ done
172172
- Repo-level operations (permission grants, archival): `sleep 5` between each repo
173173
- Code search: configurable `SEARCH_SLEEP` (default 2s) and `CONTENT_SLEEP` (default 1s)
174174
- `gh_api` auto-retries on HTTP 403/429 with 60s sleep
175+
- `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`
175176

176177
---
177178

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -854,11 +854,15 @@ All scripts can leverage a shared utility library for common operations like val
854854
- `require_command <cmd> [hint]` — Exit if command is not in PATH
855855
- `validate_token <VAR_NAME> [bearer]` — Validate GitHub token by calling `/user` endpoint
856856
- `validate_github_token [bearer]` — Convenience wrapper for `GITHUB_TOKEN` validation
857+
- `validate_slug <value> <label>` — Exit if value contains characters other than alphanumeric, hyphen, or underscore
858+
859+
**Auth helpers:**
860+
- `configure_gh_auth [scope_hint]` — Bridge `GITHUB_TOKEN→GH_TOKEN` for scripts that use the `gh` CLI, or verify an active `gh` auth session if no token is set
857861

858862
**API helpers:**
859863
- `get_repo_page_count <url>` — Get total page count from paginated REST endpoint
860-
- `validate_slug <value> <label>`Exit if value contains characters other than alphanumeric, hyphen, or underscore
861-
- `gh_api <path|url> [curl args...]`Bearer-auth REST helper with automatic rate-limit retry (up to 5 attempts); returns `__404__` / `__422__` for those status codes instead of failing
864+
- `gh_api <path|url> [curl args...]`Bearer-auth REST helper with automatic rate-limit retry (up to 5 attempts); returns the literal string `__404__` or `__422__` (exit 0) for those status codes — callers must check for these sentinels before passing the result to `jq`
865+
- `gh_api_paginate <path> [jq_filter] [api_version]`Paginated REST helper that follows `Link` headers and streams items through `jq_filter` (default `.[]`); silently returns empty output on 404/422; pipe through `jq -s '.'` to collect all items as an array
862866
- `_paginate_orgs_endpoint <jq_filter> <url_template>` — Page through an org-list REST endpoint, printing one login per line; use `PAGE` as a placeholder in the URL template
863867
- `_graphql_enterprise_orgs` — Cursor-based GraphQL pagination for all orgs in `ENTERPRISE`; prints one login per line
864868
- `get_enterprise_orgs` — Three-tier enterprise org resolver: tries REST `/enterprises/{slug}/organizations`, falls back to GraphQL, then falls back to `/user/orgs`

lib/github-common.sh

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,26 @@
1212
#
1313
# Provides:
1414
# print_status / print_success / print_warning / print_error
15-
# require_env_var <VAR> [description] — exit if variable is unset/empty
16-
# require_command <cmd> — exit if command not found
17-
# configure_gh_auth [scope_hint] — bridge GITHUB_TOKEN→GH_TOKEN or verify gh session
18-
# validate_github_token [bearer] — verify token via /user endpoint
15+
# require_env_var <VAR> [description] — exit if variable is unset/empty
16+
# require_command <cmd> — exit if command not found
17+
# configure_gh_auth [scope_hint] — bridge GITHUB_TOKEN→GH_TOKEN or verify gh session
18+
# validate_github_token [bearer] — verify GITHUB_TOKEN via /user endpoint
19+
# validate_token <VAR_NAME> — verify a secondary token variable
20+
# validate_slug <value> [label] — exit if value contains unsafe chars
21+
# gh_api <path|url> [curl args...] — Bearer-auth REST helper with retry;
22+
# returns "__404__"/"__422__" (exit 0) for those codes
23+
# gh_api_paginate <path> [filter] [version] — paginated REST, follows Link headers;
24+
# silently returns empty output on 404/422
25+
# get_repo_page_count <url> — total page count for a paginated REST endpoint
26+
# _paginate_orgs_endpoint <filter> <url_tpl> — page through an org list (internal)
27+
# _graphql_enterprise_orgs — GraphQL cursor-based enterprise orgs (internal)
28+
# get_enterprise_orgs — three-tier enterprise org resolver
1929
#
2030
# Token auto-resolution (at source time):
2131
# If GITHUB_TOKEN is unset and gh CLI is available, the token is automatically
2232
# resolved from the active gh auth session so curl-based scripts work with
23-
# either a GITHUB_TOKEN env var or a gh CLI session.
24-
# validate_token <VAR_NAME> — verify a secondary token variable
25-
# validate_slug <value> [label] — exit if value contains unsafe chars
26-
# gh_api <path|url> [curl args...] — Bearer-auth REST helper with retry
27-
# gh_api_paginate <path> [filter] [version] — paginated REST, follows Link headers
28-
# _paginate_orgs_endpoint <filter> <url_tpl> — page through an org list
29-
# _graphql_enterprise_orgs — GraphQL cursor-based enterprise orgs
30-
# get_enterprise_orgs — three-tier enterprise org resolver
33+
# either a GITHUB_TOKEN env var or a gh CLI session. GH_TOKEN is also kept
34+
# in sync with GITHUB_TOKEN so gh CLI calls use the same credential.
3135
# =============================================================================
3236

3337
###

0 commit comments

Comments
 (0)