Skip to content

Commit cc9f91a

Browse files
hopefully fixed the project cards issue
1 parent d547aa5 commit cc9f91a

File tree

2 files changed

+111
-16
lines changed

2 files changed

+111
-16
lines changed

.github/workflows/astro.yml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,36 @@ jobs:
5858
- name: Update Astro and dependencies
5959
run: ${{ steps.detect-package-manager.outputs.manager }} install astro@latest @astrojs/tailwind@latest @astrojs/react@latest @astrojs/rss@latest
6060
working-directory: ${{ env.BUILD_PATH }}
61+
- name: Fetch GitHub repo metadata
62+
# use GH_PAT secret if set, otherwise fall back to the built-in token
63+
env:
64+
GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
65+
run: |
66+
node <<'NODE'
67+
const fs = require('fs');
68+
const repos = ['c0mebackf0lders','pixeljellyfish.dev','repo','OS-Stuff'];
69+
(async () => {
70+
const out = [];
71+
for (const r of repos) {
72+
try {
73+
const url = `https://api.github.com/repos/pixeljellyfish/${r}`;
74+
const headers = process.env.GH_TOKEN ? { Authorization: `token ${process.env.GH_TOKEN}` } : undefined;
75+
const res = await fetch(url, headers ? { headers } : undefined);
76+
if (res.ok) {
77+
const d = await res.json();
78+
out.push({ name: d.name, full_name: d.full_name, description: d.description, stargazers_count: d.stargazers_count });
79+
} else {
80+
console.warn('GitHub fetch failed for', r, res.status);
81+
}
82+
} catch (e) {
83+
console.warn('Error fetching', r, e.message || e);
84+
}
85+
}
86+
fs.mkdirSync('src/data', { recursive: true });
87+
fs.writeFileSync('src/data/repos.json', JSON.stringify(out, null, 2));
88+
console.log('Wrote src/data/repos.json');
89+
})();
90+
NODE
6191
- name: Build with Astro and copy to public
6292
run: |
6393
${{ steps.detect-package-manager.outputs.runner }} astro build \
@@ -66,7 +96,8 @@ jobs:
6696
rm -rf public/* && cp -r dist/* public/
6797
working-directory: ${{ env.BUILD_PATH }}
6898
env:
69-
GH_TOKEN: ${{ secrets.GH_PAT }}
99+
# pass the same token used earlier (fallback to built-in token if GH_PAT not provided)
100+
GH_TOKEN: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
70101
OPENWEATHER_API_KEY: ${{ secrets.OPENWEATHER_API_KEY }}
71102
- name: Upload artifact
72103
uses: actions/upload-pages-artifact@v3

src/components/ProjectCard.astro

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
---
22
import Icon from 'astro-icon';
3+
import fs from 'fs';
4+
import path from 'path';
35
46
interface Props {
57
repo: string;
@@ -12,25 +14,87 @@ let name = 'Loading';
1214
let description = 'Loading';
1315
let starDisplay = 'Loading';
1416
17+
let populated = false;
18+
19+
// Try to read pre-fetched local JSON produced by CI at src/data/repos.json
1520
try {
16-
const res = await fetch(`https://api.github.com/repos/pixeljellyfish/${repo}`, {
17-
headers: {
18-
Authorization: `token ${import.meta.env.GITHUB_TOKEN}`
21+
const dataUrl = new URL('../data/repos.json', import.meta.url);
22+
const dataPath = dataUrl.pathname;
23+
if (fs.existsSync(dataPath)) {
24+
const file = fs.readFileSync(dataPath, 'utf-8');
25+
const list = JSON.parse(file);
26+
const entry = Array.isArray(list) ? list.find(e => {
27+
// match by repo name or full_name
28+
if (!e) return false;
29+
if (e.name === repo) return true;
30+
if (typeof e.full_name === 'string' && e.full_name.endsWith(`/${repo}`)) return true;
31+
return false;
32+
}) : null;
33+
34+
if (entry) {
35+
name = entry.name || 'Unnamed Repo';
36+
description = entry.description || 'No description available';
37+
starDisplay = entry.stargazers_count === 0 ? 'No stars yet' : entry.stargazers_count;
38+
populated = true;
1939
}
20-
});
21-
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
22-
const data = await res.json();
23-
name = data.name || 'Unnamed Repo';
24-
description = data.description || 'No description available';
25-
starDisplay = data.stargazers_count === 0 ? 'No stars yet' : data.stargazers_count;
26-
} catch (error) {
27-
console.error(`Failed to fetch repo ${repo} at build time:`, error);
28-
name = 'Error';
29-
description = 'Could not load repository data';
30-
starDisplay = 'N/A';
40+
}
41+
} catch (err) {
42+
// silently continue to network fetch if local data is missing or invalid
43+
console.warn('ProjectCard: local repo JSON not available or invalid:', err);
3144
}
32-
---
3345
46+
if (!populated) {
47+
try {
48+
const url = `https://api.github.com/repos/pixeljellyfish/${repo}`;
49+
const token = import.meta.env.GITHUB_TOKEN;
50+
let res;
51+
52+
// If we have a token, try authenticated first (better rate limits), otherwise unauthenticated.
53+
if (token) {
54+
res = await fetch(url, { headers: { Authorization: `token ${token}` } });
55+
// If auth fails (401/403) or rate-limited, try unauthenticated fallback:
56+
if (!res.ok && (res.status === 401 || res.status === 403 || res.status === 429)) {
57+
const fallbackRes = await fetch(url);
58+
if (fallbackRes.ok) {
59+
const fallbackData = await fallbackRes.json();
60+
name = fallbackData.name || 'Unnamed Repo';
61+
description = fallbackData.description || 'No description available';
62+
starDisplay = fallbackData.stargazers_count === 0 ? 'No stars yet' : fallbackData.stargazers_count;
63+
} else {
64+
throw new Error(`GitHub fetch failed (auth then fallback). Statuses: ${res.status}, ${fallbackRes.status}`);
65+
}
66+
} else if (!res.ok) {
67+
throw new Error(`GitHub fetch failed: ${res.status} ${res.statusText}`);
68+
} else {
69+
const data = await res.json();
70+
name = data.name || 'Unnamed Repo';
71+
description = data.description || 'No description available';
72+
starDisplay = data.stargazers_count === 0 ? 'No stars yet' : data.stargazers_count;
73+
}
74+
} else {
75+
// No token: do a single unauthenticated fetch and handle common failure statuses gracefully
76+
res = await fetch(url);
77+
if (!res.ok) {
78+
// if rate-limited or forbidden, show a friendly fallback instead of crashing
79+
console.warn(`GitHub unauthenticated fetch failed for ${repo}:`, res.status, res.statusText);
80+
name = 'Unavailable';
81+
description = 'Repository data temporarily unavailable';
82+
starDisplay = 'N/A';
83+
} else {
84+
const data = await res.json();
85+
name = data.name || 'Unnamed Repo';
86+
description = data.description || 'No description available';
87+
starDisplay = data.stargazers_count === 0 ? 'No stars yet' : data.stargazers_count;
88+
}
89+
}
90+
} catch (error) {
91+
console.error(`Failed to fetch repo ${repo} at build time:`, error);
92+
name = 'Error';
93+
description = 'Could not load repository data';
94+
starDisplay = 'N/A';
95+
}
96+
}
97+
---
3498
<a
3599
href={`https://github.com/pixeljellyfish/${repo}`}
36100
rel="noopener noreferrer"

0 commit comments

Comments
 (0)