ci: build py3-none (build.sh) recipes on a single Python leg#86
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
flet-lib*recipes (libpq, libzbar, libmupdf, …) are native C libraries: a recipe with abuild.shroutes to forge'sSimplePackageBuilder, whose wheel tag is hardcodedpy3-none-<platform>— versus thecp3XX-cp3XXtag real C-extension recipes get fromPythonPackageBuilder.A
py3-nonewheel is byte-identical regardless of which Python built it. But the matrix fans every recipe across3.12,3.13,3.14, so each of these libs is built three times, producing three identical wheel filenames. Publishing is per-leg, so only the first upload lands and the other two are dismissed as duplicates — two wasted build legs perpy3-nonerecipe, every run.Change
Build
py3-nonerecipes on a single canonical leg (the first Python in the list, computed indetectand passed to the reusable workflow). Realcp3XXextensions are unaffected and still build on every leg.build-wheels.yml:detectcomputescanonical_python(first listed, normalizedX.Y) and passes it to the build job.build-wheels-version.yml: new optionalcanonical_pythoninput (default""= no gating);set-matrixdropsbuild.shrecipes on non-canonical legs (one::notice::per skip); ahas_jobsoutput +if:guard skip a leg whose matrix ends up empty (e.g. a change touching onlyflet-lib*recipes).The gate keys off
build.shpresence — the exact signal forge itself uses to pick the builder (src/forge/package.py:116), so CI can't disagree with the wheel tag.Effect
A PR touching one
flet-lib*recipe drops from 6 build jobs → 2 (frees a scarce macOS/iOS runner); a fullALLrun sheds ~80–90 jobs. Applies to every trigger (push, PR, dispatch).cp3XXextensions keep building on all three Pythons.Backward compatibility
canonical_pythonis optional with an empty default, so standalonebuild-wheels-version.ymldispatches and any cross-repo callers are unchanged (empty = no gating).Verification
Workflow dispatch (
flet-libpq:,lru-dict:):flet-libpqbuilt only on 3.12;lru-dicton all three. Annotations confirmed:Skip py3.13: flet-libpq — py3-none recipe, built only on py3.12.Tradeoff
The redundant builds were incidental fault-tolerance — a flaky leg was masked by another publishing the identical wheel. Now each
py3-nonewheel publishes from one leg, so a canonical-leg failure blocks that recipe's publish until a re-run. Low risk: wheels are byte-identical, failures are visible (run goes red), and a re-run republishes the same artifact.