diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a804500..d6ed6f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,6 +17,7 @@ jobs: packages: write id-token: write security-events: write + pull-requests: write with: tool: "npm" lint: "run lint" diff --git a/package-lock.json b/package-lock.json index 22af922..ead80bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "flowdive", - "version": "1.0.3", + "version": "1.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "flowdive", - "version": "1.0.3", + "version": "1.0.4", "dependencies": { "@dagrejs/dagre": "^3.0.0", "@tailwindcss/vite": "^4.2.2", diff --git a/package.json b/package.json index 713c3dd..dc9e1b8 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/components/YamlLoader.tsx b/src/components/YamlLoader.tsx index 898dc64..437998b 100644 --- a/src/components/YamlLoader.tsx +++ b/src/components/YamlLoader.tsx @@ -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, @@ -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() }; }) );