Skip to content

Editable install (uv pip install -e) kept previous build's fbuild/fbuild-daemon binaries after git pull #1742

Closed

Description

@zackees

Symptom

After git pull of a local fbuild checkout (/home/niteris/dev/fbuild) to a new main, uv pip install -e /home/niteris/dev/fbuild from the FastLED project venv printed Prepared 1 package in 3m 29s, but the venv still had fbuild / fbuild-daemon binaries from the previous day. They had hardlink count 3, which means they were linked from uv's cache. Those binaries lacked features that main had: deploy said "deployer for Espressif8266 not yet implemented" although #1729 was merged. The checkout's ci/bin/ held freshly built binaries. Running uv pip install -e ... --reinstall-package fbuild --refresh-package fbuild fixed it. uv was 0.13.5 on Linux.

Findings in ci/build_backend.py and pyproject.toml

  • The wheel contents come only from ci/bin/{fbuild,fbuild-daemon} and python/fbuild/_native.so. _stage_artifacts rebuilds them when any Cargo.toml, Cargo.lock, rust-toolchain.toml, crates/**/Cargo.toml or crates/**/*.rs file is newer than the staged file, so a pull that touches Rust sources does rebuild. That matches the 3m29s "Prepared" and the fresh ci/bin/. The backend did not pick stale staged binaries.
  • Zip entries use a fixed 1980-01-01 date, so the previous-day mtime on the installed files did not come from the wheel. It is the time uv unpacked an older archive.
  • [tool.uv] cache-keys covered pyproject, Cargo.toml/lock and crates/**, but not rust-toolchain.toml, ci/build_backend.py, or the git commit. The installed uv_cache.json shows "commit": null, so freshness depended only on the maximum mtime over the globs.
  • The most likely explanation: uv decided the already-installed editable dist satisfied the request, or reused a previously unpacked archive for the same name and version (both builds said 2.5.44), even though it had just rebuilt. Both builds carry the same version, so nothing in the dist metadata changes between them. I could not reproduce this without disturbing the shared editable install, so treat this part as a hypothesis.

Mitigation in #1741

Adds { git = { commit = true } }, rust-toolchain.toml and ci/build_backend.py to cache-keys, so a pull to a new HEAD always gives uv a new key.

Possible follow-ups

  1. Embed a build id (git HEAD plus a dirty flag) in the CLI and daemon, and show it in fbuild --version and fbuild daemon status. Same-version dev builds are otherwise indistinguishable; this also confused the daemon port issue in fix(cli): adopt same-version cache-root owner daemon; fail fast on a foreign owner #1739.
  2. If staleness still happens with the commit key, compare RECORD hashes in the installed dist-info against ci/bin/* and report it to uv upstream.

Activity

  1. zackees commented on Oct 28, 2026

    @zackees
    MemberAuthor

    Addressed on main — closing.

    • The mitigation from the report landed as PR build(uv): key editable installs on git HEAD, toolchain pin and backend #1741: [tool.uv] cache-keys now include { git = { commit = true } }, rust-toolchain.toml and ci/build_backend.py, so a git pull to a new HEAD is always a new key even when mtimes say otherwise. Verified in pyproject.toml on main.
    • Follow-up 1 landed as PR feat(version): stamp the git build id into fbuild and fbuild-daemon (#1742 follow-up 1) #1769: fbuild-core/build.rs stamps the commit (--short=12) and a dirty flag, exposed via fbuild_core::build_id and shown as fbuild --version = 2.5.47+git.<sha>[-dirty] and in the daemon Build: line. Same-version dev builds are now distinguishable — which is the part of this report that made a stale binary look like a missing feature.
    • Follow-up 2 (compare installed RECORD hashes against ci/bin/* and report to uv upstream) was not implemented; it stays available as a new issue if staleness is ever seen again with the commit key in place.

    — fbuild steward (automated)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions