Skip to content

fix: support github token for plugin release checks#6886

Open
1zzxy1 wants to merge 2 commits intoAstrBotDevs:masterfrom
1zzxy1:fix/github-api-rate-limit
Open

fix: support github token for plugin release checks#6886
1zzxy1 wants to merge 2 commits intoAstrBotDevs:masterfrom
1zzxy1:fix/github-api-rate-limit

Conversation

@1zzxy1
Copy link
Contributor

@1zzxy1 1zzxy1 commented Mar 24, 2026

Summary

  • add github_token config and dashboard metadata so the setting is configurable
  • forward github_token into PluginUpdator and only attach auth headers for api.github.com requests
  • add focused tests for token forwarding and GitHub-only request headers

Closes #6870

Testing

  • uv run --group dev pytest tests/test_plugin_manager.py -k github_token tests/test_zip_updator.py -q

Summary by Sourcery

Add configurable GitHub token support for plugin release checks and ensure it is correctly propagated and used only for GitHub API requests.

New Features:

  • Introduce a github_token configuration option and expose it in the dashboard config metadata for plugin release checks.

Enhancements:

  • Pass the github_token from PluginManager into PluginUpdator and RepoZipUpdator so GitHub Releases API calls can be authenticated.
  • Limit GitHub token-based Authorization headers to api.github.com requests to avoid sending credentials to non-GitHub mirrors.

Documentation:

  • Update dashboard i18n config metadata to document the optional GitHub token setting and its purpose.

Tests:

  • Add tests to verify PluginManager forwards the github_token into the plugin updater.
  • Add async tests to verify repo release fetching sends Authorization headers only to api.github.com and not to mirror URLs.

@auto-assign auto-assign bot requested review from LIghtJUNction and anka-afk March 24, 2026 07:09
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Mar 24, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the plugin release check mechanism by introducing support for a configurable GitHub token. This allows the application to make authenticated requests to the GitHub API, thereby mitigating issues related to rate limiting that unauthenticated requests might encounter. The change integrates the token into the configuration, passes it through the update process, and ensures it's used securely and selectively for GitHub-specific API calls.

Highlights

  • GitHub Token Configuration: Introduced a github_token configuration option, allowing users to provide a personal access token for GitHub API requests.
  • Token Forwarding: Implemented logic to forward the github_token from the main configuration through the PluginManager to the PluginUpdator.
  • Conditional Authentication: Modified the RepoZipUpdator to conditionally attach the Authorization header with the provided github_token only for requests made to api.github.com.
  • New Tests: Added new unit tests to verify the correct forwarding of the github_token and the conditional application of authentication headers.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@dosubot dosubot bot added the feature:updater The bug / feature is about astrbot updater system label Mar 24, 2026
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In RepoZipUpdator._build_request_headers, consider returning None instead of an empty dict when no auth header is needed so that callers can avoid passing headers={} to aiohttp.ClientSession, which overwrites default headers unnecessarily.
  • The new github_token configuration is only read from the top-level config in PluginManager; if other consumers of RepoZipUpdator or plugin-related code should also respect this token, it may be worth centralizing how the token is retrieved (e.g., via a helper) to avoid divergence between call sites.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `RepoZipUpdator._build_request_headers`, consider returning `None` instead of an empty dict when no auth header is needed so that callers can avoid passing `headers={}` to `aiohttp.ClientSession`, which overwrites default headers unnecessarily.
- The new `github_token` configuration is only read from the top-level config in `PluginManager`; if other consumers of `RepoZipUpdator` or plugin-related code should also respect this token, it may be worth centralizing how the token is retrieved (e.g., via a helper) to avoid divergence between call sites.

## Individual Comments

### Comment 1
<location path="tests/test_plugin_manager.py" line_range="81-90" />
<code_context>
     return mock_reload


+def test_plugin_manager_passes_github_token_to_updator(monkeypatch):
+    captured = {}
+
+    class DummyUpdator:
+        def __init__(self, repo_mirror: str = "", github_token: str = ""):
+            captured["repo_mirror"] = repo_mirror
+            captured["github_token"] = github_token
+
+    class MockContext:
+        def get_all_stars(self):
+            return []
+
+    monkeypatch.setattr("astrbot.core.star.star_manager.PluginUpdator", DummyUpdator)
+    monkeypatch.setattr(
+        "astrbot.core.star.star_tools.StarTools.initialize",
+        lambda context: None,
+    )
+
+    pm = PluginManager(
+        cast(Any, MockContext()),
+        cast(Any, {"github_token": "ghp_test"}),
+    )
+
+    assert isinstance(pm.updator, DummyUpdator)
+    assert captured == {"repo_mirror": "", "github_token": "ghp_test"}
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add a complementary test for the case where `github_token` is not present or empty in the config.

Please also add a test where `github_token` is missing from the config or set to an empty string. That test should confirm that `PluginUpdator` is still constructed and that `github_token` is passed as an empty value, documenting the behavior when no token is provided and guarding against future regressions in `PluginManager` config handling.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +81 to +90
def test_plugin_manager_passes_github_token_to_updator(monkeypatch):
captured = {}

class DummyUpdator:
def __init__(self, repo_mirror: str = "", github_token: str = ""):
captured["repo_mirror"] = repo_mirror
captured["github_token"] = github_token

class MockContext:
def get_all_stars(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a complementary test for the case where github_token is not present or empty in the config.

Please also add a test where github_token is missing from the config or set to an empty string. That test should confirm that PluginUpdator is still constructed and that github_token is passed as an empty value, documenting the behavior when no token is provided and guarding against future regressions in PluginManager config handling.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively adds support for a GitHub token to authenticate API requests for plugin release checks, which is a great way to avoid rate-limiting issues. The implementation correctly restricts token usage to api.github.com requests and includes solid testing to verify the new functionality. I have a couple of suggestions to further improve the changes.

headers: dict[str, str] = {}
parsed_url = urlparse(url)
if self.github_token and parsed_url.netloc == "api.github.com":
headers["Authorization"] = f"token {self.github_token}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While using token {self.github_token} for the Authorization header is valid, GitHub's documentation recommends using the Bearer scheme for authenticating with personal access tokens. It's a more modern and standard approach.

Suggested change
headers["Authorization"] = f"token {self.github_token}"
headers["Authorization"] = f"Bearer {self.github_token}"

},
"github_token": {
"description": "GitHub Token",
"hint": "Optional. Used for GitHub Releases API requests to avoid unauthenticated rate limit exceeded errors. A read-only token is recommended."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The hint for github_token is in English. For consistency within this localization file, it should be translated into Russian.

Suggested change
"hint": "Optional. Used for GitHub Releases API requests to avoid unauthenticated rate limit exceeded errors. A read-only token is recommended."
"hint": "Необязательно. Используется для запросов к GitHub Releases API, чтобы избежать превышения лимита неаутентифицированных запросов. Рекомендуется использовать токен только для чтения."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature:updater The bug / feature is about astrbot updater system size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 当应用内部访问多次 github api 时会提示 API rate limit exceeded

1 participant