Make Linux desktop release artifacts bit-for-bit reproducible
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
I rebuilt `desktop-v0.5.18` (`Buzz_0.5.18_amd64.AppImage` + `.deb`) following
`.github/workflows/release.yml` exactly: same digest-pinned `ubuntu:24.04` container, hermit
toolchain (rust 1.95.0 / node 24.15.0 / pnpm 11.4.0), CI workspace path `/__w/buzz/buzz`,
`cargo update --workspace`, appimagetool 1.9.1 + pinned type2 runtime, `fix-appimage.sh` repack.
Result: not bit-for-bit, but remarkably close — every bundled file reproduces exactly
**except the main `buzz-desktop` binary**. All six sidecars (`buzz`, `buzz-acp`, `buzz-agent`,
`buzz-backend-kubernetes`, `buzz-dev-mcp`, `git-credential-nostr`) are bit-identical.
Official vs rebuild:
- AppImage `d04ace73…` vs `ff163ec2…`; deb `7ac74a1c…` vs `f5cc9840…`
- Main binary: identical size (200,174,032). `.text`/`.data` **identical** — the compiled code
reproduces. Remaining diffs: `.note.gnu.build-id`; `.strtab`/`.symtab` ThinLTO anonymous
symbol hashes (`anon..NNN.llvm.`); ~19.5 KB in `.rodata` consisting of
`'sha256-…'` CSP inline-script hash strings (Tauri embeds per-build random material in its
injected init scripts, so the hashes churn every build).
- AppImage runtime segment: only the 16-byte `.digest_md5` differs (derived from payload).
- linuxdeploy picks the top-level `buzz-desktop.png` symlink target nondeterministically
(official: `32x32`, rebuild: `128x128`).
- deb: `md5sums` line ordering is nondeterministic; per-file md5s match except `buzz-desktop`.
tar/gzip metadata (mtimes) differ — no `SOURCE_DATE_EPOCH` anywhere in the pipeline.
Suggested fixes, roughly in impact order:
1. Export `SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)` in the release job (normalizes
squashfs/tar/gzip timestamps).
2. Chase the Tauri CSP-hash randomness upstream (tauri codegen inline-script generation) or
pin whatever seed feeds it — this plus build-id is the whole main-binary diff.
3. Deterministic icon symlink and sorted `md5sums`.
4. Document the rebuild procedure (container digest, workspace path, throwaway
`TAURI_SIGNING_PRIVATE_KEY` needed because `createUpdaterArtifacts` refuses to run unsigned)
so third parties can verify releases.
Contributor guide
Research direction
Start with .github/workflows/release.yml and fix-appimage.sh, then reproduce the release in the documented workspace and compare the AppImage, deb, and main buzz-desktop binary. Trace the Tauri-generated CSP hashes and build-id inputs, along with icon selection, md5sums ordering, and archive timestamps. Done means independently rebuilt Linux artifacts have identical hashes and contents.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, linux, rust, tauri
- Domain
- build-system, devops, release
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100