Repository navigation
fix(desktop): keep one local bundle format from destroying the rest - #5410
Conversation
On Linux, bun run build:local asked for appimage,deb in ONE tauri invocation. When AppImage bundling failed (linuxdeploy missing a host dependency), the invocation died and the deb was never attempted — a contributor following the README got zero artifacts and an error that named a tool they never invoked (observed on a real GNOME desktop, devlog plan 260921 / 120_install_verification.md). Each format now builds in its own invocation, every format is attempted, and the summary reports each outcome beside the artifacts that did build; the exit code is non-zero when any requested format failed. A failing format is retried once with --verbose: at the bundler's default log level the error is a bare "failed to run linuxdeploy" with the tool's stderr discarded, and the verbose pass is the branch where those diagnostics reach the terminal. The release workflow builds its artifacts on its own runner image and is untouched.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
✅ Deterministic PR hygiene checks passed. |
|
Understand this PR’s impact Explore downstream dependencies and potential security impact with Blast Radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: lidge-jun/opencodex/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 10 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughThe desktop local build now processes each bundle format separately, retries failed formats with ChangesLocal bundle build orchestration
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant runBuildLocal
participant TauriCLI
participant ArtifactFilesystem
participant summarizeAttempts
runBuildLocal->>ArtifactFilesystem: snapshot existing artifacts
runBuildLocal->>TauriCLI: build one bundle format
TauriCLI-->>runBuildLocal: exit status
runBuildLocal->>TauriCLI: retry failed format with --verbose
TauriCLI-->>runBuildLocal: retry exit status
runBuildLocal->>ArtifactFilesystem: find new or modified artifacts
runBuildLocal->>summarizeAttempts: summarize format outcomes
summarizeAttempts-->>runBuildLocal: lines and aggregate exit code
Merge Risk: ⚪ Minimal · up to The local build command’s failure status and artifact reporting match the documented behavior, with no actionable merge-blocking issue identified. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c9d592e3b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Name what THIS run produced even when something failed: an error line at the end is | ||
| // the least visible place for artifacts that already built. | ||
| const produced = deps.listArtifacts().filter( | ||
| entry => !baseline.has(entry.path) || baseline.get(entry.path) !== entry.mtimeMs, |
There was a problem hiding this comment.
Stop using only mtime to identify produced bundles
On filesystems with coarse timestamp granularity, rebuilding an existing bundle within the same timestamp tick can leave mtimeMs unchanged, so this filter discards a successfully produced artifact and the new summary omits its path. This repository already documents container filesystems where write invalidation based on mtime is unreliable; report artifacts associated with successful format attempts, or use stronger creation/replacement evidence, rather than requiring the timestamp to change.
AGENTS.md reference: AGENTS.md:L313-L316
Useful? React with 👍 / 👎.
리뷰 · 우선순위 48 / 80리눅스에서 이제는 형식을 하나씩 따로 빌드합니다. 하나가 실패해도 나머지는 시도하고, 마지막에 형식마다 성공인지 실패인지 적습니다. 실패한 형식은 desktop/scripts/build-local.ts:122 - 이번 실행이 만든 파일인지는 수정 시각이 달라졌는지만 봅니다. 시각을 초 단위로만 적는 디스크에서는, 방금 다시 쓴 파일의 시각이 예전과 같아서 목록에서 빠집니다. 이 저장소는 컨테이너에서 같은 일이 난다고 이미 적어 두었습니다(AGENTS.md의 mtime 항목). macOS의 desktop/scripts/build-local.ts:114 - 실패 뒤에 desktop/scripts/build-local.ts:103 - 형식마다 메인테이너의 판단이 필요한 지점 실패한 형식마다 빌드를 한 번 더 돌릴 가치가 있는지, 로컬 빌드는 첫 실행부터 이유를 보여 줄지. 두 번째 실행이 성공하면 성공으로 바꿀지, 첫 실패를 유지할지. 나누는 대상을 리눅스 AppImage와 deb만으로 둘지, macOS와 Windows도 같이 둘지. dmg는 보통 app가 있어야 만듭니다. 둘을 따로 띄우는 시간이 아깝지 않은지는 tauri가 각 호출 안에서 app를 다시 만드는지에 달려 있고, 그 부분은 이 저장소 코드만으로는 확인하지 않았습니다. 너의 추천 형식별로 나누는 수정은 남기는 쪽이 맞습니다. 한 형식의 실패가 나머지를 막던 것이 이 패치의 이유입니다. 합치기 전에 두 곳은 고치는 편이 좋습니다. 나온 파일은 수정 시각만으로 고르지 말고, 이번에 성공한 형식의 결과만 적으면 됩니다. 실패한 형식은 빌드를 통째로 다시 하지 말고, 첫 실행에서 이유가 보이게 하거나, 다시 돌려서 성공하면 그 성공을 남기면 됩니다. 릴리스 워크플로는 지금처럼 건드리지 않으면 됩니다. 이 댓글은 grok-bot이 작성했습니다 |
Summary
On Linux,
bun run build:localasked forappimage,debin ONEtauri buildinvocation. When AppImage bundling fails — as it does on a stock GNOME workstation where linuxdeploy's own dependencies are missing — the invocation dies and the deb is never attempted: the contributor gets zero artifacts and an error that names a tool they never invoked (failed to run linuxdeploy, with linuxdeploy's diagnostics swallowed by the bundler). Observed on a real GNOME desktop; recorded in devlog/_plan/260921_app_runtime_ownership/120_install_verification.md.Each format now builds in its own invocation, every requested format is attempted, and the run ends with a per-format summary next to the artifacts that did build; the exit code is non-zero when any requested format failed. A failing format is retried once with
--verbose: at the bundler's default log level the error is a barefailed to run linuxdeploy, and the verbose pass is the branch where the tool's own stderr reaches the terminal, so the failure says why instead of naming a binary.The release workflow builds its artifacts on its own runner image and is untouched.
Verification
Local checks: NOT RUN (lane rule: no bun test, typecheck, builds, installs, or runtime execution — static review plus hosted CI only). The regression tests are written but intentionally unrun locally; what they pin:
a failing format does not destroy the formats that build— with AppImage scripted to fail and deb to succeed, both formats are attempted, the summary reportsappimage: FAILEDANDdeb: ok, the deb artifact path is printed, and the exit code is 1. Without the fix, the shared invocation never reaches the deb.a failing format is retried verbosely— exactly one--verboseinvocation, only for the failing format, so the bundler's debug-level stderr (linuxdeploy's own diagnostics) reaches the terminal.summarizeAttemptsdecides the exit code from per-format outcomes, and the fully-successful path keeps the existing "updater artifacts skipped" note.Mechanism evidence (static, read from the tauri-cli-v2.11.1 tag):
crates/tauri-cli/src/bundle.rsmaps verbosity 0 to bundler log level Error;crates/tauri-bundler/src/bundle/linux/appimage/linuxdeploy.rsruns the plain-output branch (barefailed to run linuxdeploy) only at Level::Error andoutput_ok()— which pipes the tool's stderr through debug logging — at anything higher;--verboseis a global clap arg (count), valid pre-subcommand.A gpt-5.6-sol audit of this diff passed with two minor findings (stale artifact reporting, boundary test coverage); both are folded.
Hosted CI at exact head 9c9d592: all requested jobs green. 38 check-runs: every requested job succeeded — gates (typecheck + scans), test 1/4-4/4 (including the new "local bundle builds" tests), desktop shell (fmt/clippy/test), macos 1/2 + 2/2, macos widget + bundle, docker smoke, storage policy, api usage, keyring ubuntu/windows/macos, linux-systemd, windows-schtasks, both macos-launchd, enforce-target, hygiene, label, react-doctor, resolve-pr. Skipped by event scope, not counted as green: windows shards (workflow_dispatch-gated by recorded decision), macos control, npm-global, structure gate, docs site build. No failures, no cancellations.
Checklist