fix(publish): S_IFREG on scripts + per-wheel verification + 2.1.21 bump#143
fix(publish): S_IFREG on scripts + per-wheel verification + 2.1.21 bump#143
Conversation
v2.1.20 shipped to PyPI with only 2 of 4 wheels (missing win_amd64 and manylinux_x86_64) because the upload step did not verify that every expected platform actually made it through. - download step now hard-fails on any missing artifact instead of warning - wheel-build step asserts a wheel was produced for every platform - upload step runs one `uv publish --check-url <pypi>/simple/ <whl>` per wheel concurrently, so per-file failures surface instead of being swallowed by a batched publish - post-upload verification queries PyPI and asserts every expected filename is present; hard-fails with bump instructions otherwise - new --upload-only flag retries uploads against wheels already in dist/wheels/ (--check-url makes it idempotent); this is how 2.1.20 was repaired without a version bump Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 28 minutes and 3 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 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 |
Summary
Three tightly-coupled publish-pipeline fixes forced out by 2.1.20 shipping with broken Linux/macOS wheels.
1.
fix(publish): set S_IFREG on wheel script entries2.1.20 shipped with
external_attr=0x01ed0000onfbuild/fbuild-daemonscript entries: mode bits correctly set to0o755but the file-type bit (S_IFREG,0o100000) was zero. pip's wheel installer callsstat.S_ISREG()on the upper 16 bits before applying script permissions; without IFREG, that test returns False, pip falls back to umask defaults (0o644), and the binary lands without+x:Windows
.exefiles don't need an exec bit, which is why 2.1.20 looked fine viauv tool install fbuild==2.1.20on Windows but was broken for every Linux/macOSpip install fbuild. This is also the persistent root cause behind #129 — #135's "preserve exec bit" fix set the mode but not the file-type bit, so #129 reproduced in 2.1.18, 2.1.19, 2.1.20.Reference:
uv,ruff, maturin-built wheels all ship script entries withexternal_attr=0x81ed0000(S_IFREG | 0o755), not0x01ed0000.Verified locally by rebuilding the Linux x86_64 wheel against the existing binary artifact: new
external_attr=0x81ed0000,IFREG=True, matchinguvbyte-for-byte in the file-type and mode bits.2.
fix(publish): fail loudly on partial releases(original scope of this PR)Concurrent per-wheel upload + pre/post verification +
--upload-onlyflag. 2.1.20 had already shipped with only 2 of 4 wheels on PyPI before the S_IFREG bug was found — this fixes the publish-script side of the damage. See commit message for detail.3.
chore: bump version to 2.1.212.1.20 is now stuck on PyPI — its filenames are taken, PyPI does not allow overwriting. A fresh version is the only way to ship the S_IFREG fix to end-users.
pyproject.toml,Cargo.toml(workspace),uv.lock,Cargo.lockall bumped to2.1.21.Post-merge publish plan
After this PR lands on
main:Then validate end-to-end on Linux by pointing FastLED's benchmark at
fbuild==2.1.21and confirming/bin/fbuildis executable.Test plan
external_attr=0x01ed0000,IFREG=False. Confirms the bug ships in every platform wheel.uv-0.11.7Linux wheel: script entries haveexternal_attr=0x81ed0000,IFREG=True.publish.py: script entries now showexternal_attr=0x81ed0000,IFREG=True../publish --upload-onlyalready battle-tested at the end of 2.1.20's partial-release cleanup../publishfrommainpost-merge exercises Steps 2-6 end-to-end against a fresh version.Permission deniedonfbuild==2.1.20; repoint to2.1.21and confirm the compile phase runs.🤖 Generated with Claude Code