# Binary Release workflow # # This workflow builds platform-specific binaries and creates a GitHub Release # when a version tag (v*) is pushed. This is the second release channel — # npm publishing is handled separately by version.yml via changesets. # # Release channels: # 1. npm publish — handled by version.yml (changesets/action) # 2. GitHub Release with binaries — handled by this workflow (release.yml) name: Binary Release # Auto-trigger disabled; workflow preserved for manual use via workflow_dispatch. on: workflow_dispatch: permissions: contents: write jobs: # ── Build platform-specific binaries ────────────────────────────────── build-binaries: name: Build ${{ matrix.target }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - os: ubuntu-latest target: bun-linux-x64 binary: fn-linux-x64 - os: macos-latest target: bun-darwin-arm64 binary: fn-darwin-arm64 - os: macos-13 target: bun-darwin-x64 binary: fn-darwin-x64 - os: windows-latest target: bun-windows-x64 binary: fn-windows-x64.exe steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node and install dependencies uses: ./.github/actions/setup-node-pnpm - name: Install Bun uses: oven-sh/setup-bun@v2 - name: Build run: pnpm build - name: Build binary run: pnpm --filter @runfusion/fusion build:exe -- --target ${{ matrix.target }} - name: Verify binary exists shell: bash run: test -f packages/cli/dist/${{ matrix.binary }} - name: Sign macOS binary if: runner.os == 'macOS' env: APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }} APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} APPLE_IDENTITY: ${{ secrets.APPLE_IDENTITY }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }} run: bash scripts/sign-macos.sh packages/cli/dist/${{ matrix.binary }} packages/cli/dist/runtime - name: Sign Windows binary if: runner.os == 'Windows' env: WINDOWS_CERTIFICATE_BASE64: ${{ secrets.WINDOWS_CERTIFICATE_BASE64 }} WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} run: pwsh scripts/sign-windows.ps1 packages/cli/dist/${{ matrix.binary }} - name: Generate checksum (Linux) if: runner.os == 'Linux' run: | cd packages/cli/dist sha256sum ${{ matrix.binary }} > ${{ matrix.binary }}.sha256 - name: Generate checksum (macOS) if: runner.os == 'macOS' run: | cd packages/cli/dist shasum -a 256 ${{ matrix.binary }} > ${{ matrix.binary }}.sha256 - name: Generate checksum (Windows) if: runner.os == 'Windows' shell: pwsh run: | cd packages/cli/dist $hash = (Get-FileHash ${{ matrix.binary }} -Algorithm SHA256).Hash.ToLower() "$hash ${{ matrix.binary }}" | Out-File -Encoding ascii ${{ matrix.binary }}.sha256 - name: Upload artifact uses: actions/upload-artifact@v4 with: name: ${{ matrix.binary }} path: | packages/cli/dist/${{ matrix.binary }} packages/cli/dist/${{ matrix.binary }}.sha256 packages/cli/dist/runtime/**/* # ── Build Windows desktop EXE artifacts ────────────────────────────── # Code-signing with WINDOWS_CERTIFICATE_BASE64 / WINDOWS_CERTIFICATE_PASSWORD # is intentionally deferred to FN-5592; ARM64 support is tracked in FN-5594. build-desktop-windows: name: Build Desktop Windows EXE runs-on: windows-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node and install dependencies uses: ./.github/actions/setup-node-pnpm - name: Build run: pnpm build - name: Build desktop package run: pnpm --filter @fusion/desktop build - name: Package Windows desktop EXE run: pnpm --filter @fusion/desktop dist:win -- --publish never env: CSC_IDENTITY_AUTO_DISCOVERY: "false" GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Verify desktop EXE artifacts shell: pwsh run: | $exes = Get-ChildItem packages/desktop/dist-electron -Filter "Fusion-*-win-*.exe" if ($exes.Count -eq 0) { Write-Error "No Fusion Windows EXE artifacts produced" exit 1 } - name: Generate desktop EXE checksums shell: pwsh run: | $exes = Get-ChildItem packages/desktop/dist-electron -Filter "Fusion-*-win-*.exe" foreach ($exe in $exes) { $hash = (Get-FileHash $exe.FullName -Algorithm SHA256).Hash.ToLower() "$hash $($exe.Name)" | Out-File -Encoding ascii "$($exe.FullName).sha256" } - name: Upload desktop Windows artifacts uses: actions/upload-artifact@v4 with: name: fusion-desktop-windows path: | packages/desktop/dist-electron/Fusion-*-win-*.exe packages/desktop/dist-electron/Fusion-*-win-*.exe.sha256 packages/desktop/dist-electron/Fusion-*-win-*.exe.blockmap # ── Create GitHub Release ───────────────────────────────────────────── github-release: name: Create GitHub Release needs: [build-binaries, build-desktop-windows] runs-on: ubuntu-latest permissions: contents: write steps: - name: Download all artifacts uses: actions/download-artifact@v4 with: path: artifacts - name: Collect release files run: | mkdir release-files find artifacts -type f \( -name "fn-*" -o -name "*.sha256" -o -name "*.exe" -o -name "*.exe.sha256" -o -name "*.blockmap" \) -exec cp {} release-files/ \; ls -la release-files/ - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: generate_release_notes: true files: release-files/*