Skip to content

Commit 7c7f92e

Browse files
JhaSourav07kali
andauthored
fix(api): fail fast when GitHub token is missing (JhaSourav07#855)
Co-authored-by: kali <kali@kali.kali>
2 parents 38c6ea4 + 922edd3 commit 7c7f92e

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

lib/github.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ const mockCalendar: ContributionCalendar = {
2727
],
2828
};
2929

30+
const originalGitHubPat = process.env.GITHUB_PAT;
31+
const originalGitHubToken = process.env.GITHUB_TOKEN;
32+
3033
function mockResponse(body: unknown, status = 200): Response {
3134
return new Response(JSON.stringify(body), {
3235
status,
@@ -36,10 +39,23 @@ function mockResponse(body: unknown, status = 200): Response {
3639

3740
beforeEach(() => {
3841
clearGitHubApiCacheForTests();
42+
process.env.GITHUB_PAT = 'test-token';
43+
delete process.env.GITHUB_TOKEN;
3944
});
4045

4146
afterEach(() => {
4247
clearGitHubApiCacheForTests();
48+
if (originalGitHubPat === undefined) {
49+
delete process.env.GITHUB_PAT;
50+
} else {
51+
process.env.GITHUB_PAT = originalGitHubPat;
52+
}
53+
54+
if (originalGitHubToken === undefined) {
55+
delete process.env.GITHUB_TOKEN;
56+
} else {
57+
process.env.GITHUB_TOKEN = originalGitHubToken;
58+
}
4359
});
4460

4561
describe('fetchGitHubContributions', () => {
@@ -81,13 +97,46 @@ describe('fetchGitHubContributions', () => {
8197
const [url, options] = vi.mocked(fetch).mock.calls[0];
8298
expect(url).toBe('https://api.github.com/graphql');
8399
expect(options?.method).toBe('POST');
100+
expect(options?.headers).toMatchObject({
101+
Authorization: 'bearer test-token',
102+
'Content-Type': 'application/json',
103+
});
84104

85105
// Make sure the username is wired into the GraphQL variables, not hardcoded.
86106
const body = JSON.parse(options?.body as string);
87107
expect(body.variables).toEqual({ login: 'octocat' });
88108
expect(body.query).toContain('contributionCalendar');
89109
});
90110

111+
it('uses GITHUB_TOKEN when GITHUB_PAT is not configured', async () => {
112+
delete process.env.GITHUB_PAT;
113+
process.env.GITHUB_TOKEN = 'actions-token';
114+
vi.mocked(fetch).mockResolvedValue(
115+
mockResponse({
116+
data: {
117+
user: { contributionsCollection: { contributionCalendar: mockCalendar } },
118+
},
119+
})
120+
);
121+
122+
await fetchGitHubContributions('octocat');
123+
124+
const [, options] = vi.mocked(fetch).mock.calls[0];
125+
expect(options?.headers).toMatchObject({
126+
Authorization: 'bearer actions-token',
127+
});
128+
});
129+
130+
it('throws before fetching when no GitHub token is configured', async () => {
131+
delete process.env.GITHUB_PAT;
132+
delete process.env.GITHUB_TOKEN;
133+
134+
await expect(fetchGitHubContributions('octocat')).rejects.toThrow(
135+
'GitHub token is missing. Set GITHUB_PAT or GITHUB_TOKEN.'
136+
);
137+
expect(fetch).not.toHaveBeenCalled();
138+
});
139+
91140
it('works correctly for a brand-new user who has zero contribution weeks', async () => {
92141
const emptyCalendar: ContributionCalendar = { totalContributions: 0, weeks: [] };
93142

lib/github.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export async function fetchWithRetry(
8080

8181
const GITHUB_GRAPHQL_URL = 'https://api.github.com/graphql';
8282
const GITHUB_REST_URL = 'https://api.github.com';
83+
const MISSING_GITHUB_TOKEN_MESSAGE = 'GitHub token is missing. Set GITHUB_PAT or GITHUB_TOKEN.';
8384

8485
type GitHubContributionResponse = {
8586
data?: {
@@ -182,8 +183,17 @@ export function clearGitHubApiCacheForTests(): void {
182183
reposCache.clear();
183184
}
184185

186+
function getGitHubToken(): string {
187+
const token = process.env.GITHUB_PAT || process.env.GITHUB_TOKEN;
188+
if (!token || token.trim() === '') {
189+
throw new Error(MISSING_GITHUB_TOKEN_MESSAGE);
190+
}
191+
192+
return token;
193+
}
194+
185195
const getHeaders = () => ({
186-
Authorization: `bearer ${process.env.GITHUB_PAT || process.env.GITHUB_TOKEN}`,
196+
Authorization: `bearer ${getGitHubToken()}`,
187197
'Content-Type': 'application/json',
188198
});
189199

0 commit comments

Comments
 (0)