mirror of
https://github.com/github/spec-kit.git
synced 2026-07-03 12:28:06 +08:00
feat(extensions,presets): authenticate GitHub-hosted catalog and download requests with GITHUB_TOKEN/GH_TOKEN (#2331)
* feat(extensions,presets): authenticate GitHub-hosted catalog and download requests with GITHUB_TOKEN/GH_TOKEN Squashed from #2087 (original author: @anasseth). Adds GitHub-token authentication to extension and preset catalog fetching and ZIP downloads so private GitHub repos work when GITHUB_TOKEN/GH_TOKEN is set, while preventing credential leakage to non-GitHub hosts. - Introduces shared _github_http module with build_github_request() and open_github_url() helpers - Routes ExtensionCatalog and PresetCatalog network calls through GitHub-auth-aware opener - Adds comprehensive unit/integration tests for auth header behavior - Updates user docs for both extensions and presets Co-authored-by: anasseth <16745089+anasseth@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(auth): address review feedback from #2087 - Fix redirect handler to preserve Authorization on GitHub-to-GitHub redirects (e.g. github.com → codeload.github.com). The previous implementation relied on super().redirect_request() which strips auth on cross-host redirects, breaking private repo archive downloads. - Add codeload.github.com to documented host lists in both EXTENSION-USER-GUIDE.md and presets/README.md - Add redirect auth-preservation and auth-stripping tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(auth): use Bearer scheme instead of token for consistency Aligns with the rest of the codebase (e.g. __init__.py:1721) and GitHub's current API guidance. Updates all test assertions accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: address second round of Copilot review feedback - Fix docstring to say Bearer instead of token (matches implementation) - Remove unused imports/fixtures from redirect tests (GITHUB_HOSTS, MagicMock, temp_dir, monkeypatch) - Replace __import__('io').BytesIO() with normal import io pattern in test_presets.py Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: anasseth <16745089+anasseth@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -423,7 +423,7 @@ In addition to extension-specific environment variables (`SPECKIT_{EXT_ID}_*`),
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `SPECKIT_CATALOG_URL` | Override the full catalog stack with a single URL (backward compat) | Built-in default stack |
|
||||
| `GH_TOKEN` / `GITHUB_TOKEN` | GitHub API token for downloads | None |
|
||||
| `GH_TOKEN` / `GITHUB_TOKEN` | GitHub token for authenticated requests to GitHub-hosted URLs (`raw.githubusercontent.com`, `github.com`, `api.github.com`, `codeload.github.com`). Required when your catalog JSON or extension ZIPs are hosted in a private GitHub repository. | None |
|
||||
|
||||
#### Example: Using a custom catalog for testing
|
||||
|
||||
@@ -435,6 +435,21 @@ export SPECKIT_CATALOG_URL="http://localhost:8000/catalog.json"
|
||||
export SPECKIT_CATALOG_URL="https://example.com/staging/catalog.json"
|
||||
```
|
||||
|
||||
#### Example: Using a private GitHub-hosted catalog
|
||||
|
||||
```bash
|
||||
# Authenticate with a token (gh CLI, PAT, or GITHUB_TOKEN in CI)
|
||||
export GITHUB_TOKEN=$(gh auth token)
|
||||
|
||||
# Search a private catalog added via `specify extension catalog add`
|
||||
specify extension search jira
|
||||
|
||||
# Install from a private catalog
|
||||
specify extension add jira-sync
|
||||
```
|
||||
|
||||
The token is attached automatically to requests targeting GitHub domains. Non-GitHub catalog URLs are always fetched without credentials.
|
||||
|
||||
---
|
||||
|
||||
## Extension Catalogs
|
||||
|
||||
Reference in New Issue
Block a user