Skip to content

Commit 0319f38

Browse files
authored
matplotlib: add build, test workflows for riscv64 (#97)
* matplotlib: add build, test workflows for riscv64 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 - Add python3-tk to OS dependencies list in test-matplotlib, so the 'tkinter' module is available to test for the backend test suites We add two patches and apply them after checkout: - 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). 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 <tgamblin@baylibre.com>
1 parent 6890243 commit 0319f38

4 files changed

Lines changed: 543 additions & 0 deletions

File tree

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
name: Build matplotlib wheels (riscv64)
3+
4+
on:
5+
workflow_dispatch:
6+
inputs:
7+
version:
8+
description: 'matplotlib version to build (git tag without leading v, e.g. 3.11.0)'
9+
required: true
10+
default: '3.11.0'
11+
pull_request:
12+
paths:
13+
- '.github/workflows/build-matplotlib.yml'
14+
- '.github/workflows/test-matplotlib.yml'
15+
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ inputs.version || '3.11.0' }}-${{ github.head_ref || github.run_id }}
18+
cancel-in-progress: true
19+
20+
permissions:
21+
contents: read # to fetch code (actions/checkout)
22+
23+
env:
24+
# `inputs.version` is empty on pull_request events; default there.
25+
MPL_VERSION: ${{ inputs.version || '3.11.0' }}
26+
# Query PyPI + gitlab riscv64 mirror; pick best compatible wheel
27+
# (`unsafe-best-match` = pip-like). Refuse sdist for dependencies so uv
28+
# selects the gitlab riscv64 wheel when PyPI lacks one instead of falling
29+
# back to a source build.
30+
UV_EXTRA_INDEX_URL: https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple
31+
UV_INDEX_STRATEGY: unsafe-best-match
32+
UV_ONLY_BINARY: ':all:'
33+
34+
jobs:
35+
build_sdist:
36+
name: Build matplotlib ${{ inputs.version || '3.11.0' }} sdist
37+
runs-on: ubuntu-24.04-riscv
38+
permissions:
39+
contents: read
40+
outputs:
41+
SDIST_NAME: ${{ steps.sdist.outputs.SDIST_NAME }}
42+
43+
steps:
44+
- name: Checkout matplotlib v${{ env.MPL_VERSION }}
45+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
46+
with:
47+
repository: matplotlib/matplotlib
48+
ref: v${{ env.MPL_VERSION }}
49+
fetch-depth: 0
50+
persist-credentials: false
51+
52+
- name: Checkout python-wheels
53+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
54+
with:
55+
path: python-wheels
56+
persist-credentials: false
57+
58+
- name: Install Python
59+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
60+
with:
61+
python-version: '3.12'
62+
activate-environment: true
63+
enable-cache: false
64+
65+
# We need to patch the matplotlib source to increase a threading test
66+
# timeout for the native runners
67+
- name: patch matplotlib source
68+
run: |
69+
git apply python-wheels/patches/matplotlib/${{ env.MPL_VERSION }}/00*.patch
70+
71+
# Something changed somewhere that prevents the downloaded-at-build-time
72+
# licenses from being included in built wheels, so pre-download them so
73+
# that they exist before the build and are included.
74+
- name: Pre-download bundled licenses
75+
run: >
76+
curl -Lo LICENSE/LICENSE_QHULL
77+
https://github.com/qhull/qhull/raw/2020.2/COPYING.txt
78+
79+
- name: Install dependencies
80+
run: uv pip install build twine
81+
82+
- name: Build sdist
83+
id: sdist
84+
run: |
85+
python -m build --sdist
86+
python ci/export_sdist_name.py
87+
88+
- name: Check README rendering for PyPI
89+
run: twine check dist/*
90+
91+
- name: Upload sdist result
92+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
93+
with:
94+
name: matplotlib-${{ env.MPL_VERSION }}-cibw-sdist
95+
path: dist/*.tar.gz
96+
if-no-files-found: error
97+
98+
build_wheels:
99+
needs: build_sdist
100+
name: Build matplotlib ${{ inputs.version || '3.11.0' }} wheels for riscv64
101+
permissions:
102+
contents: read
103+
runs-on: ubuntu-24.04-riscv
104+
105+
steps:
106+
- name: Checkout python-wheels
107+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
108+
with:
109+
path: python-wheels
110+
persist-credentials: false
111+
112+
- name: Download sdist
113+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
114+
with:
115+
name: matplotlib-${{ env.MPL_VERSION }}-cibw-sdist
116+
path: dist/
117+
118+
- name: Build wheels for CPython 3.14
119+
uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1
120+
with:
121+
package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }}
122+
env:
123+
CIBW_BUILD: "cp314-* cp314t-*"
124+
CIBW_ARCHS: "riscv64"
125+
# Skip musllinux: upstream matplotlib isn't building it either
126+
CIBW_SKIP: "*-musllinux_*"
127+
CIBW_BUILD_FRONTEND: "build[uv]"
128+
CIBW_ENVIRONMENT: >-
129+
UV_EXTRA_INDEX_URL=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple
130+
UV_INDEX_STRATEGY=unsafe-best-match
131+
UV_ONLY_BINARY=:all:
132+
133+
- name: Build wheels for CPython 3.13
134+
uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1
135+
with:
136+
package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }}
137+
env:
138+
CIBW_BUILD: "cp313-*"
139+
CIBW_ARCHS: "riscv64"
140+
# Skip musllinux: upstream matplotlib isn't building it either
141+
CIBW_SKIP: "*-musllinux_*"
142+
CIBW_BUILD_FRONTEND: "build[uv]"
143+
CIBW_ENVIRONMENT: >-
144+
UV_EXTRA_INDEX_URL=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple
145+
UV_INDEX_STRATEGY=unsafe-best-match
146+
UV_ONLY_BINARY=:all:
147+
148+
- name: Build wheels for CPython 3.12
149+
uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1
150+
with:
151+
package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }}
152+
env:
153+
CIBW_BUILD: "cp312-*"
154+
CIBW_ARCHS: "riscv64"
155+
# Skip musllinux: upstream matplotlib isn't building it either
156+
CIBW_SKIP: "*-musllinux_*"
157+
CIBW_BUILD_FRONTEND: "build[uv]"
158+
CIBW_ENVIRONMENT: >-
159+
UV_EXTRA_INDEX_URL=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple
160+
UV_INDEX_STRATEGY=unsafe-best-match
161+
UV_ONLY_BINARY=:all:
162+
163+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
164+
with:
165+
name: matplotlib-${{ env.MPL_VERSION }}-cibw-wheels-riscv64
166+
path: ./wheelhouse/*.whl
167+
if-no-files-found: error
168+
169+
publish:
170+
name: Publish matplotlib ${{ inputs.version || '3.11.0' }} to GitLab
171+
needs: build_wheels
172+
# Only publish when the workflow was triggered from main with a specific
173+
# version. Manual trigger is the only entry point that reaches main;
174+
# PR runs sit on refs/pull/<n>/merge and skip this job.
175+
if: github.ref == 'refs/heads/main'
176+
runs-on: ubuntu-24.04-riscv
177+
permissions:
178+
contents: read
179+
180+
steps:
181+
- name: Checkout python-wheels
182+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
183+
with:
184+
path: python-wheels
185+
persist-credentials: false
186+
187+
- name: Download wheels
188+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
189+
with:
190+
name: matplotlib-${{ env.MPL_VERSION }}-cibw-wheels-riscv64
191+
path: dist
192+
193+
- name: Publish to GitLab PyPI registry
194+
uses: ./python-wheels/actions/publish-to-gitlab
195+
with:
196+
gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }}
197+
gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }}
198+
gitlab-project-id: ${{ vars.GITLAB_PROJECT_ID }}
199+
files: |
200+
dist/*.whl

0 commit comments

Comments
 (0)