Back to logs
2026-03-20 releasebug-fixinfrastructure

First public release: three bugs, two platforms, one coffee button

v0.1.2 is the first release where the full pipeline works end-to-end: push a tag, GitHub Actions builds Linux and Windows installers in parallel, signs them, publishes a GitHub Release, uploads latest.json, and in-app update checking picks it up automatically. Getting there required fixing three separate bugs, each one silent enough that it had slipped through earlier testing.

Bug 1: The auto-updater manifest was never generated

The first release had all the right pieces: a signing keypair, the TAURI_SIGNING_PRIVATE_KEY GitHub secret, a tauri-action step configured to publish a release. But latest.json never appeared in the release assets.

The cause was a single missing line in tauri.conf.json. Tauri v2 requires "createUpdaterArtifacts": true in the bundle section before it will generate .sig signature files during the build. Without those signature files, tauri-action has nothing to sign and produces no manifest. The config option isn't mentioned prominently anywhere in the getting-started path. It lives in a note partway down the plugin documentation.

Once the config was added, the manual third job I had written to stitch together latest.json from GitHub Actions artifacts became unnecessary. tauri-action handles it automatically. That job was deleted.

Bug 2: Windows CI broke after a crate update

The Windows build was failing with a type mismatch in the focus monitor. The windows crate 0.58 changed the inner type of HWND from isize to *mut c_void, which broke a null-check written against the old type. The same update changed GetWindowTextW to take &mut [u16] directly instead of a raw pointer plus length. Both call sites needed updating.

Bug 3: The RPM crashed before the first window opened

Installing and running the RPM on Fedora/Nobara produced an immediate panic: tray icon error: Zero width not allowed. The app never reached the main window.

The tray icon setup tried two file paths at runtime: the Tauri resource directory and, as a fallback, the source tree path baked in at compile time via env!("CARGO_MANIFEST_DIR"). Both failed silently under the RPM install layout, and the final fallback was Image::new(&[], 0, 0). This is a valid call that creates a zero-width image. TrayIconBuilder then rejected it with a hard panic.

The fix was to stop doing runtime path lookups for this at all. The icon is now embedded directly in the binary via include_bytes! at compile time. It's always available regardless of where the binary is installed, and the fallback chain is gone.

The AppImage on NVIDIA + Wayland systems hits a separate crash in the NVIDIA EGL Wayland driver during WebKit initialization. This is a known incompatibility between the AppImage's bundled WebKitGTK and certain NVIDIA driver versions. The workaround is to run with WEBKIT_DISABLE_DMABUF_RENDERER=1, or to use the RPM/DEB package instead, which uses the system's WebKitGTK and doesn't have this problem.

Release automation

Getting the first release out surfaced how many manual steps the process had. A scripts/bump-version.sh script now handles the version increment across all three files that need it (tauri.conf.json, Cargo.toml, package.json) in one command. A docs/release-checklist.md documents the full sequence from "tests pass" to "verify the release artifacts" so nothing gets missed.