⚡ [performance] Add cache revalidation to GitHub Year In Review API calls#360
⚡ [performance] Add cache revalidation to GitHub Year In Review API calls#360is0692vs wants to merge 1 commit into
Conversation
Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
📝 WalkthroughWalkthrough
Changesキャッシュ制御の一貫性
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Code Review
This pull request replaces cache: 'no-store' with a 24-hour Next.js revalidation cache (86400 seconds) for both GraphQL and REST API requests. The reviewer suggests dynamically adjusting the revalidation period: maintaining the 24-hour cache for past years, but reducing it to 5 minutes for the current year to ensure users see up-to-date contribution and heatmap data.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| headers: headers(token), | ||
| body: JSON.stringify({ query, variables }), | ||
| cache: "no-store", | ||
| next: { revalidate: 86400 }, |
There was a problem hiding this comment.
Caching all GraphQL responses for 24 hours (86400 seconds) is highly efficient for past years, but it causes a significant user experience issue for the current year, where users expect to see their active contributions and heatmaps update more frequently.
We can dynamically determine the revalidation period by checking the year requested in the query variables. If the requested year is in the past, we can cache it for 24 hours. If it is the current year, we should use a shorter revalidation window (e.g., 5 minutes) to keep the data fresh while still protecting against rate limits.
next: {
revalidate: (() => {
const dateStr = (variables.from || variables.since) as string | undefined;
const year = dateStr ? parseInt(dateStr.slice(0, 4), 10) : undefined;
return year && year < new Date().getUTCFullYear() ? 86400 : 300;
})()
},| url.searchParams.set("per_page", "100"); | ||
|
|
||
| const res = await fetch(url.toString(), { headers: headers(token), cache: "no-store" }); | ||
| const res = await fetch(url.toString(), { headers: headers(token), next: { revalidate: 86400 } }); |
There was a problem hiding this comment.
Similar to the GraphQL queries, caching the REST API response for the current year's commit activity for 24 hours will prevent users from seeing their latest commits on the heatmap.
Since the year is directly available in this function, we can dynamically set the revalidation time: 24 hours for past years, and 5 minutes for the current year.
| const res = await fetch(url.toString(), { headers: headers(token), next: { revalidate: 86400 } }); | |
| const res = await fetch(url.toString(), { | |
| headers: headers(token), | |
| next: { revalidate: year < new Date().getUTCFullYear() ? 86400 : 300 } | |
| }); |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib/githubYearInReview.ts (1)
92-117: 🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoffコード重複:
src/lib/github.tsのgraphql()関数との重複。このローカルの
graphql()関数はsrc/lib/github.tsの同名関数とほぼ同じロジックを持っていますが、revalidation時間が異なります(ここ: 86400s、upstream: 300s)。この divergence は year-in-review 特有のキャッシング要件のためと思われますが、将来的にメンテナンス上の問題を引き起こす可能性があります。♻️ 提案されるリファクタリング案
Option 1: upstream の
graphql()関数にrevalidateパラメータを追加:// In src/lib/github.ts export async function graphql<T>( query: string, token?: string, variables?: Record<string, unknown>, revalidate?: number ): Promise<T> { // ... existing code const res = await fetch(GITHUB_GRAPHQL, { method: "POST", headers: headers(token), body: JSON.stringify(body), next: { revalidate: revalidate ?? 300 }, }); // ... rest of code }その後、このファイルでは upstream 関数を import して使用:
import { graphql } from "`@/lib/github`"; // In fetchYearInReviewData: const response = await graphql<YearInReviewResponse>( YEAR_IN_REVIEW_QUERY, token, variables, 86400 // or conditional based on year );Option 2: このファイルの
graphql()をgraphqlYearInReview()のような固有名に変更し、目的を明確にする。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lib/githubYearInReview.ts` around lines 92 - 117, The local graphql() in src/lib/githubYearInReview.ts duplicates logic from src/lib/github.ts but uses a different revalidate value; update the upstream graphql in src/lib/github.ts to accept an optional revalidate parameter (e.g., revalidate?: number) and use it in the fetch next.revalidate option (defaulting to the current 300), then remove the local graphql() and import the shared graphql<T> into githubYearInReview and call it with revalidate = 86400 when fetching YearInReview data; alternatively, if you prefer file-local clarity, rename the local function to graphqlYearInReview() and delegate to the upstream graphql or wrap it to only override revalidate, but prefer the former shared-parameter approach for maintainability.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/githubYearInReview.ts`:
- Line 97: Both GraphQL and REST fetches use a fixed next: { revalidate: 86400 }
which fails to distinguish current year vs past years; update
fetchYearInReviewData and fetchCommitActivityHeatmap to compute whether the
requested year equals the current year (e.g., new Date().getFullYear()) and pass
a shorter revalidate value (e.g., 300) for the current year and 86400 for past
years into the fetch options (replace the hardcoded next: { revalidate: 86400 }
with conditional logic) so current-year data is refreshed frequently while older
years keep the 24h cache.
---
Outside diff comments:
In `@src/lib/githubYearInReview.ts`:
- Around line 92-117: The local graphql() in src/lib/githubYearInReview.ts
duplicates logic from src/lib/github.ts but uses a different revalidate value;
update the upstream graphql in src/lib/github.ts to accept an optional
revalidate parameter (e.g., revalidate?: number) and use it in the fetch
next.revalidate option (defaulting to the current 300), then remove the local
graphql() and import the shared graphql<T> into githubYearInReview and call it
with revalidate = 86400 when fetching YearInReview data; alternatively, if you
prefer file-local clarity, rename the local function to graphqlYearInReview()
and delegate to the upstream graphql or wrap it to only override revalidate, but
prefer the former shared-parameter approach for maintainability.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e78e9b1f-65e5-408c-a150-0f663396e3e9
📒 Files selected for processing (1)
src/lib/githubYearInReview.ts
| headers: headers(token), | ||
| body: JSON.stringify({ query, variables }), | ||
| cache: "no-store", | ||
| next: { revalidate: 86400 }, |
There was a problem hiding this comment.
現在年と過去年を区別しない24時間キャッシュの統一的な問題。
src/lib/githubYearInReview.ts の Line 97(GraphQL fetch)と Line 319(REST fetch)の両方で、24時間(86400秒)のキャッシュ再検証が一律適用されています。共通のroot causeは、両方の fetch 呼び出しにおいて、リクエストされた year が過去年か現在年(2026年)かを区別していない点です。
現在年のデータに対して24時間キャッシュを適用すると、ユーザーが今日行ったコントリビューションが最大24時間反映されず、UX が著しく損なわれます。過去年については24時間キャッシュは適切ですが、現在年については短い revalidation 時間(例: 300秒)を使用すべきです。
修正案としては、fetchYearInReviewData および fetchCommitActivityHeatmap 内で年度チェックを追加し、現在年の場合は両方の fetch に異なる revalidation 時間を渡すようにする必要があります。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/lib/githubYearInReview.ts` at line 97, Both GraphQL and REST fetches use
a fixed next: { revalidate: 86400 } which fails to distinguish current year vs
past years; update fetchYearInReviewData and fetchCommitActivityHeatmap to
compute whether the requested year equals the current year (e.g., new
Date().getFullYear()) and pass a shorter revalidate value (e.g., 300) for the
current year and 86400 for past years into the fetch options (replace the
hardcoded next: { revalidate: 86400 } with conditional logic) so current-year
data is refreshed frequently while older years keep the 24h cache.
💡 What: Replaced
cache: "no-store"withnext: { revalidate: 86400 }in the GraphQL and RESTfetchcalls withinsrc/lib/githubYearInReview.ts.🎯 Why: Historical GitHub activity data for previous years does not change frequently. Fetching this data on every request caused unnecessary I/O latency and consumed API rate limits. Applying a 24-hour cache (86400 seconds) drastically improves response times for repeated requests without sacrificing meaningful freshness.
📊 Measured Improvement: Reusing cached responses via Next.js Data Cache prevents redundant network requests to the GitHub API, reducing overall response latency and avoiding rate limit exhaustion on popular profiles.
PR created automatically by Jules for task 9916394064566109213 started by @is0692vs
Greptile Summary
GraphQLおよびREST fetchの
cache: "no-store"をnext: { revalidate: 86400 }に置き換え、GitHubの年次レビューAPIレスポンスを24時間キャッシュするパフォーマンス改善PRです。過去年のデータへの繰り返しリクエストを削減しレート制限の消費を抑える意図は妥当ですが、実装に2点の問題があります。yearが現在年の場合でも同じTTLが適用されるため、当日のコントリビューションが反映されない。Authorizationヘッダーをキャッシュキーに含めない場合、異なるユーザーのプライベートコントリビューション情報が混在するリスクがある。Confidence Score: 3/5
現在年のリクエストで最大24時間古いコントリビューションデータを返すことと、ユーザー固有トークンのキャッシュ分離が未検証であることから、このままマージするのは推奨しません。
現在年に対して24時間キャッシュが無条件に適用されるため、本日行ったコントリビューションが反映されない状態が続く。加えてGitHub GraphQL APIはトークンによって返すデータが異なるにもかかわらず、POSTリクエストのキャッシュキーにAuthorizationヘッダーが含まれる保証がなく、ユーザー間のデータ混在リスクが排除できていない。
src/lib/githubYearInReview.ts — キャッシュTTLと年判定ロジック、およびキャッシュキーのユーザー分離を確認する必要がある。
Security Review
src/lib/githubYearInReview.ts): GitHub GraphQL APIはトークンスコープに基づいてプライベートリポジトリへのアクセスを返す。POSTリクエストのキャッシュキーにAuthorizationヘッダーが確実に含まれない場合、ユーザーAのプライベートコントリビューション情報が同じusername/yearをリクエストする別ユーザーBに返される可能性がある。Important Files Changed
cache: "no-store"をnext: { revalidate: 86400 }に置換。現在年のデータが24時間古くなる問題と、Authorizationヘッダーがキャッシュキーに含まれない場合の潜在的なユーザー間データ漏洩リスクがある。Comments Outside Diff (2)
src/lib/githubYearInReview.ts, line 92-98 (link)yearパラメータが現在の年と一致する場合(例:2025年のリクエスト)、24時間のキャッシュが適用されるため、その日に行われたコントリビューションが最大24時間反映されません。PR説明には「過去年のデータは頻繁に変更されない」と記載されていますが、実装では現在年と過去年の区別が行われていません。Prompt To Fix With AI
src/lib/githubYearInReview.ts, line 92-98 (link)GitHub GraphQL APIは
Authorizationヘッダーによって返すデータが異なります。Next.jsのData CacheがPOSTリクエストのキャッシュキーにAuthorizationヘッダーを確実に含めない場合、ユーザーAのプライベートコントリビューション情報が別ユーザーBに返されるリスクがあります。Prompt To Fix With AI
Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "perf: Add 24-hour cache revalidation to ..." | Re-trigger Greptile