Skip to content

fix(bundler): order bundle members by canonical POSIX arcname (reproducible builds)#3658

Open
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/bundler-packager-deterministic-order
Open

fix(bundler): order bundle members by canonical POSIX arcname (reproducible builds)#3658
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/bundler-packager-deterministic-order

Conversation

@jawwad-ali

Copy link
Copy Markdown
Contributor

What

_collect_files returned sorted(collected) — i.e. pathlib.Path comparison order. That ordering is platform-dependent: on Windows PurePath compares case-folded with backslash separators, while on Linux/macOS it compares the case-preserving forward-slash string.

But the zip member names are the canonical POSIX arcnames (build_bundle: file_path.relative_to(bundle_dir).as_posix()), which are platform-independent. So member order was derived from a platform-dependent key while member names were canonical — the same bundle built on Windows vs Linux/macOS produced archives whose members were laid out in different order, i.e. not byte-for-byte identical across build hosts. That contradicts the packager's stated reproducible-build guarantee (fixed timestamps + canonical 0644/0755 modes; test_build_is_deterministic asserts "byte-for-byte reproducible").

Fix

Order by the same canonical POSIX-arcname key used to name the members:

return sorted(collected, key=lambda p: p.relative_to(bundle_dir).as_posix())

Tests

tests/unit/test_bundler_packager.py::test_member_order_is_platform_independent — builds a bundle with mixed-case sibling files and asserts archive.namelist() == sorted(archive.namelist()). Fails before the fix on Windows (Path order groups case differently: apple.txt sorts before Foo.txt); passes after. CI's windows-latest matrix exercises this. All existing packager tests (incl. test_build_is_deterministic) still pass. ruff clean.


AI-assisted: authored with Claude Code. Verified the arcname key matches build_bundle's naming, and confirmed fail-before on Windows / pass-after.

…ucible builds)

_collect_files returned sorted(collected), i.e. pathlib.Path order, which is
platform-dependent: on Windows PurePath compares case-folded with backslash
separators, whereas the zip member NAMES are the canonical POSIX arcnames
(build_bundle: file_path.relative_to(bundle_dir).as_posix()). So the same
bundle built on Windows vs Linux/macOS produced archives whose members were
laid out in different order — not byte-for-byte identical across build hosts,
contradicting the packager's reproducible-build guarantee (fixed timestamps +
canonical modes).

Order by the same canonical POSIX-arcname key used to name members, so member
order is host-independent.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jawwad-ali
jawwad-ali requested a review from mnriem as a code owner July 22, 2026 16:28
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