--- name: Build CI wheels env: # A tag or branch name or a commit hash for the matplotlib/matplotlib repo, for which # to build wheels. This is normally set to `main` in the main branch of this # repo, and to a tag name (e.g., `v2.3.2`) on a release branch. SOURCE_REF_TO_BUILD: main on: # TODO cron job? scipy does this # Save CI by only running this on release branches or tags. push: # FOR TESTING ONLY branches: - main - v[0-9]+.[0-9]+.x tags: - v* # Also allow running this action on PRs if requested by applying the # "Run cibuildwheel" label. pull_request: branches: - main - v[0-9]+.[0-9]+.x workflow_dispatch: inputs: environment: description: Which PyPI environment to upload to, if any required: true type: choice options: ["none", "testpypi", "pypi"] concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true permissions: contents: read jobs: build_sdist: name: Build sdist runs-on: ubuntu-latest outputs: SDIST_NAME: ${{ steps.sdist.outputs.SDIST_NAME }} steps: - name: Checkout matplotlib-release uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Checkout matplotlib uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: repository: matplotlib/matplotlib ref: ${{ env.SOURCE_REF_TO_BUILD }} path: mpl-src submodules: true persist-credentials: false fetch-depth: 0 - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 name: Install Python with: python-version: '3.11' - name: Install dependencies run: python -m pip install build twine - name: Build sdist id: sdist run: | cd mpl-src python -m build --sdist python ci/export_sdist_name.py - name: Check README rendering for PyPI run: twine check mpl-src/dist/* - name: Upload sdist result uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: cibw-sdist path: mpl-src/dist/*.tar.gz if-no-files-found: error sdist_license: needs: build_sdist name: Repackage licenses in sdist for binary distribution runs-on: ubuntu-latest steps: - name: Checkout matplotlib-release uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - name: Download sdist uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: name: cibw-sdist path: dist/ - name: Update LICENSE for binary distribution (append auxilliary licenses to LICENSE file) run: | tar -xvf dist/${{ needs.build_sdist.outputs.SDIST_NAME }} cat ${{ github.workspace }}/tools/wheels/LICENSE_binary.txt >> matplotlib*/LICENSE/LICENSE tar -cvf dist/${{ needs.build_sdist.outputs.SDIST_NAME }} matplotlib* - name: Upload sdist result uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: sdist-license path: dist/*.tar.gz if-no-files-found: error build_wheels: needs: [build_sdist, sdist_license] name: Build wheels on ${{ matrix.os }} for ${{ matrix.cibw_archs }} runs-on: ${{ matrix.os }} env: CIBW_BEFORE_BUILD: >- rm -rf {package}/build CIBW_BEFORE_BUILD_WINDOWS: >- pip install delvewheel && rm -rf {package}/build CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >- delvewheel repair -w {dest_dir} {wheel} # On Windows, we explicitly request MSVC compilers (as GitHub Action runners have # MinGW on PATH that would be picked otherwise), switch to a static build for # runtimes, but use dynamic linking for `VCRUNTIME140.dll`, `VCRUNTIME140_1.dll`, # and the UCRT. This avoids requiring specific versions of `MSVCP140.dll`, while # keeping shared state with the rest of the Python process/extensions. CIBW_CONFIG_SETTINGS_WINDOWS: >- setup-args="--vsenv" setup-args="-Db_vscrt=mt" setup-args="-Dcpp_link_args=['ucrt.lib','vcruntime.lib','/nodefaultlib:libucrt.lib','/nodefaultlib:libvcruntime.lib']" CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 CIBW_SKIP: "*-musllinux_aarch64" CIBW_TEST_COMMAND: >- python -m pip install build && python {package}/ci/check_version_number.py MACOSX_DEPLOYMENT_TARGET: "10.12" CIBW_TEST_ENVIRONMENT: PIP_PREFER_BINARY="1" strategy: matrix: include: - os: ubuntu-latest cibw_archs: "x86_64" - os: ubuntu-24.04-arm cibw_archs: "aarch64" - os: windows-latest cibw_archs: "AMD64" - os: windows-11-arm cibw_archs: "ARM64" - os: macos-15-intel cibw_archs: "x86_64" - os: macos-14 cibw_archs: "arm64" steps: - name: Download sdist uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: name: sdist-license path: dist/ - name: Build wheels for CPython 3.14 uses: pypa/cibuildwheel@9c00cb4f6b517705a3794b22395aedc36257242c # v3.2.1 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: CIBW_BUILD: "cp314-* cp314t-*" CIBW_ENABLE: "cpython-freethreading cpython-prerelease" CIBW_ARCHS: ${{ matrix.cibw_archs }} CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 - name: Build wheels for CPython 3.13 uses: pypa/cibuildwheel@9c00cb4f6b517705a3794b22395aedc36257242c # v3.2.1 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: CIBW_BUILD: "cp313-* cp313t-*" CIBW_ENABLE: cpython-freethreading CIBW_ARCHS: ${{ matrix.cibw_archs }} - name: Build wheels for CPython 3.12 uses: pypa/cibuildwheel@9c00cb4f6b517705a3794b22395aedc36257242c # v3.2.1 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: CIBW_BUILD: "cp312-*" CIBW_ARCHS: ${{ matrix.cibw_archs }} - name: Build wheels for CPython 3.11 uses: pypa/cibuildwheel@9c00cb4f6b517705a3794b22395aedc36257242c # v3.2.1 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: CIBW_BUILD: "cp311-*" CIBW_ARCHS: ${{ matrix.cibw_archs }} - name: Build wheels for PyPy uses: pypa/cibuildwheel@9c00cb4f6b517705a3794b22395aedc36257242c # v3.2.1 with: package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} env: CIBW_BUILD: "pp311-*" CIBW_ARCHS: ${{ matrix.cibw_archs }} CIBW_ENABLE: pypy if: matrix.cibw_archs != 'aarch64' && matrix.os != 'windows-latest' && matrix.os != 'windows-11-arm' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: cibw-wheels-${{ runner.os }}-${{ matrix.cibw_archs }} path: ./wheelhouse/*.whl if-no-files-found: error # ------------------------------------------------------------------------------------- testpypi-publish: name: Publish release to TestPyPI if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'testpypi' needs: [build_wheels, build_sdist] runs-on: ubuntu-latest environment: name: testpypi url: https://test.pypi.org/p/matplotlib permissions: id-token: write # mandatory for trusted publishing steps: - name: Download sdist and wheels uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 with: pattern: cibw-* path: dist merge-multiple: true - name: Publish uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 with: repository-url: https://test.pypi.org/legacy/ skip-existing: true print-hash: true attestations: true # ------------------------------------------------------------------------------------- check_version: name: Ensure commit is tag before upload to PyPi if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'pypi' needs: [build_wheels, build_sdist] runs-on: ubuntu-latest steps: - name: Checkout matplotlib uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: repository: matplotlib/matplotlib ref: ${{ env.SOURCE_REF_TO_BUILD }} path: mpl-src fetch-depth: 0 fetch-tags: true submodules: false persist-credentials: false - name: Examine git commit run: | cd mpl-src hash=$(git describe HEAD) echo $hash if [[ $hash == *"-"*"-"* ]]; then echo "SOURCE_REF_TO_BUILD is not a tag" exit 1 else echo "SOURCE_REF_TO_BUILD is a tag" fi; # ------------------------------------------------------------------------------------- pypi-publish: name: Publish release to PyPI if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'pypi' needs: [check_version] runs-on: ubuntu-latest environment: name: pypi url: https://pypi.org/p/matplotlib permissions: id-token: write # mandatory for trusted publishing steps: - name: Download sdist and wheels uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: pattern: cibw-* path: dist merge-multiple: true - name: Publish uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 with: print-hash: true attestations: true