From ca8fc4a169b2166e0b7efd90342ffa4179024243 Mon Sep 17 00:00:00 2001 From: Trevor Gamblin Date: Tue, 30 Jun 2026 14:06:35 -0400 Subject: [PATCH 1/4] matplotlib: add build, test workflows for riscv64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We make use of uv to simplify the pipeline in several ways: - replace 'python -m pip' with 'uv pip' - set cache to match uv usage - use uv for CIBW_BUILD_FRONTEND - set UV_EXTRA_INDEX_URL to our GitLab registry, with UV_INDEX_STRATEGY=unsafe-best-match and UV_ONLY_BINARY=:all: so we pick whichever source has a binary wheel - drop 'allow-prereleases' from setup-uv since this only applies to the setup-python action Also make sure we explicitly skip musllinux builds, since upstream isn't building them either. Otherwise, we run into issues with uv setup: |Building cp314-musllinux_riscv64 wheel |CPython 3.14 musllinux riscv64 | |Setting up build environment... | | + mkdir -p / | + /opt/python/cp39-cp39/bin/python -c 'import sys, json, os; json.dump(os.environ.copy(), sys.stdout)' | + which python | + which uv | ✕ 4.07s |Error: cibuildwheel: Command ['which', 'uv'] failed with code 1. | |Error: Process completed with exit code 1. Signed-off-by: Trevor Gamblin --- .github/workflows/build-matplotlib.yml | 194 +++++++++++++++++++ .github/workflows/test-matplotlib.yml | 252 +++++++++++++++++++++++++ 2 files changed, 446 insertions(+) create mode 100644 .github/workflows/build-matplotlib.yml create mode 100644 .github/workflows/test-matplotlib.yml diff --git a/.github/workflows/build-matplotlib.yml b/.github/workflows/build-matplotlib.yml new file mode 100644 index 0000000..0272638 --- /dev/null +++ b/.github/workflows/build-matplotlib.yml @@ -0,0 +1,194 @@ +--- +name: Build matplotlib wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'matplotlib version to build (git tag without leading v, e.g. 3.11.0)' + required: true + default: '3.11.0' + pull_request: + paths: + - '.github/workflows/build-matplotlib.yml' + - '.github/workflows/test-matplotlib.yml' + +concurrency: + group: ${{ github.workflow }}-${{ inputs.version || '3.11.0' }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + # `inputs.version` is empty on pull_request events; default there. + MPL_VERSION: ${{ inputs.version || '3.11.0' }} + # Query PyPI + gitlab riscv64 mirror; pick best compatible wheel + # (`unsafe-best-match` = pip-like). Refuse sdist for dependencies so uv + # selects the gitlab riscv64 wheel when PyPI lacks one instead of falling + # back to a source build. + UV_EXTRA_INDEX_URL: https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple + UV_INDEX_STRATEGY: unsafe-best-match + UV_ONLY_BINARY: ':all:' + +jobs: + build_sdist: + name: Build matplotlib ${{ inputs.version || '3.11.0' }} sdist + runs-on: ubuntu-24.04-riscv + permissions: + contents: read + outputs: + SDIST_NAME: ${{ steps.sdist.outputs.SDIST_NAME }} + + steps: + - name: Checkout python-wheels + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + path: python-wheels-repo + persist-credentials: false + + - name: Checkout matplotlib v${{ env.MPL_VERSION }} + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + repository: matplotlib/matplotlib + ref: v${{ env.MPL_VERSION }} + fetch-depth: 0 + persist-credentials: false + + - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + name: Install Python + with: + python-version: '3.12' + activate-environment: true + enable-cache: false + + # Something changed somewhere that prevents the downloaded-at-build-time + # licenses from being included in built wheels, so pre-download them so + # that they exist before the build and are included. + - name: Pre-download bundled licenses + run: > + curl -Lo LICENSE/LICENSE_QHULL + https://github.com/qhull/qhull/raw/2020.2/COPYING.txt + + - name: Install dependencies + run: uv pip install build twine + + - name: Build sdist + id: sdist + run: | + python -m build --sdist + python ci/export_sdist_name.py + + - name: Check README rendering for PyPI + run: twine check dist/* + + - name: Upload sdist result + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: matplotlib-${{ env.MPL_VERSION }}-cibw-sdist + path: dist/*.tar.gz + if-no-files-found: error + + build_wheels: + needs: build_sdist + name: Build matplotlib ${{ inputs.version || '3.11.0' }} wheels for riscv64 + permissions: + contents: read + runs-on: ubuntu-24.04-riscv + + steps: + - name: Checkout python-wheels + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + path: python-wheels-repo + persist-credentials: false + + - name: Download sdist + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: matplotlib-${{ env.MPL_VERSION }}-cibw-sdist + path: dist/ + + - name: Build wheels for CPython 3.14 + uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1 + with: + package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} + env: + CIBW_BUILD: "cp314-* cp314t-*" + CIBW_ARCHS: "riscv64" + # Skip musllinux: upstream matplotlib isn't building it either + CIBW_SKIP: "*-musllinux_*" + CIBW_BUILD_FRONTEND: "build[uv]" + CIBW_ENVIRONMENT: >- + UV_EXTRA_INDEX_URL=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple + UV_INDEX_STRATEGY=unsafe-best-match + UV_ONLY_BINARY=:all: + + - name: Build wheels for CPython 3.13 + uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1 + with: + package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} + env: + CIBW_BUILD: "cp313-*" + CIBW_ARCHS: "riscv64" + # Skip musllinux: upstream matplotlib isn't building it either + CIBW_SKIP: "*-musllinux_*" + CIBW_BUILD_FRONTEND: "build[uv]" + CIBW_ENVIRONMENT: >- + UV_EXTRA_INDEX_URL=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple + UV_INDEX_STRATEGY=unsafe-best-match + UV_ONLY_BINARY=:all: + + - name: Build wheels for CPython 3.12 + uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1 + with: + package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} + env: + CIBW_BUILD: "cp312-*" + CIBW_ARCHS: "riscv64" + # Skip musllinux: upstream matplotlib isn't building it either + CIBW_SKIP: "*-musllinux_*" + CIBW_BUILD_FRONTEND: "build[uv]" + CIBW_ENVIRONMENT: >- + UV_EXTRA_INDEX_URL=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple + UV_INDEX_STRATEGY=unsafe-best-match + UV_ONLY_BINARY=:all: + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: matplotlib-${{ env.MPL_VERSION }}-cibw-wheels-riscv64 + path: ./wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish matplotlib ${{ inputs.version || '3.11.0' }} to GitLab + needs: build_wheels + # Only publish when the workflow was triggered from main with a specific + # version. Manual trigger is the only entry point that reaches main; + # PR runs sit on refs/pull//merge and skip this job. + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-24.04-riscv + permissions: + contents: read + + steps: + - name: Checkout python-wheels + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + path: python-wheels-repo + persist-credentials: false + + - name: Download wheels + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: matplotlib-${{ env.MPL_VERSION }}-cibw-wheels-riscv64 + path: dist + + - name: Publish to GitLab PyPI registry + uses: ./python-wheels-repo/actions/publish-to-gitlab + with: + gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }} + gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }} + gitlab-project-id: ${{ vars.GITLAB_PROJECT_ID }} + files: | + dist/*.whl diff --git a/.github/workflows/test-matplotlib.yml b/.github/workflows/test-matplotlib.yml new file mode 100644 index 0000000..b38b5ed --- /dev/null +++ b/.github/workflows/test-matplotlib.yml @@ -0,0 +1,252 @@ +--- +name: Test matplotlib (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'matplotlib version to test (git tag without leading v, e.g. 3.11.0)' + required: true + default: '3.11.0' + pull_request: + paths: + - '.github/workflows/test-matplotlib.yml' + +concurrency: + group: ${{ github.workflow }}-${{ inputs.version || '3.11.0' }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + NO_AT_BRIDGE: 1 # Necessary for GTK3 interactive test. + OPENBLAS_NUM_THREADS: 1 + PYTHONFAULTHANDLER: 1 + MPL_VERSION: ${{ inputs.version || '3.11.0' }} + # Query PyPI + gitlab riscv64 mirror; pick best compatible wheel + # (`unsafe-best-match` = pip-like). Refuse sdist for dependencies so uv + # selects the gitlab riscv64 wheel when PyPI lacks one instead of falling + # back to a source build. + UV_EXTRA_INDEX_URL: https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple + UV_INDEX_STRATEGY: unsafe-best-match + UV_ONLY_BINARY: ':all:' + +jobs: + test: + permissions: + contents: read + name: "Test matplotlib ${{ inputs.version || '3.11.0' }} — Python ${{ matrix.python-version }} on ${{ matrix.os }}" + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-24.04-riscv + python-version: '3.12' + + steps: + - name: Checkout python-wheels + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + path: python-wheels-repo + persist-credentials: false + + - name: Checkout matplotlib v${{ env.MPL_VERSION }} + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + repository: matplotlib/matplotlib + ref: v${{ env.MPL_VERSION }} + fetch-depth: 0 + persist-credentials: false + + - name: Set up Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + python-version: ${{ matrix.python-version }} + activate-environment: true + enable-cache: false + + - name: Install OS dependencies + run: | + echo 'Acquire::Retries "3";' | sudo tee /etc/apt/apt.conf.d/80-retries + sudo apt-get update -yy + sudo apt-get install -yy --no-install-recommends \ + ccache \ + cm-super \ + dvipng \ + fonts-freefont-otf \ + fonts-noto-cjk \ + fonts-wqy-zenhei \ + gdb \ + gir1.2-gtk-3.0 \ + gir1.2-gtk-4.0 \ + graphviz \ + inkscape \ + language-pack-de \ + lcov \ + libcairo2 \ + libcairo2-dev \ + libffi-dev \ + libgeos-dev \ + libnotify4 \ + libxkbcommon-x11-0 \ + libxcb-cursor0 \ + libxcb-icccm4 \ + libxcb-image0 \ + libxcb-keysyms1 \ + libxcb-randr0 \ + libxcb-render-util0 \ + libxcb-xinerama0 \ + lmodern \ + ninja-build \ + pkg-config \ + qtbase5-dev \ + texlive-fonts-recommended \ + texlive-latex-base \ + texlive-latex-extra \ + texlive-latex-recommended \ + texlive-luatex \ + texlive-pictures \ + texlive-xetex + sudo apt-get install -yy --no-install-recommends ffmpeg poppler-utils + sudo apt-get install -yy --no-install-recommends libgirepository-2.0-dev + + - name: Cache uv + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ~/.cache/uv + key: | + ${{ matrix.os }}-py${{ matrix.python-version }}-uv-${{ + hashFiles('pyproject.toml', 'ci/minver-requirements.txt') }} + restore-keys: | + ${{ matrix.os }}-py${{ matrix.python-version }}-uv- + - name: Cache ccache + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + ~/.ccache + key: ${{ matrix.os }}-py${{ matrix.python-version }}-ccache-${{ hashFiles('src/*') }} + restore-keys: | + ${{ matrix.os }}-py${{ matrix.python-version }}-ccache- + - name: Cache Matplotlib + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + ~/.cache/matplotlib + !~/.cache/matplotlib/tex.cache + !~/.cache/matplotlib/test_cache + key: 6-${{ matrix.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}-${{ github.sha }} + restore-keys: | + 6-${{ matrix.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}- + 6-${{ matrix.os }}-py${{ matrix.python-version }}-mpl- + + - name: Install Python dependencies + run: | + # Upgrade pip and setuptools and wheel to get as clean an install as + # possible. + uv pip install --upgrade pip setuptools wheel + + # Install dependencies from PyPI. + # Preinstall build requirements to enable no-build-isolation builds. + uv pip install --upgrade --only-binary :all: \ + --group build --group test + + # Install optional dependencies from PyPI. + # Sphinx is needed to run sphinxext tests + uv pip install --upgrade sphinx!=6.1.2 + + # GUI toolkits are pip-installable only for some versions of Python + # so don't fail if we can't install them. Make it easier to check + # whether the install was successful by trying to import the toolkit + # (sometimes, the install appears to be successful but shared + # libraries cannot be loaded at runtime, so an actual import is a + # better check). + uv pip install --upgrade pycairo 'cairocffi>=0.8' 'PyGObject' && + ( + python -c 'import gi; gi.require_version("Gtk", "4.0"); from gi.repository import Gtk' && + echo 'PyGObject 4 is available' || echo 'PyGObject 4 is not available' + ) && ( + python -c 'import gi; gi.require_version("Gtk", "3.0"); from gi.repository import Gtk' && + echo 'PyGObject 3 is available' || echo 'PyGObject 3 is not available' + ) + + # PyQt5 has no riscv64 wheels; skip. + uv pip install --upgrade --only-binary :all: pyqt6 && + python -c 'import PyQt6.QtCore' && + echo 'PyQt6 is available' || + echo 'PyQt6 is not available' + uv pip install --upgrade --only-binary :all: pyside6 && + python -c 'import PySide6.QtCore' && + echo 'PySide6 is available' || + echo 'PySide6 is not available' + + - name: Install Matplotlib + run: | + ccache -s + git describe + + export CPPFLAGS='--coverage -fprofile-abs-path' + + uv pip install --no-deps --no-build-isolation --verbose \ + --config-settings=setup-args="-DrcParams-backend=Agg" \ + --editable .[dev] + + unset CPPFLAGS + + - name: Run pytest + run: | + pytest -rfEsXR -n auto \ + --maxfail=50 --timeout=300 --durations=25 \ + --cov-report=xml --cov=lib --log-level=DEBUG --color=yes + + - name: Cleanup non-failed image files + if: failure() + run: | + find ./result_images -name "*-expected*.png" | while read file; do + if [[ $file == *-expected_???.png ]]; then + extension=${file: -7:3} + base=${file%*-expected_$extension.png}_$extension + else + extension="png" + base=${file%-expected.png} + fi + if [[ ! -e ${base}-failed-diff.png ]]; then + indent="" + list=($file $base.png) + if [[ $extension != "png" ]]; then + list+=(${base%_$extension}-expected.$extension ${base%_$extension}.$extension) + fi + for to_remove in "${list[@]}"; do + if [[ -e $to_remove ]]; then + rm $to_remove + echo "${indent}Removed $to_remove" + fi + indent+=" " + done + fi + done + + if [ "$(find ./result_images -mindepth 1 -type d)" ]; then + find ./result_images/* -type d -empty -delete + fi + + - name: Filter C coverage + if: ${{ !cancelled() }} + run: | + LCOV_IGNORE_ERRORS='mismatch' + lcov --rc lcov_branch_coverage=1 --ignore-errors $LCOV_IGNORE_ERRORS \ + --capture --directory . --exclude $PWD/subprojects --exclude $PWD/build \ + --output-file coverage.info + lcov --rc lcov_branch_coverage=1 --ignore-errors $LCOV_IGNORE_ERRORS \ + --output-file coverage.info --extract coverage.info $PWD/src/'*' + lcov --rc lcov_branch_coverage=1 --ignore-errors $LCOV_IGNORE_ERRORS \ + --list coverage.info + find . -name '*.gc*' -delete + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + if: failure() + with: + name: "matplotlib-${{ env.MPL_VERSION }}-py${{ matrix.python-version }}-${{ matrix.os }}-result-images" + path: result_images From 244ccf3829af65edf0a6b1777db9f122a66e5a9d Mon Sep 17 00:00:00 2001 From: Trevor Gamblin Date: Tue, 21 Jul 2026 11:29:20 -0400 Subject: [PATCH 2/4] patches: matplotlib: increase threading test timeout Signed-off-by: Trevor Gamblin --- ...manager-increase-test_fontcache_thre.patch | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 patches/matplotlib/3.11.0/0001-tests-test_font_manager-increase-test_fontcache_thre.patch diff --git a/patches/matplotlib/3.11.0/0001-tests-test_font_manager-increase-test_fontcache_thre.patch b/patches/matplotlib/3.11.0/0001-tests-test_font_manager-increase-test_fontcache_thre.patch new file mode 100644 index 0000000..56ac2d1 --- /dev/null +++ b/patches/matplotlib/3.11.0/0001-tests-test_font_manager-increase-test_fontcache_thre.patch @@ -0,0 +1,34 @@ +From a830afe01625f10e11640e2b2c3f3d88b2c16b36 Mon Sep 17 00:00:00 2001 +From: Trevor Gamblin +Date: Tue, 21 Jul 2026 11:25:31 -0400 +Subject: [PATCH] tests: test_font_manager: increase test_fontcache_thread_safe + timeout + +This test seems to pass in a local riscv64 container, but fails when run +on the native runners. It's a single threading test with a 10s timeout, +so double that timeout for our builds. For now this should be considered +inappropriate for upstream until we see the failure on their end too. + +Upstream-Status: Inappropriate [native runner specific] + +Signed-off-by: Trevor Gamblin +--- + lib/matplotlib/tests/test_font_manager.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py +index add063df90..f3a9d57039 100644 +--- a/lib/matplotlib/tests/test_font_manager.py ++++ b/lib/matplotlib/tests/test_font_manager.py +@@ -344,7 +344,7 @@ def _test_threading(): + def test_fontcache_thread_safe(): + pytest.importorskip('threading') + +- subprocess_run_helper(_test_threading, timeout=10) ++ subprocess_run_helper(_test_threading, timeout=20) + + + def test_lockfilefailure(tmp_path): +-- +2.55.0 + From e65cc2aafe3d06f2bb72c934954e16e2db6bea1d Mon Sep 17 00:00:00 2001 From: Trevor Gamblin Date: Tue, 21 Jul 2026 11:35:31 -0400 Subject: [PATCH 3/4] workflows: build-matplotlib: patch source, simplify python-wheels path Signed-off-by: Trevor Gamblin --- .github/workflows/build-matplotlib.yml | 28 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-matplotlib.yml b/.github/workflows/build-matplotlib.yml index 0272638..f740537 100644 --- a/.github/workflows/build-matplotlib.yml +++ b/.github/workflows/build-matplotlib.yml @@ -41,12 +41,6 @@ jobs: SDIST_NAME: ${{ steps.sdist.outputs.SDIST_NAME }} steps: - - name: Checkout python-wheels - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - path: python-wheels-repo - persist-credentials: false - - name: Checkout matplotlib v${{ env.MPL_VERSION }} uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: @@ -55,13 +49,25 @@ jobs: fetch-depth: 0 persist-credentials: false - - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 - name: Install Python + - name: Checkout python-wheels + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + path: python-wheels + persist-credentials: false + + - name: Install Python + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: python-version: '3.12' activate-environment: true enable-cache: false + # We need to patch the matplotlib source to increase a threading test + # timeout for the native runners + - name: patch matplotlib source + run: | + git apply python-wheels/patches/matplotlib/${{ env.MPL_VERSION }}/00*.patch + # Something changed somewhere that prevents the downloaded-at-build-time # licenses from being included in built wheels, so pre-download them so # that they exist before the build and are included. @@ -100,7 +106,7 @@ jobs: - name: Checkout python-wheels uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - path: python-wheels-repo + path: python-wheels persist-credentials: false - name: Download sdist @@ -175,7 +181,7 @@ jobs: - name: Checkout python-wheels uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - path: python-wheels-repo + path: python-wheels persist-credentials: false - name: Download wheels @@ -185,7 +191,7 @@ jobs: path: dist - name: Publish to GitLab PyPI registry - uses: ./python-wheels-repo/actions/publish-to-gitlab + uses: ./python-wheels/actions/publish-to-gitlab with: gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }} gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }} From be90e6ba6db4f7b043a980e4d9a7909d2cc68be3 Mon Sep 17 00:00:00 2001 From: Trevor Gamblin Date: Tue, 21 Jul 2026 11:35:51 -0400 Subject: [PATCH 4/4] workflows: test-matplotlib: patch source, simplify python-wheels path Add two patches for our matplotlib tests: - One to increase a threading test timeout, helping to overcome hardware limitations (marked as "Inappropriate" as it's unique for our setup) - One to backport a fix from upstream main, which is proposed for backporting into the 3.11.x releases but not part of 3.11.0. This pins pytest below version 9.1.0 due to how that version results in numerous errors being reported during the test runs (marked as "Backport" with a commit link). Signed-off-by: Trevor Gamblin --- .github/workflows/test-matplotlib.yml | 18 ++++--- .../0001-TST-temporarily-pin-pytest.patch | 48 +++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 patches/matplotlib/3.11.0/0001-TST-temporarily-pin-pytest.patch diff --git a/.github/workflows/test-matplotlib.yml b/.github/workflows/test-matplotlib.yml index b38b5ed..5c6e8f8 100644 --- a/.github/workflows/test-matplotlib.yml +++ b/.github/workflows/test-matplotlib.yml @@ -47,12 +47,6 @@ jobs: python-version: '3.12' steps: - - name: Checkout python-wheels - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - path: python-wheels-repo - persist-credentials: false - - name: Checkout matplotlib v${{ env.MPL_VERSION }} uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: @@ -61,6 +55,12 @@ jobs: fetch-depth: 0 persist-credentials: false + - name: Checkout python-wheels + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + path: python-wheels + persist-credentials: false + - name: Set up Python ${{ matrix.python-version }} uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: @@ -68,6 +68,12 @@ jobs: activate-environment: true enable-cache: false + # We need to patch the matplotlib source to increase a threading test + # timeout for the native runners + - name: patch matplotlib source + run: | + git apply python-wheels/patches/matplotlib/${{ env.MPL_VERSION }}/00*.patch + - name: Install OS dependencies run: | echo 'Acquire::Retries "3";' | sudo tee /etc/apt/apt.conf.d/80-retries diff --git a/patches/matplotlib/3.11.0/0001-TST-temporarily-pin-pytest.patch b/patches/matplotlib/3.11.0/0001-TST-temporarily-pin-pytest.patch new file mode 100644 index 0000000..31e649a --- /dev/null +++ b/patches/matplotlib/3.11.0/0001-TST-temporarily-pin-pytest.patch @@ -0,0 +1,48 @@ +From afb7f27453493011e33d7bc84be964fbe84eeaf3 Mon Sep 17 00:00:00 2001 +From: Ruth Comer <10599679+rcomer@users.noreply.github.com> +Date: Sun, 14 Jun 2026 21:04:35 +0100 +Subject: [PATCH] TST: temporarily pin pytest + +Upstream-Status: Backport [https://github.com/matplotlib/matplotlib/pull/31896/changes/afb7f27] + +Upstream devs have pinned pytest below 9.1.0 due to numerous test failures. This +commit is only in main so far. We should backport it to avoid various +TestSpectral errors on our end. + +See also: https://github.com/matplotlib/matplotlib/issues/31897 + +Signed-off-by: Trevor Gamblin +--- + environment.yml | 2 +- + pyproject.toml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/environment.yml b/environment.yml +index 27624759ea..057b8466fe 100644 +--- a/environment.yml ++++ b/environment.yml +@@ -63,7 +63,7 @@ dependencies: + - psutil + - prek + - pydocstyle>=5.1.0 +- - pytest!=4.6.0,!=5.4.0,!=8.1.0 ++ - pytest!=4.6.0,!=5.4.0,!=8.1.0,<9.1.0 + - pytest-cov + - pytest-rerunfailures + - pytest-timeout +diff --git a/pyproject.toml b/pyproject.toml +index cf0cde26cd..b63ce715ed 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -129,7 +129,7 @@ test = [ + "certifi", + "coverage!=6.3", + "psutil; sys_platform != 'cygwin'", +- "pytest!=4.6.0,!=5.4.0,!=8.1.0", ++ "pytest!=4.6.0,!=5.4.0,!=8.1.0,<9.1.0", + "pytest-cov", + "pytest-rerunfailures!=16.0", + "pytest-timeout", +-- +2.55.0 +