diff --git a/scripts/update-github-languages.mjs b/scripts/update-github-languages.mjs index 71dd9dee..38331601 100644 --- a/scripts/update-github-languages.mjs +++ b/scripts/update-github-languages.mjs @@ -2,15 +2,18 @@ // user's non-fork repositories (GraphQL, paginated). Needs GITHUB_TOKEN, which // Actions provides automatically. import { writeFile } from "node:fs/promises"; -import { fetchGitHubLanguages } from "../src/lib/services/github.ts"; +import { fetchGitHubCommitTotal, fetchGitHubLanguages } from "../src/lib/services/github.ts"; const username = process.env.GITHUB_USERNAME || "ewanc26"; const token = process.env.GITHUB_TOKEN; if (!token) throw new Error("GITHUB_TOKEN is required"); -const languages = await fetchGitHubLanguages(username, fetch, token); +const [languages, commits] = await Promise.all([ + fetchGitHubLanguages(username, fetch, token), + fetchGitHubCommitTotal(username, fetch, token), +]); if (languages.length === 0) throw new Error("No languages returned; leaving snapshot untouched"); const out = process.env.OUT_FILE || new URL("../src/lib/data/github-languages.json", import.meta.url); -await writeFile(out, JSON.stringify({ username, updatedAt: new Date().toISOString().slice(0, 10), languages }, null, 2) + "\n"); -console.log(`Wrote ${languages.length} languages for ${username}`); +await writeFile(out, JSON.stringify({ username, updatedAt: new Date().toISOString().slice(0, 10), commits, languages }, null, 2) + "\n"); +console.log(`Wrote ${languages.length} languages and ${commits} commits for ${username}`); diff --git a/src/lib/components/GithubActivity.svelte b/src/lib/components/GithubActivity.svelte index 60f1a881..b9cf91e5 100644 --- a/src/lib/components/GithubActivity.svelte +++ b/src/lib/components/GithubActivity.svelte @@ -5,8 +5,9 @@ username: string; contributions: ContributionCalendar | null; languages: LanguageShare[]; + commits?: number | null; } - let { username, contributions, languages }: Props = $props(); + let { username, contributions, languages, commits = null }: Props = $props(); const fmtDate = (iso: string) => new Date(`${iso}T00:00:00Z`).toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric", timeZone: "UTC" }); @@ -57,8 +58,8 @@ {#if contributions && stats}
-
Contributions
-
{stats.total.toLocaleString("en-GB")}
+
{commits === null ? "Contributions" : "Commits"}
+
{(commits ?? stats.total).toLocaleString("en-GB")}
Days active
diff --git a/src/lib/services/github.ts b/src/lib/services/github.ts index 6cdd5d97..eb310979 100644 --- a/src/lib/services/github.ts +++ b/src/lib/services/github.ts @@ -321,6 +321,20 @@ export async function fetchGitHubContributions( return fetchContributionsFromProfile(username, fetchFn); } +export async function fetchGitHubCommitTotal( + username: string, + fetchFn: typeof fetch, + token: string, +): Promise { + const data = await graphql( + `query Commits($login: String!) { user(login: $login) { contributionsCollection { totalCommitContributions } } }`, + username, + token, + fetchFn, + ); + return data.user.contributionsCollection.totalCommitContributions; +} + const LINGUIST_COLORS: Record = { Assembly: "#6E4C13", Astro: "#ff5a03", Batchfile: "#C1F12E", C: "#555555", "C#": "#178600", "C++": "#f34b7d", CMake: "#DA3434", CSS: "#663399", Clojure: "#db5855", Dart: "#00B4AB", diff --git a/src/lib/services/home.ts b/src/lib/services/home.ts index 7d677e37..2432ce1e 100644 --- a/src/lib/services/home.ts +++ b/src/lib/services/home.ts @@ -53,7 +53,7 @@ async function fetchVerifications() { const LANGUAGE_SNAPSHOT_URL = "https://raw.githubusercontent.com/ewanc26/website/data/github-languages.json"; -type LanguageSnapshot = typeof languageSnapshot; +type LanguageSnapshot = typeof languageSnapshot & { commits?: number | null }; const usable = (snap: LanguageSnapshot | null | undefined, username: string) => !!snap && @@ -61,18 +61,26 @@ const usable = (snap: LanguageSnapshot | null | undefined, username: string) => Array.isArray(snap.languages) && snap.languages.length > 0; -async function loadLanguages(username: string) { +async function loadSnapshot(username: string) { try { const res = await fetch(LANGUAGE_SNAPSHOT_URL); if (res.ok) { const remote = (await res.json()) as LanguageSnapshot; - if (usable(remote, username)) return remote.languages; + if (usable(remote, username)) { + return { languages: remote.languages, commits: remote.commits ?? null }; + } } } catch {} - if (usable(languageSnapshot, username)) return languageSnapshot.languages; - return fetchGitHubLanguages(username, fetch, env.GITHUB_TOKEN).catch( - () => [], - ); + const bundled = languageSnapshot as LanguageSnapshot; + if (usable(bundled, username)) { + return { languages: bundled.languages, commits: bundled.commits ?? null }; + } + const languages = await fetchGitHubLanguages( + username, + fetch, + env.GITHUB_TOKEN, + ).catch(() => []); + return { languages, commits: null }; } export async function getHomeData() { @@ -85,7 +93,7 @@ export async function getHomeData() { postsData, githubProjects, githubContributions, - githubLanguages, + githubSnapshot, publicationsData, links, ] = await Promise.all([ @@ -107,7 +115,7 @@ export async function getHomeData() { fetchGitHubContributions(githubUsername, fetch, env.GITHUB_TOKEN).catch( () => null, ), - loadLanguages(githubUsername), + loadSnapshot(githubUsername), fetchPublications(PUBLIC_ATPROTO_DID, fetch).catch(() => ({ publications: [], })), @@ -123,7 +131,8 @@ export async function getHomeData() { githubProjects: githubProjects as any[], githubUsername, githubContributions, - githubLanguages, + githubLanguages: githubSnapshot.languages, + githubCommits: githubSnapshot.commits, publications: (publicationsData?.publications ?? []) as any[], links: (links ?? { cards: [] }) as { cards: any[] }, }; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index d45d0d0d..ec5dd418 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -15,7 +15,7 @@ import { PUBLIC_LEAFLET_BLOG_PUBLICATION, PUBLIC_ATPROTO_DID } from "$env/static/public"; let { data } = $props(); - const { profile, kibunStatus, musicStatus, posts, githubProjects, githubUsername, githubContributions, githubLanguages, publications, links, apps, watching, feed, latestPlay } = $derived(data); + const { profile, kibunStatus, musicStatus, posts, githubProjects, githubUsername, githubContributions, githubLanguages, githubCommits, publications, links, apps, watching, feed, latestPlay } = $derived(data); const almanac = $derived(data.almanac); const esc = (t: string) => t.replace(/&/g, "&").replace(//g, ">"); @@ -233,7 +233,7 @@ {/if}

Commitsa year of GitHub

- + {#if watching.length > 0}

Watchinglogged on Popfeed