|
47 | 47 | # bit-exact-validated on every merge — without paying LTO's ~2-3x |
48 | 48 | # build cost on PRs. Separate ccache namespace + artifact prefix |
49 | 49 | # (…-lto-…) so they never perturb the fast PR build or its seed. |
| 50 | +# build-legacy-{linux,windows,macos} : the cp310 + cp311 version-specific |
| 51 | +# (non-abi3) wheels. 3.10/3.11 cannot be abi3 (stable-ABI member |
| 52 | +# constants are 3.12+), so they ship as six per-version wheels across |
| 53 | +# the three desktop OSes. RELEASE-ONLY: built only when a Release is |
| 54 | +# published (where `publish` ships them), so they add nothing to |
| 55 | +# per-merge CI cost. FVTK_ABI3=0 selects the legacy path. |
50 | 56 | # publish : RELEASE-ONLY (if: github.event_name == 'release'). Uploads the |
51 | 57 | # SHIPPED wheels to PyPI via trusted publishing (OIDC, no stored |
52 | | -# token) — the LTO Linux wheel (build-lto) plus the optimized macOS + |
53 | | -# Windows wheels (build-other-os) — gated on the LTO bit-exact + |
54 | | -# pixel-exact legs being green. A final step then attaches those same |
55 | | -# wheels to the GitHub Release (gh release upload) so every wheel is |
56 | | -# downloadable from the Release page too, not only PyPI. Wheels-only |
57 | | -# (fvtk_backend has no sdist). |
| 58 | +# token) — the four abi3 wheels (LTO Linux x86_64 + aarch64 + macOS + |
| 59 | +# Windows) PLUS the six legacy cp310/cp311 wheels — gated on the LTO |
| 60 | +# bit-exact + pixel-exact legs and the legacy legs being green. A final |
| 61 | +# step then attaches those same ten wheels to the GitHub Release (gh |
| 62 | +# release upload) so every wheel is downloadable from the Release page |
| 63 | +# too, not only PyPI. Wheels-only (fvtk_backend has no sdist). |
58 | 64 | name: CI |
59 | 65 |
|
60 | 66 | on: |
@@ -616,16 +622,157 @@ jobs: |
616 | 622 | path: wheelhouse/*.whl |
617 | 623 | if-no-files-found: error |
618 | 624 |
|
| 625 | + # === Legacy version-specific wheels (cp310 + cp311) ======================== |
| 626 | + # 3.10/3.11 CANNOT be abi3: PyMemberDef + the Py_T_*/Py_READONLY member |
| 627 | + # constants the heap-type wrappers emit only entered the stable ABI in 3.12 |
| 628 | + # (gh-93274). So they ship as version-specific (non-abi3) wheels — six in all: |
| 629 | + # cp310 + cp311 x {Linux, Windows, macOS}. The backend emits the legacy static |
| 630 | + # per-version wheel automatically when the build interpreter is < 3.12 or |
| 631 | + # FVTK_ABI3=0 (set belt-and-suspenders below), so there is NO new build logic. |
| 632 | + # |
| 633 | + # RELEASE-ONLY: these build only when a Release is published — where `publish` |
| 634 | + # collects their artifacts and ships them to PyPI + the Release alongside the four |
| 635 | + # abi3 wheels. They are deliberately kept off push-to-main / PRs / workflow_dispatch |
| 636 | + # / merge_group so they add nothing to per-merge CI cost (validated at release |
| 637 | + # time; the cibuildwheel smoke import per leg is the validation, not a numeric gate). |
| 638 | + build-legacy-linux: |
| 639 | + name: build legacy linux (manylinux2014, cp310+cp311) |
| 640 | + # RELEASE-ONLY: the legacy cp310/cp311 wheels build only when a Release is |
| 641 | + # published (where `publish` ships them). Kept off push-to-main / PRs / dispatch |
| 642 | + # so they never add to per-merge CI cost; they are validated at release time. |
| 643 | + if: github.event_name == 'release' |
| 644 | + # Two non-abi3 cp legs + LTO link is the heaviest build; generous cap, still |
| 645 | + # well below the 360-min default so a hung leg can't drain paid runners. |
| 646 | + runs-on: ${{ vars.FVTK_RUNNER_LINUX || 'ubuntu-latest' }} |
| 647 | + timeout-minutes: 120 |
| 648 | + steps: |
| 649 | + - uses: actions/checkout@v5 |
| 650 | + with: |
| 651 | + fetch-depth: 0 # VTK derives its version from full history |
| 652 | + - name: Build wheels + offscreen smoke (cibuildwheel) |
| 653 | + uses: pypa/cibuildwheel@v3.1.4 |
| 654 | + env: |
| 655 | + # Version-specific wheels for 3.10 + 3.11 (each builds + tests on its own |
| 656 | + # interpreter; no abi3 dedup). musllinux skipped (Alpine not a target). |
| 657 | + CIBW_BUILD: "cp310-* cp311-*" |
| 658 | + CIBW_SKIP: "*-musllinux_*" |
| 659 | + # Broader baseline than the shipped abi3 wheel (manylinux_2_28): |
| 660 | + # manylinux2014 == CentOS 7 == glibc 2.17, matching stock vtk's wheels. |
| 661 | + CIBW_MANYLINUX_X86_64_IMAGE: "manylinux2014" |
| 662 | + CIBW_ARCHS_LINUX: "x86_64" |
| 663 | + # OVERRIDE the pyproject before-all (AlmaLinux-8/dnf specific, installs |
| 664 | + # mold+lld that do NOT exist on CentOS 7). On el7 we use yum, drop |
| 665 | + # mold/lld, and rely on the gold linker (FVTK_FAST_LINKER below). EPEL is |
| 666 | + # enabled first for xvfb + a couple of mesa devel packages. |
| 667 | + CIBW_BEFORE_ALL_LINUX: >- |
| 668 | + yum install -y epel-release && |
| 669 | + yum install -y |
| 670 | + mesa-libGL-devel mesa-libEGL-devel mesa-libOSMesa-devel |
| 671 | + mesa-libGLU-devel libglvnd-devel |
| 672 | + libX11-devel libXcursor-devel libXt-devel libXext-devel |
| 673 | + mesa-dri-drivers xorg-x11-server-Xvfb ccache git && |
| 674 | + mkdir -p /ccache && chmod 0777 /ccache |
| 675 | + CIBW_BEFORE_BUILD_LINUX: "{project}/ci/cibw/before-build.sh" |
| 676 | + # Toolchain accommodations for CentOS 7 / GCC 10.2.1: FVTK_ABI3=0 forces |
| 677 | + # the legacy per-version path; gold linker (mold absent on el7); LTO + -O3 |
| 678 | + # kept (GCC 10 OK); the GCC>=12 unity/array-split levers auto-disable. |
| 679 | + CIBW_ENVIRONMENT_LINUX: >- |
| 680 | + FVTK_ABI3=0 |
| 681 | + FVTK_FAST_LINKER=gold |
| 682 | + CCACHE_DIR=/ccache |
| 683 | + CMAKE_C_COMPILER_LAUNCHER=ccache |
| 684 | + CMAKE_CXX_COMPILER_LAUNCHER=ccache |
| 685 | + CCACHE_MAXSIZE=30G |
| 686 | + # Default repair stamps manylinux_2_28; legacy wheels are manylinux2014. |
| 687 | + CIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel repair --plat manylinux2014_x86_64 -w {dest_dir} {wheel}" |
| 688 | + - uses: actions/upload-artifact@v4 |
| 689 | + with: |
| 690 | + name: fvtk-wheels-legacy-linux |
| 691 | + path: wheelhouse/*.whl |
| 692 | + if-no-files-found: error |
| 693 | + |
| 694 | + build-legacy-windows: |
| 695 | + name: build legacy windows (cp310+cp311) |
| 696 | + # RELEASE-ONLY: the legacy cp310/cp311 wheels build only when a Release is |
| 697 | + # published (where `publish` ships them). Kept off push-to-main / PRs / dispatch |
| 698 | + # so they never add to per-merge CI cost; they are validated at release time. |
| 699 | + if: github.event_name == 'release' |
| 700 | + runs-on: ${{ vars.FVTK_RUNNER_WINDOWS || 'windows-latest' }} |
| 701 | + timeout-minutes: 120 |
| 702 | + steps: |
| 703 | + - uses: actions/checkout@v5 |
| 704 | + with: |
| 705 | + fetch-depth: 0 |
| 706 | + # Ninja does NOT auto-run vcvars; ci/cmake/windows.cmake pins cl, so cl must |
| 707 | + # be discoverable (same as the abi3 Windows leg). |
| 708 | + - name: Set up MSVC (vcvars) for the Ninja build |
| 709 | + uses: ilammy/msvc-dev-cmd@v1 |
| 710 | + with: |
| 711 | + arch: x64 |
| 712 | + - name: Build wheels + smoke (cibuildwheel) |
| 713 | + uses: pypa/cibuildwheel@v3.1.4 |
| 714 | + env: |
| 715 | + CIBW_BUILD: "cp310-* cp311-*" |
| 716 | + # CIBW_ENVIRONMENT REPLACES the pyproject [tool.cibuildwheel.windows. |
| 717 | + # environment] table, so re-declare the Windows build vars: the MSVC |
| 718 | + # init-cache (link-closure restore for trimmed render classes), the MSVC |
| 719 | + # toolchain gate, and FVTK_ABI3=0 for the legacy per-version path. |
| 720 | + CIBW_ENVIRONMENT: "FVTK_ABI3=0 FVTK_CMAKE_INIT=ci/cmake/windows.cmake FVTK_FORCE_MSVC=ON" |
| 721 | + - uses: actions/upload-artifact@v4 |
| 722 | + with: |
| 723 | + name: fvtk-wheels-legacy-windows |
| 724 | + path: wheelhouse/*.whl |
| 725 | + if-no-files-found: error |
| 726 | + |
| 727 | + build-legacy-macos: |
| 728 | + name: build legacy macos (cp310+cp311) |
| 729 | + # RELEASE-ONLY: the legacy cp310/cp311 wheels build only when a Release is |
| 730 | + # published (where `publish` ships them). Kept off push-to-main / PRs / dispatch |
| 731 | + # so they never add to per-merge CI cost; they are validated at release time. |
| 732 | + if: github.event_name == 'release' |
| 733 | + runs-on: ${{ vars.FVTK_RUNNER_MACOS || 'macos-14' }} |
| 734 | + timeout-minutes: 120 |
| 735 | + steps: |
| 736 | + - uses: actions/checkout@v5 |
| 737 | + with: |
| 738 | + fetch-depth: 0 |
| 739 | + - name: Build wheels + smoke (cibuildwheel) |
| 740 | + uses: pypa/cibuildwheel@v3.1.4 |
| 741 | + env: |
| 742 | + CIBW_BUILD: "cp310-* cp311-*" |
| 743 | + # CIBW_ENVIRONMENT REPLACES the pyproject [tool.cibuildwheel.macos. |
| 744 | + # environment] table, so re-declare every macOS build var (init-cache, |
| 745 | + # target OS, deployment target + host-platform tag, ccache launchers) and |
| 746 | + # add FVTK_ABI3=0. archs/before-build/repair/test-command are NOT in the |
| 747 | + # environment table, so they survive from pyproject (arm64, delocate+strip |
| 748 | + # repair, smoke_min) unchanged. |
| 749 | + CIBW_ENVIRONMENT: >- |
| 750 | + FVTK_ABI3=0 |
| 751 | + FVTK_CMAKE_INIT=ci/cmake/macos.cmake |
| 752 | + FVTK_TARGET_OS=macos |
| 753 | + MACOSX_DEPLOYMENT_TARGET=11.0 |
| 754 | + _PYTHON_HOST_PLATFORM=macosx-11.0-arm64 |
| 755 | + CMAKE_C_COMPILER_LAUNCHER=ccache |
| 756 | + CMAKE_CXX_COMPILER_LAUNCHER=ccache |
| 757 | + - uses: actions/upload-artifact@v4 |
| 758 | + with: |
| 759 | + name: fvtk-wheels-legacy-macos |
| 760 | + path: wheelhouse/*.whl |
| 761 | + if-no-files-found: error |
| 762 | + |
619 | 763 | publish: |
620 | 764 | name: Publish to PyPI (trusted publishing) |
621 | 765 | # Only on a published GitHub Release, and only after the SHIPPED-config legs |
622 | 766 | # are green: build-lto (the -O3 + LTO Linux x86_64 wheel that ships) validated |
623 | 767 | # by bitexact-lto + renderexact-lto, plus the optimized macOS/Windows wheels |
624 | | - # from build-other-os and the aarch64 wheel from build-arm. The fast non-LTO |
625 | | - # gate (build/bitexact/renderexact) is not a dependency — its wheel is never |
626 | | - # published. |
| 768 | + # from build-other-os and the aarch64 wheel from build-arm. Also waits on the |
| 769 | + # three legacy legs (build-legacy-linux/windows/macos) so the cp310/cp311 |
| 770 | + # version-specific wheels ship in the same release as the abi3 wheels. The fast |
| 771 | + # non-LTO gate (build/bitexact/renderexact) is not a dependency — its wheel is |
| 772 | + # never published. |
627 | 773 | if: github.event_name == 'release' |
628 | | - needs: [build-lto, build-arm, build-other-os, bitexact-lto, renderexact-lto] |
| 774 | + needs: [build-lto, build-arm, build-other-os, bitexact-lto, renderexact-lto, |
| 775 | + build-legacy-linux, build-legacy-windows, build-legacy-macos] |
629 | 776 | runs-on: ${{ vars.FVTK_RUNNER_LINUX_SMALL || 'ubuntu-latest' }} |
630 | 777 | # Artifact download + PyPI upload only; cap low. |
631 | 778 | timeout-minutes: 15 |
@@ -666,12 +813,32 @@ jobs: |
666 | 813 | with: |
667 | 814 | name: fvtk-wheels-windows-latest |
668 | 815 | path: dist |
| 816 | + # The six legacy (cp310 + cp311) wheels — Linux, Windows, macOS — into the |
| 817 | + # SAME dist/. They ship to PyPI and (via the attach step below) to the Release |
| 818 | + # alongside the four abi3 wheels. Distinct artifact names, no glob collision. |
| 819 | + - name: Download legacy Linux wheels (cp310+cp311) |
| 820 | + uses: actions/download-artifact@v4 |
| 821 | + with: |
| 822 | + name: fvtk-wheels-legacy-linux |
| 823 | + path: dist |
| 824 | + - name: Download legacy Windows wheels (cp310+cp311) |
| 825 | + uses: actions/download-artifact@v4 |
| 826 | + with: |
| 827 | + name: fvtk-wheels-legacy-windows |
| 828 | + path: dist |
| 829 | + - name: Download legacy macOS wheels (cp310+cp311) |
| 830 | + uses: actions/download-artifact@v4 |
| 831 | + with: |
| 832 | + name: fvtk-wheels-legacy-macos |
| 833 | + path: dist |
669 | 834 | - name: List + sanity-check the release wheels |
670 | 835 | run: | |
671 | 836 | ls -l dist |
672 | 837 | n=$(ls dist/*.whl 2>/dev/null | wc -l) |
673 | 838 | echo "collected $n wheel(s)" |
674 | | - test "$n" -ge 1 || { echo "::error::no wheels to publish"; exit 1; } |
| 839 | + # 4 abi3 (linux x86_64 + aarch64, macOS, Windows) + 6 legacy |
| 840 | + # (cp310/cp311 x linux/windows/macos) == 10 expected. |
| 841 | + test "$n" -ge 10 || { echo "::error::expected >=10 wheels (4 abi3 + 6 legacy), found $n"; exit 1; } |
675 | 842 | - name: Publish to PyPI |
676 | 843 | uses: pypa/gh-action-pypi-publish@release/v1 |
677 | 844 | with: |
|
0 commit comments