Skip to content

Commit f392855

Browse files
joaoh82claude
andauthored
Phase 6e: add publish-desktop job to release.yml (#20)
Adds a tauri-action-based matrix job that builds + uploads unsigned desktop installers to the sqlrite-desktop-v<V> GitHub Release alongside the existing publish-crate + publish-ffi jobs. Matrix mirrors publish-ffi's OS/arch choices for consistency: ubuntu-22.04 → AppImage + .deb (x86_64) macos-latest → .dmg (aarch64) windows-latest → .msi (x86_64) ubuntu-22.04 (not ubuntu-latest) is deliberate: AppImage links glibc at build time, so building on 22.04 (glibc 2.35) yields an AppImage that runs on any distro with glibc ≥ 2.35 — building on 24.04 would produce an AppImage that won't launch on older distros. Wiring: - tag-all → also pushes sqlrite-desktop-v<V> - finalize's `needs` → extended with publish-desktop - umbrella release body → includes 🖥️ Desktop link - environment: release → same approval gate as the other publish-* jobs (re-uses the single required-reviewer config that already exists for crates.io) Tauri configuration: - bundle.active flipped from false → true so installers actually get produced (this was the single-biggest gotcha) - bundle.icon array extended to list the native-format icons for each platform (.icns for macOS, .ico for Windows, size-specific PNGs for Linux) - category / shortDescription / longDescription added so .deb / AppImage metadata has useful fields instead of defaults Icons (64x64.png, 128x128.png, 128x128@2x.png, icon.icns, icon.ico) are pre-generated via `npx tauri icon src-tauri/icons/icon.png` and committed to the repo. That keeps CI deterministic (no build-time network dependency on the Tauri CLI version resolving differently over time) and saves ~10s per matrix cell. Tradeoff: anyone swapping out icon.png has to re-run `tauri icon` locally and commit the regenerated assets — PR review catches this. The android/ and ios/ outputs + Windows-Store Square* / StoreLogo variants tauri icon also generates are discarded (not used by desktop-MVP, keeps repo lean). Installers ship unsigned — Phase 6.1 wires up Apple Developer ID + Windows code-signing certs. The release body warns about the "unidentified developer" / SmartScreen prompts and how to bypass until signing lands. Follow-ups: - macOS universal (x86_64 + aarch64 via lipo) — needs both Rust targets installed + a lipo step - Linux aarch64 AppImage — adds one ubuntu-24.04-arm matrix cell Also updates docs/roadmap.md with the Phase 6e done-marker + a retrospective note on the v0.1.2 canary success. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 900012a commit f392855

8 files changed

Lines changed: 150 additions & 15 deletions

File tree

.github/workflows/release.yml

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
# merge commit. A `workflow_dispatch` fallback lets a human re-run
55
# the publish side manually when the auto-trigger needs a kick.
66
#
7-
# Phase 6d scope: tag-all + publish-crate + publish-ffi + finalize.
8-
# Phase 6e–6i add publish-desktop / publish-python / publish-nodejs /
9-
# publish-wasm / publish-go as separate jobs to this same file.
7+
# Phase 6d: tag-all + publish-crate + publish-ffi + finalize.
8+
# Phase 6e adds publish-desktop.
9+
# Phases 6f–6i add publish-python / publish-nodejs / publish-wasm /
10+
# publish-go as separate jobs to this same file.
1011
#
1112
# Design doc: docs/release-plan.md.
1213
# One-time registry / branch-protection setup: docs/release-secrets.md.
@@ -84,14 +85,14 @@ jobs:
8485
# BEFORE any publish step so a bad version number (e.g., tag
8586
# already exists for some reason) aborts the whole release cleanly.
8687
#
87-
# Phase 6d only tags products whose publish jobs exist:
88-
# - sqlrite-v<V> (Rust engine)
89-
# - sqlrite-ffi-v<V> (C FFI prebuilt binaries)
90-
# - v<V> (umbrella)
88+
# As of Phase 6e, we tag:
89+
# - sqlrite-v<V> (Rust engine)
90+
# - sqlrite-ffi-v<V> (C FFI prebuilt binaries)
91+
# - sqlrite-desktop-v<V> (Tauri desktop installers)
92+
# - v<V> (umbrella)
9193
#
9294
# Later phases add sqlrite-py-v<V>, sqlrite-node-v<V>,
93-
# sqlrite-wasm-v<V>, sdk/go/v<V>, sqlrite-desktop-v<V> as their
94-
# publish jobs come online.
95+
# sqlrite-wasm-v<V>, sdk/go/v<V> as their publish jobs come online.
9596
#
9697
# Idempotent on re-run: if a tag already exists (partial-failure
9798
# scenario where publish-crate succeeded but publish-ffi failed,
@@ -119,6 +120,7 @@ jobs:
119120
TAGS=(
120121
"sqlrite-v$V"
121122
"sqlrite-ffi-v$V"
123+
"sqlrite-desktop-v$V"
122124
"v$V"
123125
)
124126
for tag in "${TAGS[@]}"; do
@@ -281,6 +283,123 @@ jobs:
281283
files: ${{ env.ASSET }}
282284
generate_release_notes: true
283285

286+
# ---------------------------------------------------------------------------
287+
# Step 3c: build the Tauri desktop app for each supported platform
288+
# and upload the installers to the `sqlrite-desktop-v<V>` GitHub
289+
# Release. (Phase 6e.)
290+
#
291+
# Matrix mirrors publish-ffi's — same three OS families, same
292+
# "aarch64 on macOS, x86_64 elsewhere" choice. The actual installer
293+
# formats per platform come from Tauri's bundler, not the matrix:
294+
# - ubuntu-22.04 → AppImage + .deb (x86_64)
295+
# - macos-latest → .dmg (aarch64)
296+
# - windows-latest → .msi (x86_64)
297+
#
298+
# ubuntu-22.04 (not ubuntu-latest) is deliberate: AppImage links
299+
# glibc at build time, so building on 22.04 (glibc 2.35) yields
300+
# an AppImage that runs on any distro with glibc ≥ 2.35 — which
301+
# covers everything shipped since 2022. Building on ubuntu-latest
302+
# (24.04, glibc 2.39) would produce an AppImage that refuses to
303+
# launch on Debian 12 / Ubuntu 22.04 and older.
304+
#
305+
# macOS universal (x86_64 + aarch64 lipo'd together) + Linux
306+
# aarch64 desktop are follow-ups — same MVP-simplicity reasoning
307+
# as publish-ffi. Apple Silicon is the majority of Mac downloads
308+
# and x86_64 Linux is the majority of Linux downloads, so this
309+
# covers 95%+ of users on day one.
310+
#
311+
# Installers ship **unsigned** — Phase 6.1 wires up Apple
312+
# Developer ID + Windows code-signing cert. Unsigned installers
313+
# trigger the expected "unidentified developer" / SmartScreen
314+
# warnings; the release body explains how to bypass them.
315+
publish-desktop:
316+
name: Publish desktop (${{ matrix.platform }})
317+
needs: [detect, tag-all]
318+
if: needs.detect.outputs.should_release == 'true'
319+
runs-on: ${{ matrix.os }}
320+
environment: release
321+
strategy:
322+
fail-fast: false
323+
matrix:
324+
include:
325+
- os: ubuntu-22.04
326+
platform: linux-x86_64
327+
- os: macos-latest
328+
platform: macos-aarch64
329+
- os: windows-latest
330+
platform: windows-x86_64
331+
steps:
332+
- uses: actions/checkout@v4
333+
334+
- uses: actions/setup-node@v4
335+
with:
336+
node-version: '20'
337+
cache: 'npm'
338+
cache-dependency-path: desktop/package-lock.json
339+
340+
- uses: dtolnay/rust-toolchain@stable
341+
342+
- uses: Swatinem/rust-cache@v2
343+
with:
344+
shared-key: publish-desktop-${{ matrix.platform }}
345+
workspaces: './ -> target'
346+
347+
# Linux-only: Tauri's webview backend is webkit2gtk, which
348+
# isn't preinstalled on GitHub runners. libayatana-appindicator
349+
# / librsvg2 / patchelf are the rest of the standard Tauri
350+
# Linux build kit. Matches the `desktop-build` job in ci.yml.
351+
- name: Install Tauri Linux deps
352+
if: matrix.os == 'ubuntu-22.04'
353+
run: |
354+
sudo apt-get update
355+
sudo apt-get install -y \
356+
libwebkit2gtk-4.1-dev \
357+
libayatana-appindicator3-dev \
358+
librsvg2-dev \
359+
patchelf
360+
361+
- name: npm ci
362+
working-directory: desktop
363+
run: npm ci
364+
365+
# Icons (icon.ico, icon.icns, size-specific PNGs for Linux,
366+
# mobile assets) are pre-generated in the repo via `npx tauri
367+
# icon src-tauri/icons/icon.png` and committed to
368+
# `desktop/src-tauri/icons/`. That keeps CI deterministic and
369+
# saves ~10s per matrix cell; the tradeoff is that anyone
370+
# changing `icon.png` needs to re-run `tauri icon` locally and
371+
# commit the regenerated assets (PR review catches this).
372+
373+
# tauri-action does: frontend build (via beforeBuildCommand) →
374+
# `cargo tauri build` → bundle installers per platform → upload
375+
# each installer to the target GitHub Release. It reads
376+
# tauri.conf.json for bundle config, so flipping `bundle.active`
377+
# from `false` to `true` there is what actually causes installers
378+
# to get produced. `tagName` is templated so the action doesn't
379+
# create its own tag — we already did that in `tag-all`.
380+
- name: Build + upload installers
381+
uses: tauri-apps/tauri-action@v0
382+
env:
383+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
384+
with:
385+
tagName: sqlrite-desktop-v${{ needs.detect.outputs.version }}
386+
releaseName: Desktop v${{ needs.detect.outputs.version }}
387+
releaseBody: |
388+
SQLRite desktop app — unsigned installers for Linux (AppImage + deb), macOS (dmg, aarch64), Windows (msi).
389+
390+
**⚠️ Unsigned installers**: macOS shows "SQLRite can't be opened because it is from an unidentified developer" — right-click → Open → Open to bypass. Windows SmartScreen blocks on first run — click "More info" → "Run anyway". Code signing lands in Phase 6.1.
391+
392+
See the umbrella release [v${{ needs.detect.outputs.version }}](../../releases/tag/v${{ needs.detect.outputs.version }}) for the full changelog.
393+
releaseDraft: false
394+
prerelease: false
395+
projectPath: desktop
396+
# tauri-action's default is to create the release if it
397+
# doesn't exist. Since we want the release to aggregate
398+
# artifacts across all three matrix jobs, the first job
399+
# to finish creates it; the other two upload additional
400+
# files to the same release. (action is idempotent on
401+
# this — it uses `tagName` as the identity key.)
402+
284403
# ---------------------------------------------------------------------------
285404
# Step 4: create the umbrella GitHub Release. Runs after all
286405
# publish-* jobs succeed. Uses GitHub's native auto-generated
@@ -289,7 +408,7 @@ jobs:
289408
# config if we add one later.
290409
finalize:
291410
name: Finalize umbrella release
292-
needs: [detect, publish-crate, publish-ffi]
411+
needs: [detect, publish-crate, publish-ffi, publish-desktop]
293412
if: needs.detect.outputs.should_release == 'true'
294413
runs-on: ubuntu-latest
295414
steps:
@@ -309,8 +428,9 @@ jobs:
309428
310429
- 🦀 [Rust engine](../../releases/tag/sqlrite-v${{ needs.detect.outputs.version }}) → [crates.io](https://crates.io/crates/sqlrite-engine/${{ needs.detect.outputs.version }})
311430
- 🔧 [C FFI](../../releases/tag/sqlrite-ffi-v${{ needs.detect.outputs.version }}) — prebuilt `libsqlrite_c` for Linux x86_64/aarch64, macOS aarch64, Windows x86_64
431+
- 🖥️ [Desktop](../../releases/tag/sqlrite-desktop-v${{ needs.detect.outputs.version }}) — unsigned installers for Linux (AppImage + deb), macOS (dmg aarch64), Windows (msi)
312432
313-
_Python / Node.js / WASM / Go / desktop SDKs land as their publish jobs come online (Phases 6e–6i)._
433+
_Python / Node.js / WASM / Go SDKs land as their publish jobs come online (Phases 6f–6i)._
314434
315435
---
316436
299 Bytes
Loading
665 Bytes
Loading

desktop/src-tauri/icons/64x64.png

160 Bytes
Loading

desktop/src-tauri/icons/icon.icns

12.4 KB
Binary file not shown.

desktop/src-tauri/icons/icon.ico

1.94 KB
Binary file not shown.

desktop/src-tauri/tauri.conf.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,17 @@
2626
}
2727
},
2828
"bundle": {
29-
"active": false,
29+
"active": true,
3030
"targets": "all",
31+
"category": "DeveloperTool",
32+
"shortDescription": "SQLRite — a small embeddable SQLite clone",
33+
"longDescription": "SQLRite is a small, embeddable SQLite-inspired database engine written in Rust. This desktop app provides a GUI for browsing and querying SQLRite databases.",
3134
"icon": [
32-
"icons/icon.png"
35+
"icons/32x32.png",
36+
"icons/128x128.png",
37+
"icons/128x128@2x.png",
38+
"icons/icon.icns",
39+
"icons/icon.ico"
3340
]
3441
}
3542
}

docs/roadmap.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,17 @@ Products whose publish jobs land in later phases (desktop, Python, Node.js, WASM
397397

398398
> **v0.1.1 canary retrospective** *(2026-04-22)* — first publish attempt failed on `cargo publish` with a 403 because the `sqlrite` crate name on crates.io is owned by an unrelated RAG-SQLite project. Renamed the package to `sqlrite-engine` (lib / bin names unchanged, so `use sqlrite::…` still works for consumers). Tags `sqlrite-v0.1.1` / `sqlrite-ffi-v0.1.1` / `v0.1.1` stay on main per the never-reuse-a-tag policy; the next canary cuts `v0.1.2` under the new crate name.
399399
400-
### Phase 6e — Desktop publish
400+
> **v0.1.2 canary success** *(2026-04-23)* — end-to-end pipeline validated. `sqlrite-engine 0.1.2` landed on crates.io; `sqlrite-v0.1.2` / `sqlrite-ffi-v0.1.2` / `v0.1.2` GitHub Releases all live. One hiccup: GitHub's squash-merge default title (`release: v0.1.2 (#18)`) didn't match `detect`'s anchored regex, so the auto-trigger skipped and we kicked `release.yml` via `workflow_dispatch` as a manual fallback. [PR #19](https://github.com/joaoh82/rust_sqlite/pull/19) fixes that by stripping `(#N)` before the regex test — future canaries auto-publish without the manual kick.
401401
402-
Adds `publish-desktop` job to `release.yml`. `tauri-action` builds for Linux (AppImage + deb), macOS (dmg universal), Windows (msi). Unsigned — signing is Phase 6.1.
402+
### ✅ Phase 6e — Desktop publish
403+
404+
Adds `publish-desktop` job to `release.yml`. [`tauri-apps/tauri-action@v0`](https://github.com/tauri-apps/tauri-action) builds for Linux (AppImage + deb, x86_64 on ubuntu-22.04 for broad glibc compat), macOS (dmg, aarch64 — matching the publish-ffi matrix), Windows (msi, x86_64). Unsigned — signing is Phase 6.1.
405+
406+
Icons are pre-generated via `npx tauri icon desktop/src-tauri/icons/icon.png` and committed to `desktop/src-tauri/icons/` (one source PNG → .icns + .ico + size-specific PNGs + mobile assets). That keeps CI deterministic and saves ~10s per matrix cell; the tradeoff is that changing `icon.png` requires re-running `tauri icon` locally and committing the regenerated assets.
407+
408+
Release assets land on the `sqlrite-desktop-vX.Y.Z` GitHub Release with a body that explains the unsigned-installer warnings (macOS Gatekeeper / Windows SmartScreen) and how to bypass them until Phase 6.1 lands.
409+
410+
Follow-ups: macOS universal (x86_64 + aarch64 lipo'd — adds one Rust target build + `lipo` step), Linux aarch64 AppImage (adds one matrix cell on `ubuntu-24.04-arm`).
403411

404412
### Phase 6f — Python SDK publish
405413

0 commit comments

Comments
 (0)