Skip to content

Bump recipes to their latest upstream versions#68

Merged
ndonkoHenri merged 32 commits into
mainfrom
bumps-recipes
Jun 8, 2026
Merged

Bump recipes to their latest upstream versions#68
ndonkoHenri merged 32 commits into
mainfrom
bumps-recipes

Conversation

@ndonkoHenri

Copy link
Copy Markdown

52 recipes bumped to latest stable (build_number reset to 1):

Details

  • aiohttp 3.9.5 → 3.14.0
  • argon2-cffi-bindings 21.2.0 → 25.1.0
  • bcrypt 4.2.0 → 5.0.0
  • bitarray 3.6.1 → 3.8.1
  • blis 1.0.0 → 1.3.3
  • brotli 1.1.0 → 1.2.0
  • cffi 1.17.1 → 2.0.0
  • contourpy 1.3.1 → 1.3.3
  • flet-libgdal 3.10.0 → 3.13.1
  • flet-libgeos 3.13.0 → 3.13.1
  • flet-libopaque 0.99.8 → 1.0.1
  • gdal 3.10.0 → 3.13.1
  • google-crc32c 1.6.0 → 1.8.0
  • greenlet 3.1.1 → 3.5.1
  • grpcio 1.67.1 → 1.81.0
  • jiter 0.8.2 → 0.15.0
  • jq 1.8.0 → 1.11.0
  • kiwisolver 1.4.7 → 1.5.0
  • lru-dict 1.3.0 → 1.4.1
  • lxml 6.1.0 → 6.1.1
  • markupsafe 2.1.5 → 3.0.3
  • matplotlib 3.10.0 → 3.10.9
  • msgpack 1.1.0 → 1.1.2
  • msgspec 0.18.6 → 0.21.1
  • numpy 2.2.2 → 2.4.6
  • opaque 0.2.0 → 1.0.0
  • opencv-python 4.10.0.84 → 4.12.0.88
  • pandas 2.2.3 → 3.0.3
  • pendulum 3.0.0 → 3.2.0
  • pillow 11.1.0 → 12.2.0
  • protobuf 5.28.3 → 7.35.0
  • pycryptodome 3.21.0 → 3.23.0
  • pycryptodomex 3.21.0 → 3.23.0
  • pyjnius 1.6.1 → 1.7.0
  • pymongo 4.10.1 → 4.17.0
  • pynacl 1.5.0 → 1.6.2
  • pyobjus 1.2.3 → 1.2.4
  • pyogrio 0.10.0 → 0.12.1
  • pyproj 3.7.0 → 3.7.2
  • pyyaml 6.0.2 → 6.0.3
  • regex 2024.11.6 → 2026.5.9
  • rpds-py 0.23.1 → 2026.5.1
  • ruamel.yaml.clib 0.2.12 → 0.2.15
  • shapely 2.0.6 → 2.1.2
  • sqlalchemy 2.0.36 → 2.0.50
  • tiktoken 0.9.0 → 0.13.0
  • time-machine 2.16.0 → 3.2.0
  • tokenizers 0.21.0 → 0.22.2
  • websockets 13.0.1 → 16.0
  • yarl 1.11.1 → 1.24.2
  • zope.interface 7.2 → 8.5
  • zstandard 0.23.0 → 0.25.0

Same-version consumer rebuilds (linked against new flet-libgdal, build_number bumped to outrank what's already on pypi.flet.dev per PEP 427 wheel selection):

  • fiona 1.10.1: build_number 10 → 11
  • rasterio 1.5.0: build_number 10 → 11

Patches:

  • New: recipes/flet-libgdal/patches/mobile.patch — guards GDAL 3.13's new unconditional find_package(Python) block behind BUILD_PYTHON_BINDINGS so it doesn't trip CMake 4.x's CMP0190 cross-compile policy.
  • Deleted (upstream resolved): recipes/numpy/patches/mobile-2.2.2.patch, recipes/pendulum/patches/mobile.patch.
  • Renamed: recipes/pillow/patches/setup-11.x.patchsetup-12.x.patch (rebased for the 12.x setup.py reorganization).

recipes/flet-libgdal/build.sh also gets-DBUILD_PYTHON_BINDINGS=OFF on the iOS branch (Android already had it) and -DGDAL_USE_OPENMP=OFF on both, because GDAL 3.13 newly probes OpenMP via gdal_check_package(OpenMP ... CAN_DISABLE) — FindOpenMP finds the host runner's libgomp during cross-compile and stamps DT_NEEDED libomp.so into libgdal.so, but Android's Python runtime doesn't ship libomp.so → consumers dlopen-fail at first import.

.github/workflows/build-wheels.yml gets a new prebuild_libs workflow_dispatch input — see next section.

Why prebuild_recipes

Bumping a flet-lib* recipe forces every consumer of that lib to be rebuilt against the new version (ABI change + pip's exact-version pin on host deps). The old loop was: publish flet-libgdal → wait for pypi.flet.dev → dispatch the 4 consumers against it. Three turns and no way to back out cleanly if the lib turned out to be broken.

prebuild_recipes="flet-libgdal:3.13.1" builds the lib first inside the same matrix runner, drops the wheel into dist/, and steers forge's host-dep pip resolution at it via PIP_FIND_LINKS=$GITHUB_WORKSPACE/dist. The consumer pip-resolves the freshly-built local wheel over whatever pypi.flet.dev still has published. One dispatch end-to-end.

Expected CI failures on this PR

The pull_request trigger fires the workflow but does not pass prebuild_recipes (that input is manual-dispatch only). So consumers pip-resolve their host deps against pypi.flet.dev, where the new flet-lib* versions aren't published yet — chicken and egg.

14 jobs (7 recipes × 2 archs) will fail with
ERROR: No matching distribution found for ...:

Recipe Missing dep (not yet on pypi.flet.dev)
pynacl 1.6.2 cffi>=2.0.0 (target ABI)
opaque 1.0.0 flet-libopaque 1.0.1
shapely 2.1.2 flet-libgeos 3.13.1
gdal 3.13.1 flet-libgdal 3.13.1
fiona 1.10.1 flet-libgdal 3.13.1
rasterio 1.5.0 flet-libgdal 3.13.1
pyogrio 0.12.1 flet-libgdal 3.13.1

These same 7 chains were already validated end-to-end on the prebuild_recipes manual-dispatch path. The PR's push-triggered runs simply can't exercise that path automatically. The four flet-lib* themselves (flet-libgdal 3.13.1, flet-libgeos 3.13.1, flet-libopaque 1.0.1, cffi 2.0.0) will all build and pass.

Post-merge recovery (2-pass dance):

  1. The merge-triggered push run publishes the four flet-lib* wheels successfully
  2. Wait ~1 min for gemfury to index the new versions
  3. Rerun failes jobs or Manually re-dispatch the consumers (no prebuild_recipes needed — their host deps are now resolvable on pypi.flet.dev):

recipes: bump 13 major-tier upstreams to latest PyPI

Major-level bumps (X in X.Y.Z) — semver allows breaking API/ABI
changes. Highest risk. Patches/mobile.patch are intentionally left
untouched: CI will surface every recipe whose patch no longer applies,
whose setup.py reorganized, or whose build system flipped. We iterate
from there.

Special notes per recipe (see audit summary):
  * cffi 1 → 2 is the keystone — bcrypt, argon2-cffi-bindings,
    pycryptodome (transitively via cffi-on-Android) all consume it.
  * opaque 0.2.0 → 1.0.0: upstream 1.0.0 tried to fix
    install_requires=("pysodium") but shipped a string-not-tuple. Our
    mobile.patch likely still needed; verify on first CI failure.
  * pillow 11 → 12: meson build system tweaks; the host-dep patches
    will need rework.
  * regex 2024.* → 2026.* and rpds-py 0.23 → 2026.5 are CalVer
    bumps — mechanically major but semantically just continuous
    progress.

Every touched recipe also has build.number reset to 1 (was 10).

  argon2-cffi-bindings  21.2.0     → 25.1.0
  bcrypt                4.2.0      → 5.0.0
  cffi                  1.17.1     → 2.0.0
  markupsafe            2.1.5      → 3.0.3
  opaque                0.2.0      → 1.0.0
  pandas                2.2.3      → 3.0.3
  pillow                11.1.0     → 12.2.0
  protobuf              5.28.3     → 7.35.0
  regex                 2024.11.6  → 2026.5.9    (CalVer)
  rpds-py               0.23.1     → 2026.5.1    (scheme switched to CalVer)
  time-machine          2.16.0     → 3.2.0
  websockets            13.0.1     → 16.0
  zope.interface        7.2        → 8.5

recipes: bump 27 minor-tier upstreams to latest PyPI

Minor-level bumps (Y in X.Y.Z) — semver allows new features but no
breaking changes. Most should build and test cleanly; expect occasional
patch refreshes if upstream renamed a setup.py entry point or moved a
header. Patches/mobile.patch are untouched; CI will surface what needs
refreshing.

Every touched recipe also has build.number reset to 1 (was 10).

  aiohttp        3.9.5     → 3.14.0
  bitarray       3.6.1     → 3.8.1
  blis           1.0.0     → 1.3.3
  brotli         1.1.0     → 1.2.0
  gdal           3.10.0    → 3.13.1
  google-crc32c  1.6.0     → 1.8.0
  greenlet       3.1.1     → 3.5.1
  grpcio         1.67.1    → 1.81.0
  jiter          0.8.2     → 0.15.0
  jq             1.8.0     → 1.11.0
  kiwisolver     1.4.7     → 1.5.0
  lru-dict       1.3.0     → 1.4.1
  msgspec        0.18.6    → 0.21.1
  numpy          2.2.2     → 2.4.6
  opencv-python  4.10.0.84 → 4.13.0.92
  pendulum       3.0.0     → 3.2.0
  pycryptodome   3.21.0    → 3.23.0
  pycryptodomex  3.21.0    → 3.23.0
  pyjnius        1.6.1     → 1.7.0     (Android-only)
  pymongo        4.10.1    → 4.17.0
  pynacl         1.5.0     → 1.6.2
  pyogrio        0.10.0    → 0.12.1
  shapely        2.0.6     → 2.1.2
  tiktoken       0.9.0     → 0.13.0
  tokenizers     0.21.0    → 0.23.1
  yarl           1.11.1    → 1.24.2
  zstandard      0.23.0    → 0.25.0

recipes: bump 9 patch-tier upstreams to latest PyPI

Patch-level bumps (Z in X.Y.Z) — semver promises these are bug-fix-only,
so risk is low and patches/mobile.patch should still apply cleanly. We
leave existing patches untouched for this commit and let CI surface any
regressions; if a patch needs a refresh, that's a follow-up.

Per the bump policy: every touched recipe also has build.number reset
to 1 (was 10 — from the 'Bump all recipe build numbers to 10 for
python-build vNext' wave).

  contourpy           1.3.1  → 1.3.3
  lxml                6.1.0  → 6.1.1   (Jinja `{% set version %}` source)
  matplotlib          3.10.0 → 3.10.9
  msgpack             1.1.0  → 1.1.2
  pyobjus             1.2.3  → 1.2.4   (iOS-only)
  pyproj              3.7.0  → 3.7.2
  pyyaml              6.0.2  → 6.0.3
  ruamel.yaml.clib    0.2.12 → 0.2.15
  sqlalchemy          2.0.36 → 2.0.50
YAML 1.1 parses bare 16.0 as a float, then forge build.py:867 tries
Path.cwd() / 16.0 and raises TypeError. Quoting forces a string. The
other recipes were already fine: most have three-part versions (which
YAML keeps as strings due to multiple dots), and the only other
two-part version on the branch (zope.interface 8.5) was already
quoted as 8.5 in single quotes.
markupsafe 3.0 renamed the C accelerator entry point from "escape"
to "_escape_inner" (the public markupsafe.escape() now dispatches to
it). The recipe-tester asserts callable(_speedups.escape), which
failed on 3.x with AttributeError. Probe whichever name the installed
version exposes so the test stays useful across version bumps.
Verified locally with markupsafe 3.0.3 → both tests pass.
opencv-python stopped publishing sdists from 4.13.0.90 onward — only
binary wheels for desktop platforms exist for 4.13+. forge's
get_pypi_source_urls() raises KeyError because there is no sdist URL
to fetch. 4.12.0.88 is the latest version that still ships an sdist,
so the recipe can build from source for our cross-targets.

Upstream API delta 4.10.0.84 -> 4.12.0.88 is just 2 minors; no
breaking surface for our use.
gdal Python wheels hard-require an exact major.minor match with the
libgdal C library (configure.ac: "Python bindings of GDAL X.Y.Z
require at least libgdal X.Y.Z"). Bumping the Python recipe to 3.13.1
needs flet-libgdal bumped too — and that cascades to fiona, rasterio,
pyogrio, which all currently pass on 3.10.0 and would all break in
the same way.

Net for this bulk-bump pass: leave gdal + flet-libgdal at 3.10.0,
keep the 4 currently-green recipes green, and revisit the libgdal
chain as a dedicated effort once flet-libgdal 3.13.x is published to
pypi.flet.dev (so downstream consumers can pull it transitively).

Reset build.number to 10 (the pre-bump value) so this commit
preserves equivalence with main for the gdal recipe.
pycryptodome 3.23.0 + pycryptodomex 3.23.0
  python_requires line gained ", !=3.6.*". Patch context updated +
  line numbers shifted 521 -> 523. Semantic change unchanged:
  install_requires=['cffi'].

opaque 1.0.0
  Upstream tried to fix the install_requires problem the recipe was
  patching for, but shipped install_requires = ("pysodium") -- string
  inside parens is not a tuple; setuptools treats it as a single
  string requirement which sometimes works but is brittle. Switched
  the patch from "insert install_requires line" to "rewrite the
  broken string-as-tuple into a proper list". Context also updated
  to match the LGPLv3+ license classifier the 1.0.0 release added.

pynacl 1.6.2
  Dropped the cosmetic blank-line hunk (no semantic effect); kept the
  cmdclass/distclass commenting hunk, with line numbers shifted from
  218 -> 197 because the test_requirements block above shrunk in
  1.6.x. Same setup.py outcome as before.

All four verified locally: patch -p1 against fresh sdist applies
cleanly with no rejects.
shapely 2.1.0 added the official GEOS_INCLUDE_PATH /
GEOS_LIBRARY_PATH env-var path in setup.py. When both are set,
setup.py skips the geos-config probe AND the version-compat check,
and links against geos_c directly. That replaces our 2.0.x-era
mobile.patch's by-hand-commenting of the geos-config block.

  * Drop recipes/shapely/patches/mobile.patch entirely.
  * Set GEOS_INCLUDE_PATH = {platlib}/opt/include and
    GEOS_LIBRARY_PATH = {platlib}/opt/lib in script_env.
  * Keep the iOS -undefined dynamic_lookup LDFLAGS so the C
    extension can defer libgeos -> libgeos_c static-cascade refs at
    link time (same fix pattern as recipes/pyogrio + recipes/fiona).
…ibs context

pillow 12.x removed the `self.add_imaging_libs = ""` line that lived
just below `initialize_options` in 11.x, so hunk 1's trailing context
no longer matched. Hunks 2 + 3 still fuzzed cleanly because the lines
they touch were stable.

Renamed setup-11.x.patch -> setup-12.x.patch and bumped the meta.yaml
Jinja selector to `version >= (12,0,0)`. (We were already at 12.2.0
on this branch; nobody downstream is consuming the renamed-away
11.x-only variant.) Hunk 1 line numbers shifted 355 -> 372; line-count
metadata also corrected (8/6 vs 9/7) since one removed line dropped.

Verified locally: patch -p1 against fresh pillow-12.2.0 sdist applies
all three hunks with no rejects.
pandas 3.0.3
  pandas 3.0 bumped its own build-system pin to meson-python>=0.17.1
  (we used to pin >=0.16.0), so hunk 1 of mobile.patch is now a
  no-op. Dropped it. The [tool.meson-python] meson="meson-wrapper.py"
  hunk + the meson-wrapper.py file are still needed for our
  cross-build (forces meson to invoke under the cross-Python so
  sysconfig probes hit the TARGET, not the BUILD host). Line numbers
  for the append-section hunk shifted 809 -> 833 because upstream
  grew the codespell ignore list.

pyobjus 1.2.4
  Heavy upstream cleanup: the old "iOS vs darwin platform-fork" in
  setup.py is gone (now always builds from pyobjus.pyx via Cython 3),
  and most of the Py2 leftovers in pyobjus_conversions.pxi were
  removed too (`type(arg) is long`, `<long>long(arg)`, etc.). Our
  mobile.patch shrunk from 9 hunks to 3:
    - keep _runtime.h ffi/ffi.h -> ffi.h
    - keep common.pxi ffi/ffi.h -> ffi.h (line 109 -> 110)
    - keep one remaining isinstance(arg, (str, unicode)) -> str hunk
      at line 428 (last Py2 isinstance check upstream missed)
  Dropped: 4 setup.py hunks (now redundant) + 2 conversions.pxi hunks
  (already done upstream).

Both verified locally: patch -p1 against fresh sdist applies cleanly.
…m fix)

blis 1.3.3
  - Major file restructure in upstream: bli_pthread.c's barrier impl
    moved from a #elif after bli_pthread_barrier_wait (line 594 in 1.0)
    to a standalone #if defined(__APPLE__) || defined(_MSC_VER) block
    near the top (line 322). Rewrote the hunk for the new location.
  - blis.h hunk dropped entirely: upstream now ships
    `#if defined(__APPLE__) || defined(__ANDROID__)` for the barrier
    typedefs at line 1540, so our patch is a no-op.
  - setup.py hunks 1-3 fuzz-matched cleanly at new line numbers;
    hunk 4 (-mios-version-min) regenerated with current offsets.

grpcio 1.81.0
  - Dropped the third_party/zlib/zutil.h fdopen-redefine hunk: the
    vendored zlib was updated and no longer contains the
    `#ifndef fdopen / #define fdopen(fd,mode) NULL` block at all.
    Our `#if !defined(__APPLE__)` wrapper is now unneeded.
  - setup.py hunks (CARES Android config, OPENSSL_ROOT_DIR, etc.)
    still apply cleanly.

pendulum 3.2.0
  - Patch DELETED entirely. Our patch was a 32-bit overflow fix in
    rust/src/helpers.rs (`usize/isize` arithmetic overflowing on
    armeabi-v7a/x86). Upstream 3.2 rewrote local_time() to use i64
    throughout — naturally 64-bit, no overflow. Our patch and the
    `patches:` line in meta.yaml are gone.

pyjnius 1.7.0
  - The MetaJavaClass.__new__ proxy block was refactored to use
    NewObjectArray + SetObjectArrayElement instead of malloc + direct
    indexing. Our patch's intent (redirect FindClass calls through
    PyJni_FindClass so they see Flet's app classloader) still
    applies — rewrote the failing hunk to match the new code shape
    (single SetObjectArrayElement(... PyJni_FindClass(...)) instead
    of two FindClass replacements). All other hunks fuzz-matched.

All four verified locally with patch -p1 against fresh sdists, no
rejects.
numpy 2.4.6
  Drop recipes/numpy/patches/mobile-2.2.2.patch entirely. The patch
  was a one-hunk tweak to vendored-meson's AppleDynamicLinker.
  get_std_shared_module_args (-bundle -> -dynamiclib for iOS shared
  modules). Numpy upstreamed this in 2.4.x: vendored-meson's
  AppleDynamicLinker now branches on `if self.system == 'ios': return
  ['-dynamiclib']` natively. The recipe's meta.yaml moves the
  `patches:` line inside the `version < (2, 0)` Jinja branch so the
  legacy 1.26.4 patch still applies if someone ever pins back, while
  2.x recipes build patch-free.

tokenizers 0.22.2
  Backed off from the bulk-bump's 0.23.1 target. tokenizers 0.23.1
  introduced a process-wide BPE cache generation counter as
  `static NEXT_CACHE_ID: AtomicU64` in src/models/bpe/model.rs.
  AtomicU64 isn't available on `arm-linux-androideabi` (armeabi-v7a)
  because ARMv7-A doesn't have native 64-bit atomic ops — the build
  fails with `error[E0432]: unresolved import
  std::sync::atomic::AtomicU64`. 0.22.2 is the latest stable release
  without this dep. Re-attempt 0.23+ once we carry a recipe-side
  patch swapping AtomicU64 for the portable-atomic crate, or after
  upstream gates the cache id on `cfg(target_has_atomic = "64")`.
Comment out the concurrency block so quick follow-up pushes during the
recipe-bump iteration each get their own full CI run (instead of older
runs getting killed mid-flight). Will restore once the bumps branch
settles.
blis 1.3.3
  Re-add the blis.h barrier-typedef hunk I incorrectly dropped last
  pass. Upstream did NOT extend the gate to include __ANDROID__
  (only kept __APPLE__); my earlier grep was on a fuzz-matched
  intermediate state, not the fresh sdist. Without this hunk Android
  falls into the typedef pthread_barrier_t bli_pthread_barrier_t
  branch -> bli_pthread.c then references barrier->mutex/cond/count
  /tripCount on the bionic native struct, which only has opaque
  internal members -> "no member named mutex in pthread_barrier_t".
  iOS happened to pass because Apples
pyobjus 1.2.4's setup.py added a hard RuntimeError when the
ios-deps-install/ directory is missing -- upstream's
.ci/build_ios_dependencies.sh produces it (their own libffi build).
Mobile-forge supplies libffi via the recipe's libffi host dep
(headers + libs under {platlib}/opt, surfaced through CFLAGS /
CPPFLAGS / LDFLAGS), so we don't want that check fatally aborting.

Replaces the iOS branch in setup.py with a minimal libraries.append
("objc") and a comment pointing at the rationale; lets forge's build
env handle libffi paths.

Verified locally: patch -p1 against fresh pyobjus-1.2.4 sdist applies
all 4 hunks (_runtime.h, common.pxi, pyobjus_conversions.pxi, setup.py)
with no rejects.
…disable brotli

opencv-python 4.12.0.88
  Android: the mobile.patch had a stray empty-file diff at the very
  top declaring a.diff (mode 100644, hash e69de29). patch choked on
  it in CI -- "1 out of 1 hunk FAILED -- saving rejects to file
  pyproject.toml.rej" was misleading; the actual choke was on the
  zero-byte a.diff block confusing patch's parser. Removed.

  iOS: opencv-python's setup.py runs its own dep probe that hard
  requires cmake>=3.5 on PATH. macOS runners pre-install cmake but
  forge's iOS cross-venv stripped it from the shimmed PATH. Add the
  pip-installable cmake package to requirements.build so it lands
  in the build venv's bin/.

pillow 12.2.0 (iOS link failure)
  Pillow 12 added brotli to the optional-feature list and links
  -lbrotlicommon -lbrotlidec whenever its headers are reachable.
  The iOS cross site-packages exposes brotli headers (via the python
  xcframework include tree), so feature.brotli sticks, but no
  matching static archive is in our link search path -> linker
  fails with "ld: library 'brotlicommon' not found". Force
  self.disable_brotli = True AFTER pillow's feature-detection loop
  in setup-12.x.patch's initialize_options hunk, so the detection
  result is overridden and brotli stays out of LIBS.

Verified locally: opencv-python patch applies all hunks with no
rejects; pillow patch still applies, with disable_brotli = True
landing right before the raqm/fribidi vendor loop.
…dep-chain dependency

These three pass at the BUILD step on the bump-target version but fail
at the recipe-tester RUNTIME, each for a different reason that is
out-of-scope for this bulk-bump branch:

opaque 1.0.0 -> 0.2.0
  Wheel builds, imports. test_registration_and_credential_roundtrip
  fails on both Android and iOS with
  "AttributeError: undefined symbol: opaque_FinalizeRequest_core".
  opaque 1.0 calls a libopaque C symbol that does NOT exist in the
  currently-shipping `flet-libopaque 0.99.8` host dep. Needs
  flet-libopaque bumped + republished in lockstep. Same dep-chain
  pattern we deferred for gdal.

pynacl 1.6.2 -> 1.5.0
  pip resolution fails at build with
  "ERROR: No matching distribution found for cffi>=2.0.0".
  pynacl 1.6 bumped its cffi runtime/build requirement from cffi>=1.4
  to cffi>=2.0. We bumped cffi to 2.0.0 in the bulk pass but the new
  cffi wheels are not yet published to pypi.flet.dev. Defer pynacl
  until cffi 2.0 is published, then reland.

shapely 2.1.2 -> 2.0.6 (iOS only — Android still passes 2.1.2)
  Android tests all green. iOS test fails at import time with
  "ImportError: dlopen ... symbol not found in flat namespace
  '__ZN4geos4geom23GeometryComponentFilter9filter_roEPKNS0_8GeometryE'"
  (geos::geom::GeometryComponentFilter::filter_ro). The C++ virtual
  method shapely 2.1's wheel was linked against doesn't exist in our
  flet-libgeos 3.13.0 build at runtime on iOS (Android picks it up
  via the shared libgeos.so; iOS uses the static archive and the
  resolver misses). Needs flet-libgeos rebuilt with the extra
  symbol, or a recipe-side patch. Restored the 2.0.6 mobile.patch
  (the env-var approach added for 2.1+ isn't needed at 2.0).

Recap: 12 bumps in this batch are still green (gdal, markupsafe,
pillow, pycryptodome/x, websockets, and friends). 3 deferred. After
the matching infra bumps land (flet-libopaque + flet-libgeos), and
once cffi 2.0 is published, these three can come back in one focused
follow-up.
opencv-python 4.12.0.88
  Drop the obsolete pyproject.toml hunk that tried to relax
  setuptools==59.2.0 to bare setuptools. Upstream 4.12 restructured
  that pin into two python_version-conditional lines:
    "setuptools==59.2.0; python_version<'3.12'",
    "setuptools<70.0.0; python_version>='3.12'",
  Our hunk's context no longer matched, breaking the whole patch on
  Android. Removed -- the python_version>='3.12' branch (setuptools
  <70) is fine for our build env.

  Add a 2nd Ptr-prefix hunk for pyopencv_videoio.hpp:120
  ("Ptr<cv::IStreamReader>" -> "cv::Ptr<cv::IStreamReader>"). The
  existing patch only prefixed the VideoCapture overload at line 26;
  iOS clang flagged the IStreamReader overload too with
  "reference to 'Ptr' is ambiguous".

pillow 12.2.0 iOS
  My earlier disable_brotli = True hook landed correctly but didn't
  actually keep brotli out of the link line, because pillow 12 has a
  HARDCODED iOS-specific libs.extend at setup.py line ~1001:
    if sys.platform == "ios":
        libs.extend(["z", "bz2", "brotlicommon", "brotlidec", "png"])
  That bypasses the feature.brotli check entirely. Added a 4th hunk
  to drop "brotlicommon", "brotlidec" from that list -- libs.extend
  becomes ["z", "bz2", "png"] on iOS. Android isn't affected (this
  block is iOS-only).

All verified locally with patch -p1 against fresh sdists; both
recipes' patches apply cleanly with no rejects.
The brotli removal exposed the next layer: pillow 12 hardcodes
`-lpng` on iOS for the _imagingft extension too, and our build
doesn't provide libpng either (pillow recipe comment notes
"PNG support is internal: libpng is not used"). The wheel link
fails with `ld: library png not found`. Trim png from
libs.extend so only [z, bz2] remain.

Android isn't affected (the block is iOS-only).
Adds a workflow_dispatch input `prebuild_libs` and a new `prebuild`
job that runs BEFORE the main `build` job. When the input is set,
each listed native-lib recipe (typically a `flet-lib*`) is built
first; its dist/*.whl is uploaded as an artifact named
`prebuild-<platform>-<recipe>-<run_id>-<run_attempt>`. The `build`
job then downloads every matching artifact at start, copies the
wheels into its own `dist/`, and exports
`PIP_FIND_LINKS=$GITHUB_WORKSPACE/dist` so forge's host-dep pip
resolution prefers the freshly-built wheels over whatever
pypi.flet.dev has published.

End-to-end chain-dep validation in a single dispatch — instead of
the current 3-step dance:

  1. publish flet-libgdal 3.13.1 to pypi.flet.dev
  2. wait
  3. dispatch gdal/fiona/rasterio/pyogrio against the new lib

becomes one shot:

  gh workflow run build-wheels.yml --ref <branch> \
    -f prebuild_libs="flet-libgdal:3.13.1" \
    -f packages="gdal:3.13.1,fiona:1.10.2,rasterio:1.5.1,pyogrio:0.12.1" \
    -f archs="android,iOS"

Once green, you know the chain works -- publish flet-libgdal for
real and re-dispatch the consumers without prebuild_libs.

Implementation shape:

* The `setup` job gains a second output, `prebuild_matrix`, computed
  the same way as the main matrix but over `prebuild_libs` instead
  of `packages`. Emits `{"include":[]}` when unset.

* The `prebuild` job is a stripped-down clone of `build` (checkout +
  free disk + setup uv + Setup Rust + NDK install + `forge <arch>
  <package>`), followed by an `actions/upload-artifact` step that
  uploads dist/*.whl. Skipped via `if:` when prebuild_libs is empty
  or the matrix is empty.

* The `build` job's `needs:` adds `prebuild`. Its `if:` allows
  `prebuild.result` to be 'skipped' (input unset) or 'success'
  (input set + all libs built); 'failure' propagates and the build
  job is skipped, since consuming a broken chain dep is doomed.

* A new "Seed dist/ from prebuild artifacts" step is added BEFORE
  "Build wheels". Uses `gh run download` with a per-platform pattern
  so iOS builds don't end up with Android wheels in their dist/
  (and vice versa). Runs only when `inputs.prebuild_libs != ''`.

* `PIP_FIND_LINKS=$GITHUB_WORKSPACE/dist` is added to the Build
  wheels step env. Harmless when dist/ is empty (forge's own output
  dir; pip just sees an empty directory listing).

No change to existing push / pull_request triggers — those don't
set prebuild_libs, so prebuild is always skipped and the build job
runs unchanged.
Re-apply the pynacl 1.6.2 bump that we deferred earlier (commit
48709e1). Going to dispatch this branch with prebuild_libs="cffi:2.0.0"
so the workflow builds cffi 2.0.0 wheels FIRST, seeds them into the
build job dist/, and pynacl 1.6.2 should then resolve cffi>=2.0.0 via
PIP_FIND_LINKS instead of failing at the pypi.flet.dev probe.

If green, that validates both: (a) prebuild_libs works end-to-end,
and (b) the cffi 2.0 chain is safe to publish.
Re-stage the opaque chain bump we deferred earlier (commit 48709e1).
The runtime test had failed with
"AttributeError: undefined symbol: opaque_FinalizeRequest_core" --
opaque 1.0.0's Python wrapper calls that symbol but flet-libopaque
0.99.8 (the host dep) was built from libopaque <= 0.99.x which doesn't
export it. Verified against stef/libopaque GitHub: tags v0.99.8/v0.99.10
contain zero occurrences of opaque_FinalizeRequest_core; v1.0.0/v1.0.1
contain 2 occurrences each.

* flet-libopaque: 0.99.8 -> 1.0.1, build_number reset to 1. Existing
  src/makefile patch applies cleanly to v1.0.1.
* opaque: 0.2.0 -> 1.0.0, build_number reset to 1, host dep updated
  to flet-libopaque 1.0.1. mobile.patch rewrites upstream 1.0.0's
  broken install_requires = ("pysodium") (string-in-parens, not a
  tuple) to a proper list install_requires=["pysodium"].

Dispatch shape:
  gh workflow run build-wheels.yml --ref ci/prebuild-libs-input \
    -f prebuild_libs="flet-libopaque:1.0.1" \
    -f packages="opaque:1.0.0" \
    -f archs="android,iOS"
…test

The gdal chain was the largest of the deferred bumps from the bulk-bump
pass: bumping the GDAL Python bindings to a new major.minor needs
flet-libgdal (the host C library) bumped to the matching version AND
fiona / rasterio / pyogrio all re-pinned in lockstep, since their
extension modules link against libgdal directly.

Bumps:
* flet-libgdal: 3.10.0 -> 3.13.1, build_number reset to 1. build.sh
  uses generic CMake flags (GDAL_BUILD_OPTIONAL_DRIVERS=OFF,
  OGR_BUILD_OPTIONAL_DRIVERS=OFF, GDAL_USE_*=OFF) that should remain
  compatible across the 3.10 -> 3.13 jump.
* gdal: 3.10.0 -> 3.13.1, build_number reset to 1, host dep updated
  to flet-libgdal 3.13.1, GDAL_VERSION script_env synced.
* fiona: kept at 1.10.1 (latest stable), host dep + GDAL_VERSION
  script_env updated to 3.13.1, build_number reset to 1.
* rasterio: kept at 1.5.0 (latest stable), host dep + GDAL_VERSION
  script_env updated to 3.13.1, build_number reset to 1.
* pyogrio: kept at 0.12.1 (latest stable), host dep + GDAL_VERSION
  script_env updated to 3.13.1, build_number bumped 1 -> 2.

Dispatch shape (validates the whole chain end-to-end without
round-tripping flet-libgdal through pypi.flet.dev first):
  gh workflow run build-wheels.yml --ref ci/prebuild-libs-input \
    -f prebuild_libs="flet-libgdal:3.13.1" \
    -f packages="gdal:3.13.1,fiona:1.10.1,rasterio:1.5.0,pyogrio:0.12.1" \
    -f archs="android,iOS"
…oad fix

Re-stage the shapely chain bump deferred in 48709e1 (commit message
explained the runtime failure). Issue and fix:

The defer commit reverted shapely 2.1.2 -> 2.0.6 (Android worked at
2.1; iOS dlopen failed at import with "symbol not found in flat
namespace '__ZN4geos4geom23GeometryComponentFilter9filter_roEPKNS0_8GeometryE'"
-- the C++ mangled name for `geos::geom::GeometryComponentFilter::filter_ro(const Geometry*)`).

Root cause is the static-link C++ vtable elision: shapely 2.1's C
extension subclasses GeometryComponentFilter and overrides the virtual
filter_ro(); the base-class vtable lives in libgeos.a's object file
but the linker only pulls object files that satisfy *direct* symbol
references -- vtables expected by C++ dispatch aren't included. At
dlopen, dyld eagerly resolves the flat namespace and aborts on the
missing vtable entry. Android picks the symbol up via shared
libgeos.so, so this only ever bit iOS.

Fix: add `-Wl,-force_load,{platlib}/opt/lib/libgeos.a` to shapely's
iOS LDFLAGS. force_load pulls every object out of libgeos.a -- the
base-class vtable comes along, dyld is satisfied. Kept the existing
`-undefined dynamic_lookup` for libgeos_c-side externals shapely.so
defers to dlopen.

This static-cascade pattern is the same family as fiona/pyogrio/rasterio,
but those only needed the dynamic_lookup half because their missing
symbols were from *external* deps of libgdal (proj/tiff/curl) -- not
C++ vtables internal to libgdal itself.

Bumps:
* flet-libgeos: 3.13.0 -> 3.14.1 (latest stable, build_number reset
  to 1). build.sh's generic CMake invocation should remain compatible.
* shapely: 2.0.6 -> 2.1.2 (latest stable, build_number reset to 1).
  Restored the 2.1 env-var cross-compile path (GEOS_INCLUDE_PATH /
  GEOS_LIBRARY_PATH) added by 49775ba, dropped the 2.0.x mobile.patch
  (no longer needed -- and `recipes/shapely/patches/` removed since
  it's now empty).

Dispatch shape:
  gh workflow run build-wheels.yml --ref ci/prebuild-libs-input \
    -f prebuild_libs="flet-libgeos:3.14.1" \
    -f packages="shapely:2.1.2" \
    -f archs="android,iOS"
The gdal chain dispatch (run 27070408877) failed at the prebuild step
because GDAL 3.13's CMakeLists.txt unconditionally calls
`find_package(Python 3.8 COMPONENTS Interpreter Development NumPy)`
at line 229 -- regardless of -DBUILD_PYTHON_BINDINGS=OFF, which our
build.sh already passes. Under CMake 4.x the search trips CMake policy
CMP0190:

  Python: When cross-compiling, Interpreter and/or Compiler components
  cannot be searched when CMAKE_CROSSCOMPILING_EMULATOR variable is not
  specified (see policy CMP0190).

This is a no-op block for our build -- we have BUILD_PYTHON_BINDINGS=OFF
and want zero Python detection -- so the cleanest fix is to wrap the
find_package(Python) block (and its Python_NumPy follow-up) in
`if (BUILD_PYTHON_BINDINGS OR NOT DEFINED BUILD_PYTHON_BINDINGS)`.

When mobile-forge passes -DBUILD_PYTHON_BINDINGS=OFF the variable is set
to a falsy value, the guard fails, and the whole Python detection is
skipped. For upstream users who don't define the cache variable, the
NOT DEFINED clause keeps default behavior intact.

Verified the patch applies cleanly to upstream GDAL v3.13.1 CMakeLists.txt
via `patch -p1 --dry-run`.
…pt.cpp)

GEOS 3.14.0 introduced a `CurrentThreadInterrupt::ThreadCallback`
mechanism in src/util/Interrupt.cpp that uses C++ `thread_local`
storage. iOS clang refuses this with:

  error: thread-local storage is not supported for the current target
  thread_local geos::util::CurrentThreadInterrupt::ThreadCallback* callback_thread = nullptr;

iOS theoretically supports TLS as of iOS 9.0+, but the iOS simulator
target (x86_64 13.0 in our build) hits a known clang/libc++ ABI gap
that rejects `thread_local` for static class members. Android builds
3.14.1 fine but iOS fails at 98% of the libgeos compile.

GEOS 3.13.1 (latest 3.13.x patch release) doesn't have the thread_local
addition -- src/util/Interrupt.cpp still uses plain `bool requested`
and `Callback* callback` globals. Pinning there gives us a small stable
bump (3.13.0 -> 3.13.1) without the iOS-breaking change.

The GeometryComponentFilter::filter_ro vtable that motivated the shapely
chain has been in libgeos.a since GEOS 3.0+ -- the original vtable
elision failure on iOS is fixed by shapely's new `-Wl,-force_load,libgeos.a`
LDFLAGS in 49f6...d635a19, not by the GEOS version bump itself.
The previous patch (d5919ae) wrapped GDAL CMakeLists.txt's Python
detection block in
`if (BUILD_PYTHON_BINDINGS OR NOT DEFINED BUILD_PYTHON_BINDINGS)`,
which fences off the find_package(Python) call only when the user
explicitly passes -DBUILD_PYTHON_BINDINGS=OFF. The condition is FALSE
both when undefined (the NOT DEFINED clause was the bug -- I wrote it
to be permissive for upstream non-mobile users, but our cross-compile
always wants the block off) and when explicitly OFF.

Android already passes -DBUILD_PYTHON_BINDINGS=OFF on line 31; iOS did
not. Add the matching flag to the iOS cmake invocation so the patched
condition evaluates FALSE and the block is fully skipped.

Verified by re-reading the run 27070846249 log: the find_package error
moved from CMakeLists.txt:229 (pre-patch) to CMakeLists.txt:235
(post-patch -- the line offset matches the 6 new lines my patch
inserted above). Block was still being entered because the iOS
build.sh never defined BUILD_PYTHON_BINDINGS at all.
Upstream gdal/setup.py reorganized between 3.10.0 (the prior recipe
version) and 3.13.1:

* `libraries = ['gdal']` moved from line 54 to line 57 (the file
  acquired an extra `gcore/multidim` include dir entry in the
  hardcoded `/home/runner/work/gdal/gdal/python_pkgs` block).
* `get_gdal_config()` moved from line 228 to line 242 (intervening
  build_ext-class refactors added a few setup-time methods).

Re-anchor both hunks to the new line numbers and replace the legacy
`/home/even/gdal/3.10/...` hardcoded path context with the new
`/home/runner/work/gdal/gdal/python_pkgs/...` path that the upstream
release build now bakes in. Hunk logic unchanged -- the GDAL_LIBS
env-var override and the per-option GDAL_<OPTION> env-var lookup
stay in place.

Verified by extracting the gdal-3.13.1.tar.gz sdist from PyPI,
git-initializing it, and running `patch -p1 --dry-run` against the
new patch: applies cleanly.
The Android consumer wheels (gdal, fiona, rasterio, pyogrio) all built
cleanly against the freshly prebuilt flet-libgdal 3.13.1 but failed
at recipe-tester runtime on the Android emulator with:

  ImportError: dlopen failed: library "libomp.so" not found

GDAL 3.13 added OpenMP-based parallelism in a handful of code paths
(checksum, JP2 codec, raster reprojection). cmake/helpers/CheckDependentLibraries.cmake:438
runs `gdal_check_package(OpenMP "Whether GDAL should use OpenMP"
COMPONENTS "C" CAN_DISABLE)`, which auto-enables OpenMP whenever
CMake's FindOpenMP succeeds. On the Linux runner cross-compiling
for Android, FindOpenMP discovers the host's libgomp, adds
`-fopenmp` to the link line, and stamps a DT_NEEDED libomp.so into
the resulting libgdal.so. Android's Python runtime doesn't ship
libomp.so, so dlopen aborts on the first import of any module
linked transitively through libgdal.so. iOS escaped because
FindOpenMP gave up earlier in the toolchain (no host libomp visible
to the iOS sysroot search), but the disable is symmetric defense
in depth on the iOS side too.

The CAN_DISABLE clause on the OpenMP gdal_check_package call means
`-DGDAL_USE_OPENMP=OFF` is the supported way to opt out. Same
pattern as the existing OPENSSL / CURL / EXPAT / LIBXML2 disables
we already pass on Android.

Symptom shown by gdal_test_chain dispatch 27071503295: all 4 Android
consumers fail at first `import` (ImportError on libomp.so missing
for fiona/rasterio/pyogrio; ModuleNotFoundError for `osgeo._gdal`
because Python masks the dlopen failure as a missing-module error
when the .so file is present but un-loadable). iOS consumer wheels
all passed.
Refactor 50ec338's two-job chain-dep staging into a single shell loop
inside the existing Build wheels step. Mechanically equivalent —
`prebuild_libs="flet-libgdal:3.13.1"` still builds the lib first, the
wheel still lands in dist/, PIP_FIND_LINKS still steers the consumer's
host-dep pip resolution at it -- but the workflow shrinks from 569
lines to 425 (−165, +21).

What goes away:
* setup job's `prebuild_matrix` output + the 50-line `set-prebuild-matrix`
  step that duplicated the main matrix's arch fan-out
* the entire `prebuild` job (75 lines: own runner setup, NDK install,
  forge invocation, artifact upload)
* the build job's `Seed dist/ from prebuild artifacts` step (20 lines:
  `gh run download` + copy into dist/)
* `build.needs: [setup, prebuild]` → `build.needs: setup`
* the `if: always() && needs.setup.result == 'success' &&
  (needs.prebuild.result == 'success' || skipped)` propagation gate

What replaces it (5 lines inside Build wheels):
  if [[ -n "${PREBUILD_LIBS:-}" ]]; then
    for lib in $(echo "$PREBUILD_LIBS" | tr ',' ' '); do
      forge "$FORGE_ARCH" "$lib"
    done
  fi

Trade-off vs. the prior two-job design: for a chain like gdal (one lib
+ 4 consumers) the lib now rebuilds inside every consumer-arch runner
— 4× per arch instead of 1× per arch. ~+60% runner-minutes on the
worst case. Wall-clock is unchanged (the prebuild was on the critical
path either way), and for the smaller chains (pynacl, opaque, shapely
— each one consumer) the cost is identical to before. Acceptable price
for the YAML being much easier to read and reason about, especially
the failure semantics (no more `needs:` + result-juggling), and the
artifact upload/download dance disappears entirely.

Existing push / pull_request triggers unaffected — they don't set
prebuild_libs, the `if` guard skips the loop, the consumer build runs
exactly as it did before 50ec338.
…tion

The gdal chain bump (flet-libgdal 3.10.0 -> 3.13.1) republishes
fiona and rasterio at the SAME upstream version (1.10.1, 1.5.0)
but linked against the new libgdal. PEP 427 wheel selection picks
the higher build_tag when (name, version) collide -- so the rebuild
must outrank what's currently on pypi.flet.dev (both at build 10),
or downstream installs silently keep the old libgdal-3.10-linked
wheel and the chain bump becomes invisible.

* fiona     1.10.1: build_number  1 -> 11 (must beat fiona-1.10.1-10)
* rasterio  1.5.0:  build_number  1 -> 11 (must beat rasterio-1.5.0-10)
* pyogrio   0.12.1: build_number  2 -> 1  (no collision since version
  changed from 0.10.0; bring in line with the branch's
  "version bump -> build_number = 1" convention)

Verified the published wheels via pip download against
https://pypi.flet.dev (android_24_x86_64, ios_13_0_arm64_iphoneos
both at build 10 for fiona / rasterio / pyogrio / gdal).
ndonkoHenri and others added 2 commits June 8, 2026 02:04
fix_wheel was unconditionally rewriting the WHEEL Tag with
`self.wheel_tag` (cp3X-cp3X-<platform>), discarding the tag maturin /
the upstream backend had emitted. For abi3 crates like cryptography
this turned `cp37-abi3-<platform>` into `cp312-cp312-<platform>` and
the produced wheel name followed, which was wrong on three counts:

- semantically incorrect: the inner _rust.abi3.so is stable-ABI;
- unnecessarily restrictive: pip refuses the wheel on cp313+;
- wasteful: forces per-Python-version rebuilds.

Now `fix_wheel` keeps the existing pythontag-abitag portion and
swaps only the platform component, falling back to self.wheel_tag
only when the upstream wheel didn't carry a Tag header. Restores
the cp3X-abi3-* wheels we shipped before commit 4cf1c1f.

Co-authored-by: Feodor Fitsner <feodor@appveyor.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates a large set of mobile-forge recipes to their latest stable upstream versions (generally resetting build.number back to 1), plus adds workflow/build-system tweaks to support rebuilding “consumer” wheels against freshly bumped flet-lib* host libraries within a single CI dispatch.

Changes:

  • Bump many Python package recipes to newer upstream versions and reset build numbers (with a few targeted rebuild-number bumps for GDAL consumers).
  • Add/adjust patches and build flags for newer upstream behavior (notably GDAL/OpenMP and Pillow/Shapely cross-compile behavior).
  • Update wheel tag normalization logic in src/forge/build.py and add a prebuild_recipes workflow input to seed locally built host-dep wheels into resolution.

Reviewed changes

Copilot reviewed 74 out of 74 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/forge/build.py Adjust wheel tag rewriting to preserve upstream Python/ABI tags while swapping platform tags.
.github/workflows/build-wheels.yml Add prebuild_recipes input and logic to build prerequisite recipes first and set PIP_FIND_LINKS to dist/.
recipes/aiohttp/meta.yaml Bump aiohttp version/build number.
recipes/argon2-cffi-bindings/meta.yaml Bump argon2-cffi-bindings version/build number.
recipes/bcrypt/meta.yaml Bump bcrypt version/build number.
recipes/bitarray/meta.yaml Bump bitarray version/build number.
recipes/blis/meta.yaml Bump blis version/build number.
recipes/blis/patches/mobile.patch Update mobile patch for blis (pthread barrier + build flag tweaks).
recipes/brotli/meta.yaml Bump Brotli version/build number.
recipes/cffi/meta.yaml Bump cffi version/build number.
recipes/contourpy/meta.yaml Bump contourpy version/build number.
recipes/fiona/meta.yaml Re-pin to new flet-libgdal and bump build number to outrank published wheel.
recipes/flet-libgdal/build.sh Disable OpenMP and ensure Python bindings are off for cross builds.
recipes/flet-libgdal/meta.yaml Bump flet-libgdal version/build number and add new patch.
recipes/flet-libgdal/patches/mobile.patch Guard GDAL’s find_package(Python ...) behind BUILD_PYTHON_BINDINGS.
recipes/flet-libgeos/meta.yaml Bump flet-libgeos version/build number and update source URL.
recipes/flet-libopaque/meta.yaml Bump flet-libopaque version/build number.
recipes/gdal/meta.yaml Re-pin to new flet-libgdal and bump GDAL Python bindings version/build number.
recipes/gdal/patches/config.patch Update GDAL config patch and allow overriding libraries via GDAL_LIBS.
recipes/google-crc32c/meta.yaml Bump google-crc32c version/build number.
recipes/greenlet/meta.yaml Bump greenlet version/build number.
recipes/grpcio/meta.yaml Bump grpcio version/build number; update iOS/mac lane C++ standard flags.
recipes/grpcio/patches/mobile.patch Drop an upstream-resolved patch hunk (zlib fdopen guard).
recipes/jiter/meta.yaml Bump jiter version/build number.
recipes/jq/meta.yaml Bump jq version/build number.
recipes/kiwisolver/meta.yaml Bump kiwisolver version/build number.
recipes/lru-dict/meta.yaml Bump lru-dict version/build number.
recipes/lxml/meta.yaml Bump lxml version/build number.
recipes/markupsafe/meta.yaml Bump MarkupSafe version/build number.
recipes/markupsafe/test_markupsafe.py Update test to handle MarkupSafe 3.x C accelerator symbol rename.
recipes/matplotlib/meta.yaml Bump matplotlib version/build number.
recipes/msgpack/meta.yaml Bump msgpack version/build number.
recipes/msgspec/meta.yaml Bump msgspec version/build number.
recipes/numpy/meta.yaml Bump numpy version/build number and adjust meson longdouble property condition.
recipes/numpy/patches/mobile-2.2.2.patch Remove obsolete numpy patch (upstream resolved).
recipes/opaque/meta.yaml Bump opaque version/build number; re-pin to new flet-libopaque and refine rationale comment.
recipes/opaque/patches/mobile.patch Fix opaque’s install_requires and update classifier.
recipes/opencv-python/meta.yaml Bump opencv-python version/build number; add cmake build dep.
recipes/opencv-python/patches/mobile.patch Refresh patch for new opencv-python sources (C++ API/type adjustments).
recipes/pandas/meta.yaml Bump pandas version/build number.
recipes/pandas/patches/mobile.patch Update pandas patch (codespell ignore list + wrapper context).
recipes/pendulum/meta.yaml Bump pendulum version/build number and remove now-unneeded patch application.
recipes/pendulum/patches/mobile.patch Remove obsolete pendulum patch (upstream resolved).
recipes/pillow/meta.yaml Bump Pillow version/build number and switch to setup-12.x.patch.
recipes/pillow/patches/setup-12.x.patch Rebase/setup patch for Pillow 12.x (disable platform guessing + brotli handling).
recipes/protobuf/meta.yaml Bump protobuf version/build number.
recipes/pycryptodome/meta.yaml Bump pycryptodome version/build number.
recipes/pycryptodome/patches/mobile.patch Adjust pycryptodome setup metadata and add runtime cffi requirement.
recipes/pycryptodomex/meta.yaml Bump pycryptodomex version/build number.
recipes/pycryptodomex/patches/mobile.patch Adjust pycryptodomex setup metadata and add runtime cffi requirement.
recipes/pyjnius/meta.yaml Bump pyjnius version/build number.
recipes/pyjnius/patches/mobile.patch Update pyjnius JNI class lookup calls for Android compatibility.
recipes/pymongo/meta.yaml Bump pymongo version/build number.
recipes/pynacl/meta.yaml Bump PyNaCl version/build number.
recipes/pynacl/patches/mobile.patch Refresh PyNaCl patch hunk positions / remove outdated setup metadata chunk.
recipes/pyobjus/meta.yaml Bump pyobjus version/build number.
recipes/pyobjus/patches/mobile.patch Update pyobjus patch for new upstream layout and iOS libffi handling.
recipes/pyogrio/meta.yaml Bump pyogrio version/build number; re-pin to new flet-libgdal.
recipes/pyproj/meta.yaml Bump pyproj version/build number.
recipes/pyyaml/meta.yaml Bump PyYAML version/build number.
recipes/rasterio/meta.yaml Re-pin to new flet-libgdal and bump build number to outrank published wheel.
recipes/regex/meta.yaml Bump regex version/build number.
recipes/rpds-py/meta.yaml Bump rpds-py version/build number.
recipes/ruamel.yaml.clib/meta.yaml Bump ruamel.yaml.clib version/build number.
recipes/shapely/meta.yaml Bump shapely version/build number; switch from patching to env-based cross-compile config and iOS link flags.
recipes/shapely/patches/mobile.patch Remove obsolete shapely patch (replaced by upstream-supported env vars).
recipes/sqlalchemy/meta.yaml Bump sqlalchemy version/build number.
recipes/tiktoken/meta.yaml Bump tiktoken version/build number.
recipes/time-machine/meta.yaml Bump time-machine version/build number.
recipes/tokenizers/meta.yaml Bump tokenizers version/build number with an upper cap rationale for 32-bit Android.
recipes/websockets/meta.yaml Bump websockets version/build number.
recipes/yarl/meta.yaml Bump yarl version/build number.
recipes/zope.interface/meta.yaml Bump zope.interface version/build number.
recipes/zstandard/meta.yaml Bump zstandard version/build number.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/forge/build.py
Comment on lines +666 to +668
upstream_tags = wheel_metadata.get_all("Tag", [])
del wheel_metadata["Tag"]
new_tags = []
Comment on lines +16 to +22
prebuild_recipes:
description: |
Comma-separated list of recipes (typically flet-lib*) to
build FIRST and seed into the matrix's dist/ for host-dep pip resolution
(e.g. flet-libgdal -> gdal).
required: false
default: ""
@FeodorFitsner

Copy link
Copy Markdown

lgtm, let's merge! 🚀

@ndonkoHenri ndonkoHenri merged commit e4e0d28 into main Jun 8, 2026
97 of 111 checks passed
@ndonkoHenri ndonkoHenri deleted the bumps-recipes branch June 8, 2026 07:38
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.

3 participants