From f6fc39d40ac430d3db60b38dbc867989bf07e30e Mon Sep 17 00:00:00 2001 From: Aric Camarata Date: Thu, 27 Aug 2026 13:55:31 -0400 Subject: [PATCH 1/3] ci(companion): surface WiX diagnostics and fix artifact paths that matched nothing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two problems in the same workflow, both about failures being invisible. 1. The windows leg dies with only: Error failed to bundle project: `failed to run ...\WixTools314\light.exe` and no WiX diagnostic. tauri-bundler runs candle/light through output_ok() (src/utils/mod.rs), which pipes stdout+stderr, re-emits every line via log::debug!, and on a non-zero exit throws that away in favour of a bare "failed to run ". At default verbosity those debug lines are dropped, so light.exe's LGHT diagnostics never reach the log. Build with --verbose so they do. 2. All three upload steps pointed at nclaw/desktop/src-tauri/target/release/bundle/..., which has never existed. desktop/src-tauri is a member of the root Cargo.toml workspace, so cargo writes bundles to /target/. The linux run bundled to .../nclaw/target/release/bundle/deb/ɳClaw_1.1.2_amd64.deb while the upload step looked under desktop/src-tauri/ and reported ##[warning]No files were found with the provided path ... No artifacts will be uploaded. upload-artifact only warns on an empty match and still exits 0, so both the linux and macos legs have been reporting success while producing nothing. Point them at the workspace target dir and set if-no-files-found: error, so a build that bundles nothing fails the job instead of passing silently. --- .github/workflows/companion-build.yml | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/companion-build.yml b/.github/workflows/companion-build.yml index 0ff4ef8..9e26705 100644 --- a/.github/workflows/companion-build.yml +++ b/.github/workflows/companion-build.yml @@ -67,32 +67,46 @@ jobs: # notarized macOS artifacts come from macos-release.yml, which supplies # the real certificate secrets, and desktop-macos.yml, which verifies # the result with `codesign --verify --deep --strict`. + # --verbose is deliberate. tauri-bundler runs candle.exe/light.exe via + # output_ok(), which pipes their stdout+stderr and re-emits each line at + # log::debug! level, then discards it on failure in favour of a bare + # "failed to run ". Without --verbose a WiX linker failure surfaces + # with no LGHT diagnostic at all, which is unactionable from CI logs. - name: Build Tauri app working-directory: nclaw/desktop/src-tauri - run: cargo tauri build + run: cargo tauri build --verbose + # Bundles land in the CARGO WORKSPACE target dir. desktop/src-tauri is a + # member of the root Cargo.toml workspace, so cargo writes to + # /target/, NOT /desktop/src-tauri/target/. The old paths + # matched nothing: upload-artifact only warns ("No files were found") + # and still exits 0, so the linux and macos legs reported success while + # uploading zero artifacts. - name: Upload Linux artifacts if: matrix.platform == 'ubuntu-latest' uses: actions/upload-artifact@v7 with: name: companion-${{ matrix.target }} + if-no-files-found: error path: | - nclaw/desktop/src-tauri/target/release/bundle/appimage/*.AppImage - nclaw/desktop/src-tauri/target/release/bundle/deb/*.deb + nclaw/target/release/bundle/appimage/*.AppImage + nclaw/target/release/bundle/deb/*.deb - name: Upload Windows artifacts if: matrix.platform == 'windows-latest' uses: actions/upload-artifact@v7 with: name: companion-${{ matrix.target }} + if-no-files-found: error path: | - nclaw/desktop/src-tauri/target/release/bundle/msi/*.msi - nclaw/desktop/src-tauri/target/release/bundle/nsis/*.exe + nclaw/target/release/bundle/msi/*.msi + nclaw/target/release/bundle/nsis/*.exe - name: Upload macOS artifacts if: matrix.platform == 'macos-latest' uses: actions/upload-artifact@v7 with: name: companion-${{ matrix.target }} + if-no-files-found: error path: | - nclaw/desktop/src-tauri/target/release/bundle/dmg/*.dmg + nclaw/target/release/bundle/dmg/*.dmg From 69c83bb66d8d695c466f64afae3fee3467780ae1 Mon Sep 17 00:00:00 2001 From: Aric Camarata Date: Thu, 27 Aug 2026 14:20:42 -0400 Subject: [PATCH 2/3] =?UTF-8?q?fix(ci):=20set=20the=20MSI=20database=20cod?= =?UTF-8?q?e=20page=20to=20UTF-8=20so=20"=C9=B3Claw"=20can=20be=20linked?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With --verbose surfacing WiX's diagnostics, the windows leg's real error turned out to be 18 copies of one problem, at every line of main.wxs that carries the product name: main.wxs(23) : error LGHT0311 : A string was provided with characters that are not available in the specified database code page '1252'. Either change these characters to ones that exist in the database's code page, or update the database's code page by modifying one of the following attributes: Product/@Codepage, Module/@Codepage, Patch/@Codepage, PatchCreation/@Codepage, or WixLocalization/@Codepage. productName is "ɳClaw". Its first character is U+0273 LATIN SMALL LETTER N WITH RETROFLEX HOOK, the eta the brand uses for display names. WiX defaults an MSI's database code page to the culture's ANSI code page, and tauri-bundler's languages.json maps en-US to asciiCode 1252. U+0273 has no representation in 1252, so light.exe refused every string containing it. Confirmed directly: "ɳClaw".encode("cp1252") raises UnicodeEncodeError. candle passed and only light failed because this is a database-encoding constraint applied at link time, not a syntax problem in the generated XML. It is also why the linux and macos legs are unaffected: deb, AppImage and app bundles are UTF-8 throughout, and both happily produced ɳClaw_1.1.2_amd64.deb and ɳClaw.app. Fixed by taking the last remedy the error itself lists. tauri's main.wxs sets no Product/@Codepage and exposes no config knob for one, but when wix.language carries a localePath, tauri-bundler reads that .wxl verbatim and only appends the default strings it cannot already find. So a minimal locale file can set WixLocalization/@Codepage=65001 and, for consistency, override TauriCodepage so Package/@SummaryCodepage stops reporting 1252 for a database that is no longer 1252. Deliberately not renaming the product to ASCII. "ɳClaw" is the documented display name, MSI ProductName and the Start Menu entry are display surfaces, and swapping the brand to satisfy a linker default would be a product decision, not a CI fix. --- desktop/src-tauri/tauri.conf.json | 9 +++++++++ desktop/src-tauri/wix/en-US.wxl | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 desktop/src-tauri/wix/en-US.wxl diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json index b0eb085..7dd5b8b 100644 --- a/desktop/src-tauri/tauri.conf.json +++ b/desktop/src-tauri/tauri.conf.json @@ -72,6 +72,15 @@ "macOS": { "minimumSystemVersion": "10.15", "entitlements": "entitlements.plist" + }, + "windows": { + "wix": { + "language": { + "en-US": { + "localePath": "wix/en-US.wxl" + } + } + } } } } diff --git a/desktop/src-tauri/wix/en-US.wxl b/desktop/src-tauri/wix/en-US.wxl new file mode 100644 index 0000000..b993987 --- /dev/null +++ b/desktop/src-tauri/wix/en-US.wxl @@ -0,0 +1,30 @@ + + + + 65001 + From 6d23fffb04945ca446f1782e938cd1ba678a8ce3 Mon Sep 17 00:00:00 2001 From: Aric Camarata Date: Thu, 27 Aug 2026 14:45:59 -0400 Subject: [PATCH 3/3] fix(ci): keep the MSI summary stream ANSI while the database stays UTF-8 Setting WixLocalization/@Codepage=65001 cleared all 18 LGHT0311 errors, so the database code page fix was right. But also overriding TauriCodepage pushed 65001 into Package/@SummaryCodepage, which has a stricter rule: main.wxs(23) : error LGHT0349 : The code page '65001' is invalid for summary information. You must specify an ANSI code page. The two code pages are independent and only the database one needed to change. Dropped the TauriCodepage override so tauri appends its 1252 default for the summary stream, and kept WixLocalization/@Codepage=65001 for the database. The mismatch is intentional and safe: tauri's Package element carries no product name, its only text attribute being Keywords="Installer", so nothing non-ASCII ever reaches the summary information stream. The product name lives in the database, which is now UTF-8 and can hold it. --- desktop/src-tauri/wix/en-US.wxl | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/desktop/src-tauri/wix/en-US.wxl b/desktop/src-tauri/wix/en-US.wxl index b993987..dea95c7 100644 --- a/desktop/src-tauri/wix/en-US.wxl +++ b/desktop/src-tauri/wix/en-US.wxl @@ -1,30 +1,37 @@ - 65001