Skip to content

fix(ci): unbreak Companion Desktop Builds on all three platforms - #54

Merged
acamarata merged 3 commits into
mainfrom
fix/companion-build-cargo-env
Aug 27, 2026
Merged

acamarata merged 3 commits into
mainfrom
fix/companion-build-cargo-env

Conversation

@acamarata

@acamarata acamarata commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Companion Desktop Builds got past the pnpm fix (#52) and then failed in Build Tauri app on all three legs, for three unrelated reasons. Each masked the next, so they only became visible one at a time.

# Leg(s) Failure
1 ubuntu + windows cc-rs handed a macOS Xcode path that cannot exist there
2 macos codesign given the literal string $APPLE_SIGNING_IDENTITY
3 windows icon.ico is a 1x1 PNG, not an icon

1 — a macOS Xcode path forced onto Linux and Windows

ubuntu  (job 98556102999)  ring v0.17.14
  error occurred in cc-rs: failed to find tool
  "/Applications/Xcode.app/.../clang": No such file or directory (os error 2)

windows (job 98556103506)  vswhom-sys v0.1.3
  error occurred in cc-rs: failed to find tool
  "/Applications/Xcode.app/.../clang++": The system cannot find the path specified. (os error 3)

desktop/src-tauri/.cargo/config.toml set CC/CXX in a bare [env] table:

[target.aarch64-apple-darwin]   # correctly target-scoped
linker = ".../XcodeDefault.xctoolchain/usr/bin/clang"

[env]                            # NOT target-scoped -- applies everywhere
CC  = ".../XcodeDefault.xctoolchain/usr/bin/clang"
CXX = ".../XcodeDefault.xctoolchain/usr/bin/clang++"

Cargo applies [env] to every invocation regardless of --target, and cc-rs prefers a target-suffixed override (CC_<triple>) only when one exists, otherwise falling back to bare CC. Both non-Apple legs got an Xcode path. The adjacent linker key is target-scoped, which is why the file looked platform-guarded but wasn't.

Fix: delete the file. The repo-root .cargo/config.toml already carries correctly scoped equivalents, which cargo finds by walking up from desktop/src-tauri:

[target.aarch64-apple-darwin]
linker = "/usr/bin/clang"
CC_aarch64_apple_darwin  = "/usr/bin/clang"
CXX_aarch64_apple_darwin = "/usr/bin/clang++"
AR_aarch64_apple_darwin  = "/usr/bin/ar"

macOS ARM stays configured; Linux and Windows fall back to their native toolchains. It also trades a hardcoded /Applications/Xcode.app path for /usr/bin/clang, the xcrun shim, which resolves through the active developer dir.

The file entered the tree in 3257e72, a docs commit for the model-registry contributor guide, with no other Rust build changes -- a local machine workaround committed by accident.

2 — an unexpandable $APPLE_SIGNING_IDENTITY literal

macOS compiled and bundled fine, then:

Signing with identity "$APPLE_SIGNING_IDENTITY"
$APPLE_SIGNING_IDENTITY: no identity found
Error failed to bundle project: failed codesign application

Tauri does no shell expansion on bundle.macOS.signingIdentity, so that literal string went to codesign as an identity name.

The value was never load-bearing. tauri-cli resolves it as (interface/rust.rs):

match env::var_os("APPLE_SIGNING_IDENTITY") {
  Some(v) => Some(v),                       // env wins
  None    => config.macos.signing_identity, // config only as fallback
}
Workflow Exports the env var? Effective identity
macos-release.yml yes, secrets.APPLE_TEAM_ID env wins -- config literal never used
desktop-macos.yml yes, secrets.APPLE_SIGNING_IDENTITY env wins -- config literal never used
companion-build.yml no falls back to the literal -> guaranteed failure

It was always shadowed in the workflows that actually sign, and only surfaced in the one that signs nothing, where it could do nothing but fail.

Fix: remove the field. tauri-bundler's sign::keychain() returns None when neither APPLE_CERTIFICATE nor an identity is present, and bundling proceeds unsigned. Release signing is untouched, because those workflows never read this field.

3 — icon.ico was a 1x1 PNG

With 1 fixed, windows got past cc-rs and hit the resource compiler:

resource.rc(26) : error RC2175 : resource file icons/icon.ico is not in 3.00 format
panicked at tauri-winres-0.3.6/src/lib.rs:543:
  Failed("RC.EXE failed to compile specified resource file")

icons/icon.ico was a 70-byte 1x1 PNG with a .ico extension -- it starts with the PNG signature, not the 00 00 01 00 ICONDIR magic. icon.icns is byte-identical (same md5), as are the three tray-*.png files: a set of stub assets committed as if real.

Fix: regenerate icon.ico from the brand artwork already in the repo (.github/wiki/brand/icons/icon-1k.png, 1024x1024) at 16/24/32/48/64/128/256 px. Entries are written as uncompressed DIB rather than PNG-compressed -- both are legal, but PNG-in-ICO is only understood by newer resource compilers, and the point is to stop depending on what a given RC.EXE accepts.

Only icon.ico is changed here, because only icon.ico blocks the build. icon.icns and the tray icons are still 1x1 placeholders; they make the macOS app and tray look blank but fail nothing, and replacing them is an asset decision, not a CI fix. Flagged separately.

On not weakening the build

No continue-on-error, no if: false, no dropped matrix leg, no loosened assertion. All three platforms still build and still fail the job on any compile or bundle regression.

Companion Desktop Builds is build verification, not distribution, so it now produces an unsigned macOS artifact instead of demanding a certificate it is never given. Signing correctness stays enforced where it belongs: macos-release.yml supplies the real certificate secrets and desktop-macos.yml asserts the result with codesign --verify --deep --strict. That split is documented inline so the placeholder does not get re-added.

Verification

Resolved cargo config on aarch64-apple-darwin, cargo -Z unstable-options config get env:

before                                            after
env.CC  = "/Applications/Xcode.app/.../clang"     env.AR_aarch64_apple_darwin  = "/usr/bin/ar"
env.CXX = "/Applications/Xcode.app/.../clang++"   env.CC_aarch64_apple_darwin  = "/usr/bin/clang"
env.CC_aarch64_apple_darwin  = "/usr/bin/clang"   env.CXX_aarch64_apple_darwin = "/usr/bin/clang++"
env.CXX_aarch64_apple_darwin = "/usr/bin/clang++"
  • cargo check in desktop/src-tauri on macOS aarch64: Finished, exit 0, zero cc-rs errors.
  • Run 33084976888 (fix 1 only) -- ubuntu-latest passed, isolating fix 1 as the complete Linux fix. macos still failed on 2, windows on 3.
  • Regenerated icon.ico parsed back: 7 entries, all DIB, 44,778 non-transparent pixels at 256px.
  • Causes 2 and 3 traced to tauri-cli / tauri-bundler / tauri-winres source and to the file's actual bytes, not inferred from symptoms.
  • Full 3-platform run dispatched against this branch. This workflow has no pull_request trigger, so it cannot run as a PR check -- dispatching against the branch is the only pre-merge verification available, same approach as fix(ci): give Companion Desktop Builds pnpm before it runs beforeBuildCommand #52.

… builds

Companion Desktop Builds failed on ubuntu-latest and windows-latest with
a macOS path, on machines that have no Xcode:

  ubuntu:  error occurred in cc-rs: failed to find tool
    "/Applications/Xcode.app/.../usr/bin/clang" (os error 2)
    -> failed to run custom build command for `ring v0.17.14`
  windows: error occurred in cc-rs: failed to find tool
    "/Applications/Xcode.app/.../usr/bin/clang++" (os error 3)
    -> vswhom-sys v0.1.3

desktop/src-tauri/.cargo/config.toml set CC and CXX in a bare [env]
table. Cargo applies [env] to every invocation regardless of --target,
and cc-rs only prefers a target-suffixed override (CC_<triple>) when one
exists, otherwise falling back to bare CC. So both non-Apple legs were
handed an Xcode toolchain path that cannot exist on those runners. Only
the sibling `linker` key was target-scoped, which is why this looked
platform-guarded but was not.

The repo root .cargo/config.toml already carries the correctly scoped
equivalents for this exact purpose:

  [target.aarch64-apple-darwin] linker = "/usr/bin/clang"
  CC_aarch64_apple_darwin  = "/usr/bin/clang"
  CXX_aarch64_apple_darwin = "/usr/bin/clang++"
  AR_aarch64_apple_darwin  = "/usr/bin/ar"

Cargo discovers it by walking up from desktop/src-tauri, so deleting the
override leaves macOS ARM fully configured while Linux and Windows fall
back to their native toolchains (gcc/cc, MSVC). It also drops a
hardcoded /Applications/Xcode.app path in favour of /usr/bin/clang, the
xcrun shim, which resolves through the active developer dir instead of
assuming one install location.

The file entered the tree in 3257e72, a docs commit for the model
registry contributor guide, alongside no other Rust build changes -- a
local machine workaround committed by accident rather than a deliberate
per-crate override.

Verified locally on aarch64-apple-darwin with
`cargo -Z unstable-options config get env`: before removal cargo
resolved both bare CC/CXX and the target-scoped pair; after removal only
the target-scoped pair remains.
…auri.conf.json

The macos-latest leg of Companion Desktop Builds compiled and bundled
cleanly, then died in codesign:

  Signing with identity "$APPLE_SIGNING_IDENTITY"
  $APPLE_SIGNING_IDENTITY: no identity found
  Error failed to bundle project: failed codesign application

tauri.conf.json carried `"signingIdentity": "$APPLE_SIGNING_IDENTITY"`.
Tauri performs no shell expansion on that field, so the literal string
`$APPLE_SIGNING_IDENTITY` was handed to codesign as an identity name.

The value was never load-bearing anywhere. tauri-cli resolves the
identity as (interface/rust.rs):

  match env::var_os("APPLE_SIGNING_IDENTITY") {
    Some(v) => Some(v),                      // env wins
    None    => config.macos.signing_identity // config only as fallback
  }

Both signing workflows already export that env var --
macos-release.yml sets it from secrets.APPLE_TEAM_ID and
desktop-macos.yml from secrets.APPLE_SIGNING_IDENTITY -- so the config
literal was always shadowed there and only ever surfaced in workflows
that sign nothing, where it could do nothing except fail.

Removing it lets tauri-bundler take its documented no-credentials path:
sign::keychain() returns None when neither APPLE_CERTIFICATE nor an
identity is present, and bundling proceeds unsigned. Release signing is
untouched, because those workflows never read this field.

Companion Desktop Builds is build verification, not distribution: it
still compiles every target and still fails the job on any compile or
bundle regression, it just no longer demands a certificate it is not
given. Signed and notarized artifacts remain the job of
macos-release.yml, with desktop-macos.yml asserting the result via
`codesign --verify --deep --strict`. Documented that split inline so the
next reader does not re-add the placeholder.
@acamarata acamarata changed the title fix(ci): stop forcing a macOS Xcode clang path onto Linux and Windows builds fix(ci): unbreak Companion Desktop Builds on all three platforms Aug 27, 2026
…n icon

With the cargo toolchain fix in place, the windows-latest leg got past
cc-rs and then failed in the Windows resource compiler:

  resource.rc(26) : error RC2175 : resource file
    desktop/src-tauri/icons/icon.ico is not in 3.00 format
  panicked at tauri-winres-0.3.6/src/lib.rs:543:
    Failed("RC.EXE failed to compile specified resource file")

desktop/src-tauri/icons/icon.ico was not an icon. It was a 70-byte 1x1
PNG that had simply been given a .ico extension -- its first bytes are
the PNG signature, not the 00 00 01 00 ICONDIR magic RC.EXE requires.
icon.icns is byte-for-byte the same placeholder (identical md5), as are
the three tray-*.png files, so this was a set of stub assets committed
as if they were real.

Regenerated icon.ico from the actual brand artwork already in the repo,
.github/wiki/brand/icons/icon-1k.png (1024x1024), at the seven sizes
Windows shells ask for: 16, 24, 32, 48, 64, 128 and 256 px.

Entries are written as uncompressed DIB rather than PNG-compressed.
Both are legal in an ICO, but PNG-in-ICO is only understood by newer
resource compilers, and the whole point here is to stop depending on
what a particular RC.EXE happens to accept. The cost is file size
(353 KB vs 99 KB), which is irrelevant for a resource linked once into
the binary.

Only icon.ico is changed, because only icon.ico blocks the build.
icon.icns and the tray icons are still 1x1 placeholders -- they produce
a blank-looking app and tray on macOS, but they do not fail any build,
and swapping them is an asset decision rather than a CI fix.
@acamarata
acamarata merged commit 03f642c into main Aug 27, 2026
16 of 17 checks passed
@acamarata
acamarata deleted the fix/companion-build-cargo-env branch August 27, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant