Skip to content

Commit d45fe33

Browse files
locus313Copilot
andauthored
feat: add dual-auth support (GITHUB_TOKEN + gh CLI) across all scripts (#21)
* feat: add dual-auth support and gh_api_paginate to shared lib - Auto-resolve GITHUB_TOKEN from active gh CLI session at source time so curl-based scripts work with either a PAT or gh CLI auth - Add configure_gh_auth() to bridge GITHUB_TOKEN→GH_TOKEN for scripts that use the gh CLI directly - Add gh_api_paginate() — paginated REST helper that follows Link headers, streams items through a jq filter, handles 404/422 silently, and supports a custom API version header for Copilot endpoints Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: make github-token optional in all action.yml files - Change github-token from required to optional in all 16 existing action.yml files; env mapping uses inputs.github-token || github.token so the built-in Actions token is used automatically when no PAT is provided - Add new action.yml for github-repo-permissions-report - Add new action.yml for github-copilot-report (with no-entra, credits, enterprise, and upn-domain inputs) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: convert gh-CLI-only scripts to support GITHUB_TOKEN + curl github-organize-stars: - Now sources lib/github-common.sh for shared helpers - Calls configure_gh_auth to bridge GITHUB_TOKEN→GH_TOKEN; kept as gh-CLI-based since it uses GraphQL mutations not available via REST github-repo-permissions-report: - Removed gh CLI dependency; now uses curl via lib's gh_api and gh_api_paginate for all API calls - Branch protection and ruleset 404s handled via __404__ sentinel github-copilot-report: - Removed gh CLI dependency; added local _copilot_api() using curl with X-GitHub-Api-Version: 2026-03-10 - fetch_seats() now uses gh_api_paginate with the Copilot API version - az CLI is now truly optional: if not installed or not logged in, Entra ID enrichment is silently skipped (--no-entra also works on runners without az installed) - Added missing API_URL_PREFIX default to fix validate_github_token Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: update all docs to reflect dual-auth support - README: prerequisites for repo-permissions-report and copilot-report updated from gh CLI to curl; az marked as optional; available actions table includes both new scripts; usage examples updated - AGENTS.md: shared library table adds configure_gh_auth and gh_api_paginate; tech stack row for gh CLI updated to only list github-organize-stars; error handling sequence documents the auto-resolution side-effect - copilot-instructions.md: script descriptions for repo-permissions-report and copilot-report updated to reflect curl usage; copilot-report az requirement noted as optional/runtime-checked Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 67fce02 commit d45fe33

24 files changed

Lines changed: 324 additions & 102 deletions

File tree

.github/copilot-instructions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,19 +193,19 @@ Generates an HTML report of issues created in a date range (`MONTH_START`/`MONTH
193193

194194
### `github-organize-stars`
195195

196-
Uses `gh` CLI GraphQL (not `curl`) to fetch all starred repos. Categorizes by primary language, GitHub topics, and name keywords using a `RULES` array (pipe-delimited: `List Name|LANGUAGES|TOPICS|NAME_KEYWORDS`; first matching rule wins). Caches stars at `~/.cache/gh-star-organizer/stars.json`. Supports `--dry-run`, `-y` (skip confirm), `--show-repos`, and `--no-cache`. Adds repos to Lists in batches of 25.
196+
Uses `gh` CLI GraphQL (not `curl`) to fetch all starred repos. Accepts `GITHUB_TOKEN` env var or an active `gh` auth session for authentication. Categorizes by primary language, GitHub topics, and name keywords using a `RULES` array (pipe-delimited: `List Name|LANGUAGES|TOPICS|NAME_KEYWORDS`; first matching rule wins). Caches stars at `~/.cache/gh-star-organizer/stars.json`. Supports `--dry-run`, `-y` (skip confirm), `--show-repos`, and `--no-cache`. Adds repos to Lists in batches of 25.
197197

198198
### `github-repo-from-template`
199199

200200
Creates a private repo from `TEMPLATE_REPO` (including all branches), assigns admin permissions to space-separated `REPO_ADMIN` teams, write permissions to `REPO_WRITE` teams, then invites `CD_USERNAME` as a collaborator using `CD_GITHUB_TOKEN` and auto-accepts the invitation. All slug values are validated before use.
201201

202202
### `github-repo-permissions-report`
203203

204-
Uses `gh` CLI (not `curl`/`GITHUB_TOKEN`) for all API calls. Accepts `-r OWNER/REPO`, `-b BRANCH`, and `-o FILE` flags. Outputs a CSV with two record types: `permission` (all users/teams) and `bypass_actor` (explicit PR approval bypass entries). Reports both branch protection rules and repository rulesets. Requires `gh auth login` before running — no `GITHUB_TOKEN` env var needed.
204+
Uses `curl` for all API calls. Accepts `GITHUB_TOKEN` env var or an active `gh` auth session (token auto-resolved at lib source time) for authentication. Accepts `-r OWNER/REPO`, `-b BRANCH`, and `-o FILE` flags. Outputs a CSV with two record types: `permission` (all users/teams) and `bypass_actor` (explicit PR approval bypass entries). Reports both branch protection rules and repository rulesets.
205205

206206
### `github-copilot-report`
207207

208-
Uses `gh` CLI (not `curl`/`GITHUB_TOKEN`) for all GitHub API calls; requires `gh auth refresh --scopes "read:enterprise,manage_billing:enterprise"`. Also requires `az` to be **installed** (not just logged in) — the script calls `require_command az` unconditionally before checking `--no-entra`. When `az` is logged in, enriches each user with Entra ID department and job title via `az rest`.
208+
Uses `curl` for all GitHub API calls. Accepts `GITHUB_TOKEN` env var (PAT with `read:enterprise` and `manage_billing:enterprise` scopes) or an active `gh` auth session (token auto-resolved at lib source time) for authentication. Also requires `az` to be **installed** when Entra ID enrichment is needed — `az` is checked at runtime only if `--no-entra` is not set and `az` is not already skipped. If `az` is not installed or not logged in, Entra lookup is silently skipped. When `az` is logged in, enriches each user with Entra ID department and job title via `az rest`.
209209

210210
Auto-detects credits per seat from a promo/standard table keyed on plan type and today's date (promo period Jun 1 – Sep 1, 2026); override with `--credits N` or `$CREDITS_PER_SEAT_OVERRIDE`. Credits are pooled enterprise-wide, not per-user buckets. Code completions are not billed in AI credits.
211211

AGENTS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ github-api-scripts/
4747
| bash 4+ | All scripts |
4848
| curl | GitHub REST and GraphQL API calls |
4949
| jq | JSON parsing and transformation |
50-
| gh CLI | Used in `github-organize-stars` and `github-repo-permissions-report` |
50+
| gh CLI | Used in `github-organize-stars` |
5151
| base64 | Used in `github-auto-repo-creation` for CODEOWNERS encoding |
5252
| git | Used in `github-import-repo` for bare clone + mirror push |
5353
| shellcheck | Linting (pre-commit hook + CI) |
@@ -142,9 +142,11 @@ Always use `SCRIPT_DIR` to build the path to `lib/github-common.sh`. The library
142142
| `print_status` / `print_success` / `print_warning` / `print_error` | Colored output |
143143
| `require_env_var <VAR>` | Exit with message if variable unset/empty |
144144
| `require_command <cmd>` | Exit if binary not in PATH |
145+
| `configure_gh_auth [scope_hint]` | Bridge GITHUB_TOKEN→GH_TOKEN or verify gh auth session |
145146
| `validate_github_token [bearer]` | Verify GITHUB_TOKEN via /user endpoint |
146147
| `validate_slug <value> <label>` | Reject values with non-alphanumeric/hyphen/underscore chars |
147148
| `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 |
148150
| `get_enterprise_orgs` | Three-tier enterprise org resolver (REST → GraphQL → /user/orgs) |
149151
| `get_repo_page_count <url>` | Returns total pages for a paginated endpoint |
150152

@@ -155,6 +157,8 @@ Always use `SCRIPT_DIR` to build the path to `lib/github-common.sh`. The library
155157
3. Validate additional inputs with `validate_slug` where needed
156158
4. Proceed with main logic
157159

160+
> **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.
161+
158162
### Pagination (REST)
159163

160164
```bash

README.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -516,11 +516,12 @@ cd reporting/github-monthly-issues-report
516516
Exports repository user/team permissions to CSV and identifies who can bypass pull request approval requirements, from both branch protection rules and repository rulesets.
517517

518518
**Prerequisites:**
519-
- **[gh](https://cli.github.com)**GitHub CLI (authenticated via `gh auth login`)
519+
- **[curl](https://curl.se)**HTTP client
520520
- **[jq](https://stedolan.github.io/jq)** — JSON processor
521521

522522
**Usage:**
523523
```bash
524+
export GITHUB_TOKEN=ghp_yourtoken # or resolved automatically from an active gh auth session
524525
cd reporting/github-repo-permissions-report
525526
./github-repo-permissions-report.sh -r OWNER/REPO
526527
./github-repo-permissions-report.sh -r OWNER/REPO -b main -o report.csv
@@ -540,9 +541,6 @@ cd reporting/github-repo-permissions-report
540541
- Identifies every principal that can bypass PR approval requirements
541542
- Produces a CSV with two record types: `permission` (all users/teams) and `bypass_actor` (explicit bypass entries)
542543

543-
> [!NOTE]
544-
> Uses the `gh` CLI for all API calls. Authenticate via `gh auth login` before running.
545-
546544
---
547545

548546
### Copilot Enterprise Report
@@ -552,14 +550,18 @@ cd reporting/github-repo-permissions-report
552550
Generates a GitHub Copilot Enterprise licence and usage report. Shows every licensed user, their plan type, pool credit contribution, and actual AI credit consumption for the current billing month. Optionally enriches data with Entra ID department information.
553551

554552
**Prerequisites:**
555-
- **[gh](https://cli.github.com)**GitHub CLI authenticated with `read:enterprise` and `manage_billing:enterprise` scopes
556-
- **[az](https://learn.microsoft.com/en-us/cli/azure/)** — Azure CLI (must be installed; login required only for Entra ID department enrichment — pass `--no-entra` to skip the login requirement)
553+
- **[curl](https://curl.se)**HTTP client
554+
- **[az](https://learn.microsoft.com/en-us/cli/azure/)** — Azure CLI (optional; required only for Entra ID department enrichment — pass `--no-entra` or omit az to skip)
557555
- **[jq](https://stedolan.github.io/jq)** — JSON processor
558556

559557
**Required variables:**
560558
```bash
561559
export GITHUB_ENTERPRISE="your-enterprise-slug"
562560

561+
# GitHub auth — use one of:
562+
export GITHUB_TOKEN=ghp_yourtoken # PAT with read:enterprise and manage_billing:enterprise scopes
563+
# OR: token is resolved automatically from an active gh auth session with the required scopes
564+
563565
# Optional: Entra ID UPN domain for users without a public GitHub email
564566
export UPN_DOMAIN="example.com" # e.g. 'john_example' → john@example.com
565567

@@ -571,9 +573,7 @@ export CREDITS_PER_SEAT_OVERRIDE="1900"
571573
```bash
572574
cd reporting/github-copilot-report
573575

574-
# Authenticate first
575-
gh auth refresh --scopes "read:enterprise,manage_billing:enterprise"
576-
az login # required to be installed; login needed only for department enrichment
576+
az login # optional; needed only for Entra ID department enrichment
577577

578578
./github-copilot-report.sh -e YOUR-ENTERPRISE
579579
./github-copilot-report.sh -e YOUR-ENTERPRISE -d example.com
@@ -599,10 +599,10 @@ az login # required to be installed; login needed only for department enrichme
599599
- Outputs a CSV and a formatted console summary with department breakdown and model usage tables
600600

601601
> [!IMPORTANT]
602-
> Requires an enterprise owner or billing manager token. Run `gh auth refresh --scopes "read:enterprise,manage_billing:enterprise"` before executing.
602+
> Requires a PAT with `read:enterprise` and `manage_billing:enterprise` scopes — the built-in `GITHUB_TOKEN` cannot grant enterprise-level access. Set `GITHUB_TOKEN` before executing (or have an active `gh` auth session with those scopes so the lib can auto-resolve the token).
603603
604604
> [!NOTE]
605-
> Uses the `gh` CLI and (optionally) the `az` CLI. The Entra ID enrichment is skipped automatically if `az` is not logged in, or can be disabled with `--no-entra`.
605+
> The Entra ID enrichment is skipped automatically if `az` is not logged in, or can be disabled with `--no-entra`.
606606
607607
---
608608

@@ -802,7 +802,7 @@ cd enterprise/github-get-public-repos
802802
Fetches all your starred repositories and organizes them into GitHub Lists using customizable categorization rules.
803803

804804
**Prerequisites:**
805-
- **[gh](https://cli.github.com)** - GitHub CLI (authenticated via `gh auth login`)
805+
- **[gh](https://cli.github.com)** - GitHub CLI (authenticated via `GITHUB_TOKEN` env var or `gh auth login`)
806806
- **[jq](https://stedolan.github.io/jq)** - Command-line JSON processor
807807

808808
**Usage:**
@@ -835,7 +835,7 @@ Edit the `RULES` array in the script. Each rule is a `|`-delimited string:
835835
The **first matching rule wins**, so order matters. Place more specific rules (e.g., AI) before general ones (e.g., Security).
836836

837837
> [!NOTE]
838-
> This script uses the `gh` CLI for all API calls (GraphQL) rather than `curl`. Ensure you are authenticated via `gh auth login` before running.
838+
> This script uses the `gh` CLI for all API calls (GraphQL) rather than `curl`. Authenticate by setting `GITHUB_TOKEN` or by running `gh auth login`.
839839
840840
## Shared Library: `lib/github-common.sh`
841841

@@ -921,6 +921,8 @@ Each script is published as a **composite action**, so you can reference it dire
921921
| `org-admin/github-migrate-internal-repos-to-private` | Convert all internal-visibility repositories to private |
922922
| `org-admin/github-repo-from-template` | Create a repository from a template with team permissions and a CI/CD collaborator |
923923
| `reporting/github-monthly-issues-report` | Generate an HTML report of issues created within a date range |
924+
| `reporting/github-repo-permissions-report` | Export repository collaborator/team permissions and branch-approval bypass actors to CSV |
925+
| `reporting/github-copilot-report` | GitHub Copilot Enterprise licence and AI credit usage report, optionally enriched with Entra ID department data |
924926

925927
---
926928

enterprise/github-add-enterprise-team-read-permissions/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: 'Grant read permissions to an enterprise team across all organizati
33
inputs:
44
github-token:
55
description: 'PAT with admin:enterprise scope'
6-
required: true
6+
required: false
77
enterprise:
88
description: 'GitHub Enterprise slug'
99
required: true
@@ -24,7 +24,7 @@ runs:
2424
- name: Add enterprise team read permissions
2525
shell: bash
2626
env:
27-
GITHUB_TOKEN: ${{ inputs.github-token }}
27+
GITHUB_TOKEN: ${{ inputs.github-token || github.token }}
2828
ENTERPRISE: ${{ inputs.enterprise }}
2929
ENTERPRISE_TEAM_SLUG: ${{ inputs.enterprise-team-slug }}
3030
ALL_REPO_READ_ROLE_NAME: ${{ inputs.all-repo-read-role-name }}

enterprise/github-dockerfile-discovery/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: 'Discover Dockerfiles and extract FROM instructions across all ente
33
inputs:
44
github-token:
55
description: 'PAT with read:org and repo scope'
6-
required: true
6+
required: false
77
enterprise:
88
description: 'GitHub Enterprise slug'
99
required: true
@@ -41,7 +41,7 @@ runs:
4141
- name: Discover Dockerfiles across enterprise
4242
shell: bash
4343
env:
44-
GITHUB_TOKEN: ${{ inputs.github-token }}
44+
GITHUB_TOKEN: ${{ inputs.github-token || github.token }}
4545
ENTERPRISE: ${{ inputs.enterprise }}
4646
REPORT_DIR: ${{ inputs.report-dir }}
4747
ORGS: ${{ inputs.orgs }}

enterprise/github-get-consumed-licenses/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: 'Report GitHub Enterprise consumed licence seat counts'
33
inputs:
44
github-token:
55
description: 'PAT with manage_billing:enterprise scope'
6-
required: true
6+
required: false
77
enterprise:
88
description: 'GitHub Enterprise slug'
99
required: true
@@ -17,7 +17,7 @@ runs:
1717
- name: Get consumed licenses
1818
shell: bash
1919
env:
20-
GITHUB_TOKEN: ${{ inputs.github-token }}
20+
GITHUB_TOKEN: ${{ inputs.github-token || github.token }}
2121
ENTERPRISE: ${{ inputs.enterprise }}
2222
API_URL_PREFIX: ${{ inputs.api-url-prefix }}
2323
run: ${{ github.action_path }}/github-get-consumed-licenses.sh

enterprise/github-get-public-repos/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: 'List all public repositories across all organizations in a GitHub
33
inputs:
44
github-token:
55
description: 'PAT with read:org and repo scope'
6-
required: true
6+
required: false
77
enterprise:
88
description: 'GitHub Enterprise slug'
99
required: true
@@ -33,7 +33,7 @@ runs:
3333
- name: Get public repositories
3434
shell: bash
3535
env:
36-
GITHUB_TOKEN: ${{ inputs.github-token }}
36+
GITHUB_TOKEN: ${{ inputs.github-token || github.token }}
3737
ENTERPRISE: ${{ inputs.enterprise }}
3838
REPORT_DIR: ${{ inputs.report-dir }}
3939
ORGS: ${{ inputs.orgs }}

lib/github-common.sh

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@
1414
# print_status / print_success / print_warning / print_error
1515
# require_env_var <VAR> [description] — exit if variable is unset/empty
1616
# require_command <cmd> — exit if command not found
17+
# configure_gh_auth [scope_hint] — bridge GITHUB_TOKEN→GH_TOKEN or verify gh session
1718
# validate_github_token [bearer] — verify token via /user endpoint
19+
#
20+
# Token auto-resolution (at source time):
21+
# If GITHUB_TOKEN is unset and gh CLI is available, the token is automatically
22+
# 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.
1824
# validate_token <VAR_NAME> — verify a secondary token variable
1925
# validate_slug <value> [label] — exit if value contains unsafe chars
2026
# gh_api <path|url> [curl args...] — Bearer-auth REST helper with retry
27+
# gh_api_paginate <path> [filter] [version] — paginated REST, follows Link headers
2128
# _paginate_orgs_endpoint <filter> <url_tpl> — page through an org list
2229
# _graphql_enterprise_orgs — GraphQL cursor-based enterprise orgs
2330
# get_enterprise_orgs — three-tier enterprise org resolver
@@ -68,6 +75,29 @@ require_command() {
6875
fi
6976
}
7077

78+
###
79+
## configure_gh_auth [scope_hint]
80+
## Bridges GITHUB_TOKEN into the gh CLI so scripts can accept either a token
81+
## or an active gh auth session interchangeably.
82+
##
83+
## When GITHUB_TOKEN is set: exports it as GH_TOKEN (gh CLI reads this env var).
84+
## When GITHUB_TOKEN is not set: verifies gh auth status and exits with an error
85+
## if no session is active. scope_hint is appended to the error message.
86+
##
87+
## Usage:
88+
## configure_gh_auth "gh auth login"
89+
## configure_gh_auth 'gh auth refresh --scopes "read:enterprise,manage_billing:enterprise"'
90+
###
91+
configure_gh_auth() {
92+
local scope_hint="${1:-gh auth login}"
93+
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
94+
export GH_TOKEN="$GITHUB_TOKEN"
95+
elif ! gh auth status >/dev/null 2>&1; then
96+
print_error "Not authenticated. Set GITHUB_TOKEN or run: ${scope_hint}"
97+
exit 1
98+
fi
99+
}
100+
71101
###
72102
## validate_token <TOKEN_VAR_NAME> [bearer]
73103
## Validates the token stored in the named variable by calling the /user endpoint.
@@ -174,6 +204,73 @@ gh_api() {
174204
return 1
175205
}
176206

207+
###
208+
## gh_api_paginate <path_or_url> [jq_filter] [api_version]
209+
## Paginated GitHub REST API helper using Link-header following.
210+
## Outputs each page's items (filtered by jq_filter) to stdout, one item per
211+
## line. Pipe the output to: jq -s '.' to get a JSON array of all items.
212+
## jq -s '. // []' to get [] when the endpoint 404s.
213+
## jq_filter defaults to .[] (one item per array element).
214+
## api_version defaults to 2022-11-28.
215+
## Returns 0 silently on 404/422 (empty output); returns 1 after 5 failed attempts.
216+
###
217+
gh_api_paginate() {
218+
local url="$1"
219+
local jq_filter="${2:-.[]}"
220+
local api_version="${3:-2022-11-28}"
221+
[[ "${url}" == http* ]] || url="${API_URL_PREFIX}${url}"
222+
223+
local _tmp_headers _tmp_body _http_code _attempt _next_url
224+
_tmp_headers=$(mktemp)
225+
_tmp_body=$(mktemp)
226+
227+
while [[ -n "${url}" ]]; do
228+
_http_code=""
229+
for _attempt in 1 2 3 4 5; do
230+
_http_code=$(curl -s \
231+
-D "${_tmp_headers}" \
232+
-o "${_tmp_body}" \
233+
-w "%{http_code}" \
234+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
235+
-H "Accept: application/vnd.github+json" \
236+
-H "X-GitHub-Api-Version: ${api_version}" \
237+
"${url}")
238+
case "${_http_code}" in
239+
200) break ;;
240+
404|422)
241+
rm -f "${_tmp_headers}" "${_tmp_body}"
242+
return 0
243+
;;
244+
403|429)
245+
print_warning "Rate limited (HTTP ${_http_code}). Sleeping 60s before retry ${_attempt}/5..."
246+
sleep 60
247+
;;
248+
*)
249+
print_warning "HTTP ${_http_code} for ${url} (attempt ${_attempt}/5)"
250+
sleep 5
251+
;;
252+
esac
253+
done
254+
255+
if [[ "${_http_code}" != "200" ]]; then
256+
rm -f "${_tmp_headers}" "${_tmp_body}"
257+
print_error "Failed to fetch ${url} after 5 attempts"
258+
return 1
259+
fi
260+
261+
jq -rc "${jq_filter}" "${_tmp_body}" 2>/dev/null || true
262+
263+
# Follow Link: <next-url>; rel="next" to the next page
264+
_next_url=$(grep -i "^link:" "${_tmp_headers}" \
265+
| grep -o '<[^>]*>; rel="next"' \
266+
| sed 's/<\([^>]*\)>.*/\1/' \
267+
|| true)
268+
url="${_next_url}"
269+
done
270+
271+
rm -f "${_tmp_headers}" "${_tmp_body}"
272+
}
273+
177274
###
178275
## _paginate_orgs_endpoint <jq_filter> <url_template>
179276
## Internal helper: pages through an org-list REST endpoint, printing one
@@ -293,3 +390,21 @@ get_enterprise_orgs() {
293390
'.[].login' \
294391
"/user/orgs?per_page=100&page=PAGE"
295392
}
393+
394+
###
395+
## Token auto-resolution (runs once at source time)
396+
## If GITHUB_TOKEN is not set, attempt to derive it from an active gh CLI
397+
## auth session. This allows scripts that use GITHUB_TOKEN with curl to work
398+
## with gh CLI auth as an alternative to an explicit token.
399+
## Scripts should still call require_env_var GITHUB_TOKEN or
400+
## validate_github_token to fail fast with a clear message if neither source
401+
## provides a token.
402+
###
403+
if [[ -z "${GITHUB_TOKEN:-}" ]] && command -v gh &>/dev/null; then
404+
_gh_resolved_token=$(gh auth token 2>/dev/null) || true
405+
if [[ -n "${_gh_resolved_token:-}" ]]; then
406+
GITHUB_TOKEN="$_gh_resolved_token"
407+
export GITHUB_TOKEN
408+
fi
409+
unset _gh_resolved_token
410+
fi

org-admin/github-add-repo-collaborators-by-pattern/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: 'Add individual collaborators to repositories whose names match a r
33
inputs:
44
github-token:
55
description: 'PAT with repo and admin:org scope'
6-
required: true
6+
required: false
77
org:
88
description: 'GitHub organization name'
99
required: true
@@ -31,7 +31,7 @@ runs:
3131
- name: Add collaborators to matching repositories
3232
shell: bash
3333
env:
34-
GITHUB_TOKEN: ${{ inputs.github-token }}
34+
GITHUB_TOKEN: ${{ inputs.github-token || github.token }}
3535
ORG: ${{ inputs.org }}
3636
COLLABORATORS: ${{ inputs.collaborators }}
3737
REPO_NAME_REGEX: ${{ inputs.repo-name-regex }}

0 commit comments

Comments
 (0)