From a45cbffa13f9856a59207928ff2b9454fed5bf4c Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 24 Jun 2026 23:37:23 -0700 Subject: [PATCH 1/3] fix(release): checkout CHANGELOG in github-release job so binaries publish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The github-release job downloaded artifacts but never checked out the repo, so the new "Extract release notes from CHANGELOG" step threw ENOENT and failed the whole job — v0.47.0 published 0 binaries despite every bun build succeeding. Sparse-checkout CHANGELOG.md and harden the notes script to fall back to a plain release body instead of crashing the publish. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/release.yml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d0007e712..7e41ab8137 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -373,6 +373,18 @@ jobs: contents: write steps: + # FNXC:Changelog 2026-06-25-09:30: + # The release-notes step reads root CHANGELOG.md, so this job needs the repo + # tree — not just downloaded artifacts. Without this checkout the notes step + # threw `ENOENT: CHANGELOG.md` and failed the whole job, publishing zero + # binaries on v0.47.0 even though every bun build leg succeeded. Sparse-checkout + # only CHANGELOG.md to keep the job lean; no submodules or full history needed. + - name: Checkout CHANGELOG for release notes + uses: actions/checkout@v4 + with: + sparse-checkout: CHANGELOG.md + sparse-checkout-cone-mode: false + - name: Download all artifacts uses: actions/download-artifact@v4 with: @@ -401,18 +413,25 @@ jobs: id: notes run: | VERSION="${GITHUB_REF#refs/tags/v}" + # FNXC:Changelog 2026-06-25-09:30: + # Never let release-note extraction fail the publish. A missing/unreadable + # CHANGELOG or absent version section falls back to a plain "Release vX.Y.Z" + # body so binaries still ship — matching the job's "partial over none" intent. NOTES=$(node -e " const fs = require('fs'); - const content = fs.readFileSync('CHANGELOG.md', 'utf8'); + const fallback = 'Release v${VERSION}'; + let content = ''; + try { content = fs.readFileSync('CHANGELOG.md', 'utf8'); } + catch (e) { console.log(fallback); process.exit(0); } const lines = content.split(/\r?\n/); const header = '## ' + '${VERSION}'; const start = lines.findIndex(l => l.trim() === header); - if (start === -1) { console.log('Release v${VERSION}'); process.exit(0); } + if (start === -1) { console.log(fallback); process.exit(0); } let end = lines.length; for (let i = start + 1; i < lines.length; i++) { if (lines[i].startsWith('## ')) { end = i; break; } } - console.log(lines.slice(start + 1, end).join('\n').trim() || 'Release v${VERSION}'); + console.log(lines.slice(start + 1, end).join('\n').trim() || fallback); ") echo "$NOTES" > /tmp/release-notes.md From 8b81cceb17800c2b249842edf87156d0272e2ebd Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 24 Jun 2026 23:38:59 -0700 Subject: [PATCH 2/3] fix(desktop): externalize @fusion/engine so desktop release builds pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit local-runtime.ts dynamically imports @fusion/engine, but it was missing from the esbuild externals list (only @fusion/core and @fusion/dashboard were there). esbuild followed the import and tried to bundle engine's transitive node-pty native .node binaries, failing with "No loader is configured for .node files" — which broke every desktop Windows EXE and macOS DMG build leg. Externalize @fusion/engine like the other workspace packages; it resolves from node_modules at runtime. Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/desktop/scripts/build.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/desktop/scripts/build.ts b/packages/desktop/scripts/build.ts index 728b875ac0..7c4fb4b453 100644 --- a/packages/desktop/scripts/build.ts +++ b/packages/desktop/scripts/build.ts @@ -5,10 +5,18 @@ import { buildDashboardClient, packageRoot, workspaceRoot } from "./workspace-to const dashboardClientDir = join(workspaceRoot, "packages", "dashboard", "dist", "client"); const desktopDistDir = join(packageRoot, "dist"); const desktopClientDistDir = join(desktopDistDir, "client"); +// FNXC:DesktopBuild 2026-06-25-09:45: +// Every workspace @fusion/* package and native (.node) module must stay external +// to the Electron main/preload bundles — they resolve from node_modules at runtime. +// @fusion/engine was missing here, so esbuild followed local-runtime.ts's dynamic +// `import("@fusion/engine")` and tried to bundle engine's transitive node-pty +// (@homebridge/node-pty-prebuilt-multiarch) native binaries, failing with +// "No loader is configured for .node files" and breaking every desktop release build. const sharedExternals = [ "electron", "@fusion/core", "@fusion/dashboard", + "@fusion/engine", "better-sqlite3", ]; const mainExternals = sharedExternals; From a20235be0dc9c18ea6c2331fd835ef45a860f1c2 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 24 Jun 2026 23:43:47 -0700 Subject: [PATCH 3/3] chore(changeset): patch for release binary publish fix Co-Authored-By: Claude Opus 4.8 (1M context) --- .changeset/fix-release-binary-publish.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/fix-release-binary-publish.md diff --git a/.changeset/fix-release-binary-publish.md b/.changeset/fix-release-binary-publish.md new file mode 100644 index 0000000000..2e3953b992 --- /dev/null +++ b/.changeset/fix-release-binary-publish.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Fix release pipeline so binaries and desktop installers publish again. +category: fix +dev: github-release job sparse-checks-out CHANGELOG.md (was missing a checkout, so the release-notes step threw ENOENT and published 0 assets on v0.47.0); desktop esbuild build externalizes @fusion/engine so it no longer tries to bundle node-pty's native .node binaries.