Fix github query to grab all contributions
This commit is contained in:
parent
620121b505
commit
53084c4e6f
1 changed files with 68 additions and 28 deletions
|
|
@ -11,19 +11,27 @@ const config = {
|
||||||
forgejoURL: requireEnv("FJ_URL"),
|
forgejoURL: requireEnv("FJ_URL"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
const oneYearAgo = new Date();
|
const oneYearAgo = new Date();
|
||||||
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
||||||
const formattedOneYearAgo = oneYearAgo.toISOString().replace("Z", "+00:00");
|
const formattedOneYearAgo = oneYearAgo.toISOString().replace("Z", "+00:00");
|
||||||
|
|
||||||
const ghQuery = `
|
function buildGhQuery(from: string, to: string): string {
|
||||||
{
|
return `{
|
||||||
user(login: "aselimov") {
|
viewer {
|
||||||
contributionsCollection {
|
contributionsCollection(from: "${from}", to: "${to}") {
|
||||||
|
contributionCalendar {
|
||||||
|
weeks {
|
||||||
|
contributionDays {
|
||||||
|
date
|
||||||
|
contributionCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
commitContributionsByRepository(maxRepositories: 100) {
|
commitContributionsByRepository(maxRepositories: 100) {
|
||||||
repository {
|
repository {
|
||||||
nameWithOwner
|
nameWithOwner
|
||||||
isMirror
|
isMirror
|
||||||
isPrivate
|
|
||||||
}
|
}
|
||||||
contributions(first: 100) {
|
contributions(first: 100) {
|
||||||
nodes {
|
nodes {
|
||||||
|
|
@ -34,8 +42,8 @@ const ghQuery = `
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}`;
|
||||||
`;
|
}
|
||||||
|
|
||||||
type DayContributions = {
|
type DayContributions = {
|
||||||
[repo: string]: number;
|
[repo: string]: number;
|
||||||
|
|
@ -126,25 +134,33 @@ function deduplicateAcrossPlatforms(
|
||||||
function parseGitHubContributions(data: any): ActivityMap {
|
function parseGitHubContributions(data: any): ActivityMap {
|
||||||
const result: ActivityMap = {};
|
const result: ActivityMap = {};
|
||||||
|
|
||||||
const repos =
|
const collection = data?.data?.viewer?.contributionsCollection;
|
||||||
data?.data?.user?.contributionsCollection
|
|
||||||
?.commitContributionsByRepository ?? [];
|
|
||||||
|
|
||||||
for (const repoEntry of repos) {
|
const calendarMap: { [day: string]: number } = {};
|
||||||
|
for (const week of collection?.contributionCalendar?.weeks ?? []) {
|
||||||
|
for (const day of week.contributionDays) {
|
||||||
|
if (day.contributionCount > 0) calendarMap[day.date] = day.contributionCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const repoEntry of collection?.commitContributionsByRepository ?? []) {
|
||||||
const repoName: string = repoEntry.repository.nameWithOwner;
|
const repoName: string = repoEntry.repository.nameWithOwner;
|
||||||
const isMirror: boolean = repoEntry.repository.isMirror;
|
if (repoEntry.repository.isMirror) continue;
|
||||||
const isPrivate: boolean = repoEntry.repository.isPrivate;
|
|
||||||
|
|
||||||
if (isMirror) continue;
|
|
||||||
|
|
||||||
const displayName = isPrivate ? "private" : repoName;
|
|
||||||
|
|
||||||
for (const contribution of repoEntry.contributions.nodes) {
|
for (const contribution of repoEntry.contributions.nodes) {
|
||||||
const day: string = contribution.occurredAt.split("T")[0];
|
const day: string = contribution.occurredAt.split("T")[0];
|
||||||
const count: number = contribution.commitCount;
|
const count: number = contribution.commitCount;
|
||||||
|
|
||||||
if (!result[day]) result[day] = {};
|
if (!result[day]) result[day] = {};
|
||||||
result[day]![displayName] = (result[day]![displayName] ?? 0) + count;
|
result[day]![repoName] = (result[day]![repoName] ?? 0) + count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [day, total] of Object.entries(calendarMap)) {
|
||||||
|
const known = Object.values(result[day] ?? {}).reduce((a, b) => a + b, 0);
|
||||||
|
const hidden = total - known;
|
||||||
|
if (hidden > 0) {
|
||||||
|
if (!result[day]) result[day] = {};
|
||||||
|
result[day]!["private"] = (result[day]!["private"] ?? 0) + hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,25 +231,49 @@ async function getForgejoActivityMap(): Promise<ActivityMap> {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function makeActivityMap(): Promise<ActivityMap> {
|
async function ghFetch(query: string): Promise<any> {
|
||||||
const ghResponse = await fetch("https://api.github.com/graphql", {
|
const response = await fetch("https://api.github.com/graphql", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Authorization: `Bearer ${config.githubApiKey}`,
|
Authorization: `Bearer ${config.githubApiKey}`,
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ query: ghQuery }),
|
body: JSON.stringify({ query }),
|
||||||
});
|
});
|
||||||
|
if (!response.ok) {
|
||||||
if (!ghResponse.ok) {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`GitHub API error: ${ghResponse.status} ${ghResponse.statusText}`,
|
`GitHub API error: ${response.status} ${response.statusText}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
const ghData = await ghResponse.json();
|
async function getGitHubActivityMap(): Promise<ActivityMap> {
|
||||||
const ghMap = parseGitHubContributions(ghData);
|
const ranges = Array.from({ length: 12 }, (_, i) => {
|
||||||
const fjMap = await getForgejoActivityMap();
|
const to = new Date(now);
|
||||||
|
to.setMonth(to.getMonth() - i);
|
||||||
|
const from = new Date(to);
|
||||||
|
from.setMonth(from.getMonth() - 1);
|
||||||
|
return { from: from.toISOString(), to: to.toISOString() };
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await Promise.all(
|
||||||
|
ranges.map(({ from, to }) => ghFetch(buildGhQuery(from, to))),
|
||||||
|
);
|
||||||
|
|
||||||
|
const map: ActivityMap = {};
|
||||||
|
for (const data of results) {
|
||||||
|
mergeInto(map, parseGitHubContributions(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function makeActivityMap(): Promise<ActivityMap> {
|
||||||
|
const [ghMap, fjMap] = await Promise.all([
|
||||||
|
getGitHubActivityMap(),
|
||||||
|
getForgejoActivityMap(),
|
||||||
|
]);
|
||||||
|
|
||||||
return deduplicateAcrossPlatforms(ghMap, fjMap);
|
return deduplicateAcrossPlatforms(ghMap, fjMap);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue