diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 004ed84..4743154 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,8 @@ jobs: python-version: ${{ matrix.python-version }} - run: pip install -e ".[dev]" - run: pytest -v + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} docker-test: runs-on: ubuntu-latest diff --git a/src/skills.py b/src/skills.py index f51b5f7..4a3b9fb 100644 --- a/src/skills.py +++ b/src/skills.py @@ -68,6 +68,14 @@ def save_skill_file(skill_name: str, raw_content: str) -> Path: # --------------------------------------------------------------------------- +def _github_headers() -> dict: + """Return auth headers if GITHUB_TOKEN is set, else empty dict.""" + import os + + token = os.environ.get("GITHUB_TOKEN") + return {"Authorization": f"Bearer {token}"} if token else {} + + def list_skills_in_repo(repo: str, branch: str = DEFAULT_BRANCH) -> List[str]: """Return names of all skills available in a GitHub repo. @@ -76,7 +84,7 @@ def list_skills_in_repo(repo: str, branch: str = DEFAULT_BRANCH) -> List[str]: """ url = _GITHUB_TREE_API.format(repo=repo, branch=branch) try: - resp = httpx.get(url, follow_redirects=True, timeout=15) + resp = httpx.get(url, follow_redirects=False, timeout=15, headers=_github_headers()) if resp.status_code != 200: return [] tree = resp.json().get("tree", []) @@ -104,7 +112,7 @@ def fetch_skill_from_repo( """ url = _GITHUB_RAW.format(repo=repo, branch=branch, skill=skill_name) try: - resp = httpx.get(url, follow_redirects=True, timeout=15) + resp = httpx.get(url, follow_redirects=False, timeout=15, headers=_github_headers()) if resp.status_code != 200: return None except httpx.HTTPError: diff --git a/tests/test_docker_integration.py b/tests/test_docker_integration.py index a379b79..28e220b 100644 --- a/tests/test_docker_integration.py +++ b/tests/test_docker_integration.py @@ -1090,15 +1090,14 @@ def test_install_all_then_sync_dry_run(self, runner, cli, tmp_path, monkeypatch) (tmp_path / ".cursor").mkdir() (tmp_path / ".cursor" / "mcp.json").write_text("{}") - r_install = runner.invoke( - cli, ["install", self.TEST_REPO, "--all", "-t", "cursor", "-y"] - ) + r_install = runner.invoke(cli, ["install", self.TEST_REPO, "--all", "-t", "cursor", "-y"]) assert r_install.exit_code == 0, r_install.output skills_dir = tmp_path / ".apc" / "skills" installed_count = len(list(skills_dir.iterdir())) if skills_dir.exists() else 0 assert installed_count > 5, ( - f"Expected >5 skills installed, got {installed_count}. Install output:\n{r_install.output}" + f"Expected >5 skills installed, got {installed_count}.\n" + f"Install output:\n{r_install.output}" ) r_sync = runner.invoke(cli, ["sync", "--tools", "cursor", "--dry-run"])