Build release artifacts free of the Nix build environment - #205
Merged
Conversation
The generated package carried no Depends field at all, so installing it pulled in none of the GTK/WebKit stack the binary links against and the app died with a bare dynamic-linker error. Declare every direct DT_NEEDED library rather than leaning on WebKitGTK to drag the rest in, so a distro splitting or renaming one of them cannot silently break the package.
Both published Unix artifacts were unusable off the build machine and nothing caught it: the macOS app resolved libiconv through an absolute /nix/store path, and the .deb recorded a /nix/store ELF interpreter that cannot even be exec'd elsewhere. Inspect the artifact that is about to be published - load commands, ELF interpreter, RUNPATH, declared dependencies - and launch it, so the next leak fails the build instead of the download. Deliberately kept out of `build`: bundles built inside the Nix devShell legitimately reference the store and must stay usable locally.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR changes the release build pipeline to produce macOS/Linux/Windows artifacts using each platform’s native toolchain (instead of building inside the Nix devShell) and adds CI gates to prevent publishing bundles that embed /nix/store paths or fail to launch. It also improves Linux installability by declaring Debian shared-library dependencies and documents Linux installation requirements.
Changes:
- Add macOS/Linux bundle verification scripts and a
just verify-bundlegate, run in CI before uploading release artifacts. - Build release artifacts with a native toolchain (while keeping
check/testunder Nix) and install required native dependencies/tools in the workflow/action. - Declare
.debruntime dependencies viadesktop/Dioxus.tomland document Linux installation + distro floor inREADME.md.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
scripts/verify-macos-bundle.sh |
Verifies .app Mach-O load commands contain no /nix/store references and that the executable starts. |
scripts/verify-linux-bundle.sh |
Verifies .deb ELF metadata/strings contain no /nix/store, checks Depends, and smoke-runs the binary. |
README.md |
Adds Linux install instructions and supported distro floor; adds releases link. |
justfile |
Adds platform-scoped verify-bundle entrypoint. |
desktop/justfile |
Implements platform-specific verify-bundle recipes for .app and .deb artifacts. |
desktop/Dioxus.toml |
Declares direct shared-library dependencies for the Debian package. |
.github/workflows/build.yml |
Switches release builds to native toolchain, installs dioxus-cli, and runs just verify-bundle on Unix legs. |
.github/actions/setup-toolchain/action.yml |
Adds toolchain flavoring (nix vs native) and installs required native deps/tools for release builds. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Release bundles were built inside the Nix devShell, which bakes absolute /nix/store paths into the binary: the libiconv install name on macOS, the ELF interpreter and RUNPATH on Linux. No machine without that store can resolve them, so every published macOS and Linux build failed at launch. The native toolchain links against the libraries the user's machine actually has. Checks, tests and `nix build` keep running through Nix - only the artifacts that ship must be free of it. Closes #204
The Installation section covered only Homebrew and Nix, leaving the published .deb undocumented - including the glibc floor that follows from building it on Ubuntu 24.04.
lambdalisue
force-pushed
the
fix/nix-free-release-artifacts
branch
from
July 29, 2026 14:12
60751d0 to
a2f4fdd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
check,testandnix-checkkeep running through Nix, andflake.nixis untouched.just verify-bundle, backed byscripts/verify-macos-bundle.shandscripts/verify-linux-bundle.sh, and run it in CI on the artifact about to be published: no/nix/storein any load command, ELF interpreter, RUNPATH or embedded string; declaredDependsthat actually resolve; and the executable really starts..deb's direct shared-library dependencies inDioxus.toml, soapt install ./arto_*.debpulls in the GTK/WebKit stack instead of leaving the user with a bare dynamic-linker error.Why
Every published Unix artifact was unusable off the build machine, because
just buildran insidenix develop.On macOS the
libccrate's#[link(name = "iconv")]resolved through the devShell's-L /nix/store/…-libiconv/lib, so the app recorded an absolute store path as the install name and dyld killed it at launch (#204). With the Apple toolchain the same link resolves to/usr/lib/libiconv.2.dylib, which every Mac has — verified locally.Linux was worse: the shipped
arto_0.31.2_amd64.debrecords/nix/store/…-glibc-2.42-67/lib/ld-linux-x86-64.so.2as its ELF interpreter, so the binary cannot even be exec'd without that store, and the package declared noDependsat all.Post-processing the binaries would have patched over the symptom; building natively removes the cause, and the verification gate makes a regression fail the build instead of the download.
Test Plan
Verified locally (macOS):
-liconvto/usr/lib/libiconv.2.dylib.appand accepts one whose only libiconv reference is the system copy (launch andcodesign --verify --deep --strictboth pass)arto_0.31.2_amd64.deb, reporting both the/nix/storeinterpreter and the missingDependsDependsparsing handlesa | balternatives and rejects a typo'd package namejust fmt check testNeeds a real CI run (cannot be exercised from macOS):
.debpasses verification.apppasses verificationA re-release is required to get fixed binaries to users; the published 0.31.2 artifacts stay broken.
Closes #204