Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
packages: write
id-token: write
security-events: write
pull-requests: write
with:
tool: "npm"
lint: "run lint"
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "flowdive",
"description": "Dive into your GitHub Actions workflows — interactive visualization with drill-down navigation and graph view.",
"private": true,
"version": "1.0.3",
"version": "1.0.4",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
12 changes: 10 additions & 2 deletions src/components/YamlLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ async function readDropItems(dataTransfer: DataTransfer): Promise<{ name: string

// ─── GitHub API helpers ───────────────────────────────────────────────────────

interface GhFile { name: string; download_url: string; type: string; }
interface GhFile { name: string; download_url: string | null; url: string; type: string; }

async function fetchWorkflowsFromGitHub(
repo: string,
Expand All @@ -185,7 +185,15 @@ async function fetchWorkflowsFromGitHub(

const contents = await Promise.all(
yamlFiles.map(async f => {
const r = await fetch(f.download_url, token ? { headers } : {});
// download_url for private repos includes a signed token, so no Auth header needed.
// download_url is null only in rare edge cases; fall back to API url + base64 decode.
if (!f.download_url) {
const r = await fetch(f.url, { headers });
if (!r.ok) throw new Error(`Failed to fetch ${f.name}: ${r.status}`);
const data = await r.json();
return { name: f.name, content: atob(data.content.replace(/\n/g, '')) };
}
const r = await fetch(f.download_url);
return { name: f.name, content: await r.text() };
})
);
Expand Down
Loading