mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
The www build saves failed GitHub star requests as zero, which the navigation displays as `0K`. This passes `GITHUB_TOKEN` through Turbo's build environment and preserves a valid previously generated count when a request fails. If there is no valid previous count, the navigation displays “GitHub” and the homepage contribution graphic omits the number. Cached fallback is available only when the previous generated content exists; rate limiting is a possible cause of the original failure, but has not been confirmed from deployment logs. ## To test - Run `pnpm --filter www exec vitest run scripts/lib/githubStars.test.ts` — all 16 tests pass, covering authenticated and anonymous requests, rate limiting, malformed responses, and missing or invalid cached content. - Build with a valid `GITHUB_TOKEN` and check that the navigation and homepage graphic show the star count. - Simulate a failed GitHub request with and without existing generated content. Confirm that a valid previous count is retained, or that no zero count appears when none is available. Verified locally: live GitHub fetch through the new loader, Turbo dry run with strict environment filtering and `GITHUB_TOKEN` allowed, Prettier, and ESLint (one existing default-export warning). Full build and browser checks have not been run. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - GitHub star counts are now displayed only when valid; otherwise, the interface shows a clear fallback label. - Star counts can fall back to cached data when GitHub is unavailable or returns invalid results. - Builds without GitHub data now complete gracefully instead of failing. - **Tests** - Added coverage for authenticated and unauthenticated requests, cached fallbacks, invalid responses, and clean builds. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import { getGitHubStars } from './githubStars.mjs'
|
|
|
|
const { request, readFile, Octokit } = vi.hoisted(() => ({
|
|
request: vi.fn(),
|
|
readFile: vi.fn(),
|
|
Octokit: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@octokit/core', () => ({ Octokit }))
|
|
vi.mock('node:fs/promises', () => ({ readFile }))
|
|
|
|
const cachePath = '/staticContent/_index.json'
|
|
|
|
describe('getGitHubStars', () => {
|
|
beforeEach(() => {
|
|
vi.resetAllMocks()
|
|
vi.stubEnv('GITHUB_TOKEN', '')
|
|
Octokit.mockImplementation(function () {
|
|
return { request }
|
|
})
|
|
vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
readFile.mockRejectedValue(new Error('ENOENT'))
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks()
|
|
vi.unstubAllEnvs()
|
|
})
|
|
|
|
it('uses the live count and authenticates when a token is available', async () => {
|
|
vi.stubEnv('GITHUB_TOKEN', 'test-token')
|
|
request.mockResolvedValue({ data: { stargazers_count: 110565 } })
|
|
|
|
expect(await getGitHubStars(cachePath)).toBe(110565)
|
|
expect(Octokit).toHaveBeenCalledWith({ auth: 'test-token' })
|
|
expect(readFile).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('can fetch public stars without a token', async () => {
|
|
request.mockResolvedValue({ data: { stargazers_count: 110565 } })
|
|
|
|
expect(await getGitHubStars(cachePath)).toBe(110565)
|
|
expect(Octokit).toHaveBeenCalledWith({})
|
|
})
|
|
|
|
it('keeps the previous count when GitHub rate limits the build', async () => {
|
|
request.mockRejectedValue(Object.assign(new Error('API rate limit exceeded'), { status: 403 }))
|
|
readFile.mockResolvedValue(JSON.stringify({ githubStars: 109037 }))
|
|
|
|
expect(await getGitHubStars(cachePath)).toBe(109037)
|
|
expect(readFile).toHaveBeenCalledWith(cachePath, 'utf8')
|
|
})
|
|
|
|
it.each([undefined, null, 0, -1, '110565', NaN, Infinity, 1.5])(
|
|
'falls back to the previous count for invalid API data: %s',
|
|
async (stargazers_count) => {
|
|
request.mockResolvedValue({ data: { stargazers_count } })
|
|
readFile.mockResolvedValue(JSON.stringify({ githubStars: 109037 }))
|
|
|
|
expect(await getGitHubStars(cachePath)).toBe(109037)
|
|
}
|
|
)
|
|
|
|
it('returns unknown when the request fails on a clean build', async () => {
|
|
request.mockRejectedValue(new Error('Network error'))
|
|
|
|
expect(await getGitHubStars(cachePath)).toBeNull()
|
|
})
|
|
|
|
it.each(['invalid json', '{}', '{"githubStars":0}', '{"githubStars":null}'])(
|
|
'does not reuse invalid cached content: %s',
|
|
async (content) => {
|
|
request.mockRejectedValue(new Error('Network error'))
|
|
readFile.mockResolvedValue(content)
|
|
|
|
expect(await getGitHubStars(cachePath)).toBeNull()
|
|
}
|
|
)
|
|
})
|