Skip to content

feat: support repo issue and pull count#149

Open
bluwy wants to merge 2 commits into
unjs:mainfrom
bluwy:issue-pull-count
Open

feat: support repo issue and pull count#149
bluwy wants to merge 2 commits into
unjs:mainfrom
bluwy:issue-pull-count

Conversation

@bluwy

@bluwy bluwy commented Mar 4, 2026

Copy link
Copy Markdown
Collaborator

closes #148

New endpoints:

  • /repos/[owner]/[repo]/issue-count => { count: number }
  • /repos/[owner]/[repo]/pull-count => { count: number }

Updated endpoints:

  • /repos/[owner]/[repo] returns new issueAndPullCount field (combined open issues and PRs count returned by github)

Thoughts needed

In #148 I mentioned using the Link header trick to retrieve the issue and pr count quickly, but it only works if the repo has more than 1 issues or prs for the header to appear (for pagination). So I went with the github search approach, however that has a stricter rate limit: 1800/hour instead of 5000/hour, however this is a separate rate limit bucket to the core apis.

Alternatively, we can use the graphql api to fetch the issue and pr count, which i calculate has a lower cost (and better rate limit) altogether (1 point per query), but at that point, maybe /repos/[owner]/[repo] should just use the graphql api and fetch everything in one go?

Any thoughts on how we should go from here? Or is the current implementation good enough?

Example graphql query test
curl -H "Authorization: Bearer YOUR_GITHUB_TOKEN" \
  -H "Content-Type: application/json" \
  -X POST https://api.github.com/graphql \
  -d '{
    "query": "query RepoInfo($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { id name nameWithOwner description createdAt updatedAt pushedAt stargazerCount watchers { totalCount } forkCount issues(states: OPEN) { totalCount } pullRequests(states: OPEN) { totalCount } defaultBranchRef { name } } rateLimit { cost remaining resetAt } }",
    "variables": {
      "owner": "unjs",
      "name": "ofetch"
    }
  }'

Summary by CodeRabbit

  • New Features
    • Repository info now includes an aggregated open issue + pull request count.
    • New endpoint to fetch the open issue count for a repository.
    • New endpoint to fetch the open pull request count for a repository.

@vercel

vercel Bot commented Mar 4, 2026

Copy link
Copy Markdown

@bluwy is attempting to deploy a commit to the Nitro Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Mar 4, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 12076273-37b0-4b21-bd90-8cc54777935e

📥 Commits

Reviewing files that changed from the base of the PR and between 0cfd8a8 and cdde6b9.

📒 Files selected for processing (2)
  • routes/orgs/[owner]/repos.ts
  • routes/users/[name]/repos.ts

📝 Walkthrough

Walkthrough

The PR adds aggregated issue+PR counts to repository listings and the single-repo endpoint, and introduces two new routes to fetch open issue and open PR counts by querying GitHub's search API.

Changes

Cohort / File(s) Summary
Single-repo & types
routes/repos/[owner]/[repo]/index.ts, types/index.ts
Added issueAndPullCount to the repository response and to the GithubRepo type, populated from rawRepo.open_issues_count.
User/Org repo listings
routes/users/[name]/repos.ts, routes/orgs/[owner]/repos.ts
Mapped repositories now include issueAndPullCount (sourced from rawRepo.open_issues_count) in each returned GithubRepo.
New count endpoints
routes/repos/[owner]/[repo]/issue-count.ts, routes/repos/[owner]/[repo]/pull-count.ts
Added two handlers exposing { count: number } endpoints; each calls GitHub's search/issues API (or search for PRs) with per_page=1 and returns total_count as count.
Manifest
package.json
Small package manifest updates (few-line changes).

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Server as API Server (route handler)
    participant GitHub as GitHub Search API
    Client->>Server: GET /repos/{owner}/{repo}/issue-count
    Server->>GitHub: GET /search/issues?q=repo:owner/repo+state:open&per_page=1
    GitHub-->>Server: { total_count: N, ... }
    Server-->>Client: { count: N }
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped to the repo, counted stars and delight,
I fetched all the issues and PRs in sight,
Two new little routes and a field in the view,
Now counts come together — a carrot for you! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: support repo issue and pull count' clearly and concisely describes the main change: adding support for repository issue and pull request counts.
Linked Issues check ✅ Passed The PR implements the requirements from #148 by adding separate endpoints for issue/PR counts and including issueAndPullCount in the main repo endpoint, fulfilling the feature request.
Out of Scope Changes check ✅ Passed All changes are directly scoped to addressing #148: new issue-count and pull-count endpoints, issueAndPullCount field addition to repo objects across multiple routes, and type updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
routes/repos/[owner]/[repo]/issue-count.ts (1)

22-24: Consider short-TTL caching for this endpoint.

This route spends Search API quota on every request. A small per-repo cache (e.g., 30–120s) would reduce throttling risk during traffic bursts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@routes/repos/`[owner]/[repo]/issue-count.ts around lines 22 - 24, This route
calls ghFetch for every request and should use a short per-repo TTL cache to
avoid burning Search API quota; wrap the ghFetch call in a small in-memory cache
(e.g., Map or LRU) keyed by
`${event.context.params.owner}/${event.context.params.repo}`, store the fetched
result (or the pending Promise) and a timestamp, return cached value when age <
TTL (30–120s, e.g., 60s), and on cache-miss perform ghFetch and update the
cache; update the code around the ghFetch call and the variable res to
read/write the cache and consider storing the Promise to dedupe concurrent
requests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@types/index.ts`:
- Line 12: The GithubRepo type now requires issueAndPullCount but the producer
in routes/users/[name]/repos.ts still returns repos without it; update the
repo-building logic (the function constructing GithubRepo objects in that file)
to include an issueAndPullCount property for every returned object (compute it
from available issue/pr data if present, or set a sensible default like 0) so
the returned shape matches the GithubRepo interface and prevents runtime or type
errors.

---

Nitpick comments:
In `@routes/repos/`[owner]/[repo]/issue-count.ts:
- Around line 22-24: This route calls ghFetch for every request and should use a
short per-repo TTL cache to avoid burning Search API quota; wrap the ghFetch
call in a small in-memory cache (e.g., Map or LRU) keyed by
`${event.context.params.owner}/${event.context.params.repo}`, store the fetched
result (or the pending Promise) and a timestamp, return cached value when age <
TTL (30–120s, e.g., 60s), and on cache-miss perform ghFetch and update the
cache; update the code around the ghFetch call and the variable res to
read/write the cache and consider storing the Promise to dedupe concurrent
requests.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1ba5e562-b114-485c-b9a5-599597ea6ad8

📥 Commits

Reviewing files that changed from the base of the PR and between 65de076 and 0cfd8a8.

📒 Files selected for processing (4)
  • routes/repos/[owner]/[repo]/index.ts
  • routes/repos/[owner]/[repo]/issue-count.ts
  • routes/repos/[owner]/[repo]/pull-count.ts
  • types/index.ts

Comment thread types/index.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Return issue and pr count in /repos/{owner}/{repo}​

1 participant