feat: solve github rate limit issue by using git ls-remote as a fallb… - #66
Conversation
…ack when the GitHub API rate limit is hit.
c80ce8c to
3b0dbfc
Compare
There was a problem hiding this comment.
Pull request overview
This PR improves resilience of the feature installer’s GitHub tag discovery by adding rate-limit detection and a fallback path that fetches tags via git ls-remote when the GitHub API rate limit is hit, and adds unit tests/CI coverage for the installer package. It also updates multiple feature manifests/READMEs to version 1.1.0 and adds some developer/debugging and troubleshooting documentation.
Changes:
- Add GitHub API rate-limit handling with optional
git ls-remotetag-fetch fallback (installer/github.go). - Add unit tests (and a CI job) covering GitHub tag fetching and override env cleanup (
installer/*_test.go,.github/workflows/ci.yml). - Bump multiple features from
1.0.xto1.1.0in feature metadata and READMEs; add troubleshooting guidance to the root README.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds devcontainer/docker bind-mount troubleshooting guidance and docker cp fallback example. |
| installer/overrides_test.go | Ensures env vars are unset after tests to prevent cross-test contamination. |
| installer/github.go | Adds rate-limit detection and git ls-remote fallback for tag enumeration. |
| installer/github_test.go | Adds unit tests for GitHub API token behavior, rate-limit error typing, and git ls-remote parsing. |
| features/src/sonar-scanner-cli/README.md | Updates example image tag to 1.1.0. |
| features/src/sonar-scanner-cli/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/rust/README.md | Updates example image tag to 1.1.0. |
| features/src/rust/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/python/README.md | Updates example image tag to 1.1.0. |
| features/src/python/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/opencode/README.md | Updates example image tag to 1.1.0. |
| features/src/opencode/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/kubectl/README.md | Updates example image tag to 1.1.0. |
| features/src/kubectl/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/goreleaser/README.md | Updates example image tag to 1.1.0. |
| features/src/goreleaser/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/gonovate/README.md | Updates example image tag to 1.1.0. |
| features/src/gonovate/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/github-copilot-cli/README.md | Updates example image tag to 1.1.0. |
| features/src/github-copilot-cli/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/github-cli/README.md | Updates example image tag to 1.1.0. |
| features/src/github-cli/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/git-lfs/README.md | Updates example image tag to 1.1.0. |
| features/src/git-lfs/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/docker-out/README.md | Updates example image tag to 1.1.0. |
| features/src/docker-out/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/claude-code/README.md | Updates example image tag to 1.1.0. |
| features/src/claude-code/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| features/src/apm/README.md | Updates example image tag to 1.1.0. |
| features/src/apm/devcontainer-feature.json | Bumps feature version to 1.1.0. |
| .vscode/launch.json | Adds Go debug launch configurations for the kubectl feature installer. |
| .github/workflows/ci.yml | Adds a unit-test job to run Go tests for the installer package in CI. |
Comments suppressed due to low confidence (1)
installer/github.go:147
- This error message says "download file", but this code path is fetching tag metadata. Using "fetch tags" here makes the error clearer and more searchable for users.
return nil, &GitHubRateLimitError{
Message: fmt.Sprintf("failed to download file '%s'. Status code: %d. You may have reached the GitHub API rate limit. Consider setting the DEV_FEATURE_TOKEN_GITHUB_API environment variable with a personal access token to increase the limit.", url, resp.StatusCode),
UseFallback: false,
}
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 32 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
installer/github.go:80
- Inside the pagination loop, the response body is closed via
defer, which accumulates defers across pages and can keep connections/file descriptors open longer than necessary. Also, the Authorization header currently uses a format string without%s, so the token value is never sent (requests remain effectively unauthenticated).
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return g.handleRateLimitError(resp, url, apiToken)
}
installer/github.go:162
- When hitting the API rate limit without a token,
UseFallbackis set to false, soGetTagswill not attempt thegit ls-remotefallback. That seems to contradict the PR goal of using git as a fallback when the GitHub API rate limit is hit (the unauthenticated rate limit is the most likely to be hit).
if !hasToken {
return nil, &GitHubRateLimitError{
Message: fmt.Sprintf(
"failed to download file '%s'. Status code: %d. You may have reached the GitHub API rate limit. Consider setting the DEV_FEATURE_TOKEN_GITHUB_API environment variable with a personal access token to increase the limit.",
url, resp.StatusCode,
installer/github_test.go:126
- If the intent is to attempt
git ls-remotewhen the GitHub API rate limit is hit (even without a token), this test should be updated to expectUseFallbackto be true and to assert the fallback message.
…ack when the GitHub API rate limit is hit.