diff --git a/.github/workflows/cross-platform-bundle.yml b/.github/workflows/cross-platform-bundle.yml new file mode 100644 index 0000000..f99d0e0 --- /dev/null +++ b/.github/workflows/cross-platform-bundle.yml @@ -0,0 +1,99 @@ +name: Cross-platform bundle spike + +# GTM-SCALE-PLAN.md §3 (unlock 2) / docs/CROSS-PLATFORM-HARDENING.md P2. +# The compile spike (cross-platform-spike.yml) proved Markup *links* on +# Win/Linux. This one goes further: it produces real **installers** — +# Linux .deb + .AppImage, Windows NSIS .exe — to surface packaging issues +# (AppImage FUSE/linuxdeploy, NSIS) before a beta. UNSIGNED on purpose: +# Windows code-signing needs a cert (owner's call, GTM §3); these artifacts +# are for validation, not distribution. Does not touch the macOS release flow +# (`--bundles` overrides tauri.conf.json's macOS targets per invocation, and +# createUpdaterArtifacts is unset so no updater signing key is required). +# +# Heavy (release LTO build) — runs on demand + on push to a *bundle* spike branch. + +on: + workflow_dispatch: {} + push: + branches: ["spike/*bundle*"] + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + +jobs: + bundle: + name: bundle (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + bundles: deb,appimage + - os: windows-latest + bundles: nsis + steps: + - uses: actions/checkout@v6 + + - uses: pnpm/action-setup@v6 + with: + version: 10 + + - uses: actions/setup-node@v6 + with: + node-version: 22 + cache: pnpm + + # Linux: WebKitGTK toolchain + libfuse2 (AppImage runtime needs FUSE 2). + - name: Install Linux system deps + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y \ + libwebkit2gtk-4.1-dev \ + libappindicator3-dev \ + librsvg2-dev \ + patchelf \ + libxdo-dev \ + libssl-dev \ + libfuse2 + + - uses: dtolnay/rust-toolchain@stable + + - name: Cache cargo registry + target + uses: Swatinem/rust-cache@v2 + with: + workspaces: src-tauri + + - name: Install frontend deps + run: pnpm install --frozen-lockfile + + # Real release bundle. `--bundles` overrides the macOS-only config targets. + # No signing env: createUpdaterArtifacts is unset, so this needs no key. + - name: tauri build (bundle ${{ matrix.bundles }}) + run: pnpm tauri build --bundles ${{ matrix.bundles }} + + - name: List produced bundles + shell: bash + run: | + echo "── bundles ──────────────────────────────" + find src-tauri/target/release/bundle -maxdepth 2 \ + \( -name '*.deb' -o -name '*.AppImage' -o -name '*.exe' -o -name '*.msi' \) \ + -print -exec ls -lh {} \; 2>/dev/null || echo "no bundles found" + + - name: Upload bundles + if: ${{ !cancelled() }} + uses: actions/upload-artifact@v7 + with: + name: markup-bundle-${{ matrix.os }} + path: | + src-tauri/target/release/bundle/**/*.deb + src-tauri/target/release/bundle/**/*.AppImage + src-tauri/target/release/bundle/**/*.exe + src-tauri/target/release/bundle/**/*.msi + if-no-files-found: warn + retention-days: 7 diff --git a/docs/CROSS-PLATFORM-HARDENING.md b/docs/CROSS-PLATFORM-HARDENING.md index a776fc0..0df6c8f 100644 --- a/docs/CROSS-PLATFORM-HARDENING.md +++ b/docs/CROSS-PLATFORM-HARDENING.md @@ -43,15 +43,22 @@ Ordered by user-visible impact. ### P2 — packaging & distribution (can't ship without) -3. **Bundle targets are macOS-only.** `tauri.conf.json` → `bundle.targets` is - `["dmg","app"]`. Add per-platform targets: Linux `deb` + `appimage` - (+ optional `flatpak`), Windows `nsis` + optional `msi`. The spike used - `--no-bundle`, so packaging is **unverified** — expect AppImage FUSE / NSIS - quirks on first real bundle. -4. **Code signing.** Windows needs a **code-signing certificate** (EV or OV) or - SmartScreen will warn on every download; Linux AppImage/flatpak signing is - lighter. Budget + procure the Windows cert (this is the real cost flagged in - GTM §3). +3. **✅ Packaging works (unsigned, CI-verified).** The bundle spike + (`.github/workflows/cross-platform-bundle.yml`) produces real installers on + both platforms with `tauri build --bundles …` (no change to `tauri.conf.json`, + so the macOS release flow is untouched): + - Linux → `Markup_1.0.1_amd64.deb` + `Markup_1.0.1_amd64.AppImage` + (`libfuse2` needed on the runner for AppImage) + - Windows → `Markup_1.0.1_x64-setup.exe` (NSIS) + + No bundler errors. **Remaining:** decide whether to bake these targets into + `tauri.conf.json` per-OS (vs CLI `--bundles`) and wire them into a real + release pipeline (today `release.yml` is macOS-only). `flatpak` / `msi` still + optional/unbuilt. +4. **Code signing — owner's call.** The installers above are **unsigned**: + Windows needs a **code-signing certificate** (EV or OV) or SmartScreen warns + on every download; Linux AppImage/flatpak signing is lighter. Budget + + procure the Windows cert (the real cost flagged in GTM §3). 5. **Updater per-platform.** The updater endpoint (`latest.json`) and signed artifacts are currently macOS-only. Extend the release pipeline (`.github/workflows/release.yml`) to build, sign, and publish Win/Linux