Skip to content

Build and publish package to PyPI #187

Build and publish package to PyPI

Build and publish package to PyPI #187

Workflow file for this run

name: Build and publish package to PyPI
on:
release:
types: [published]
schedule:
# Run at 10 am UTC on day-of-month 1 and 15.
- cron: "0 10 1,15 * *"
workflow_dispatch:
inputs:
target:
description: 'Deployment target. Can be "pypi" or "testpypi"'
default: "testpypi"
debug_enabled:
type: boolean
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
required: false
default: false
# Set options available for all jobs that use cibuildwheel
env:
# Increase pip debugging output, equivalent to `pip -vv`
CIBW_BUILD_VERBOSITY: 2
# Disable build isolation to allow pre-installing build-time dependencies.
# Note: CIBW_BEFORE_BUILD must be present in all jobs using cibuildwheel.
CIBW_BUILD_FRONTEND: "pip; args: --no-build-isolation"
# Skip PyPy and MUSL builds in any and all jobs
CIBW_SKIP: "pp* *musllinux*"
FORCE_COLOR: 3
jobs:
build_windows_wheels:
name: Wheels (windows-latest)
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Get number of cores on Windows
id: get_num_cores
shell: python
run: |
from os import environ, cpu_count
num_cpus = cpu_count()
output_file = environ['GITHUB_OUTPUT']
with open(output_file, "a", encoding="utf-8") as output_stream:
output_stream.write(f"count={num_cpus}\n")
- name: Clone pybind11 repo (no history)
run: git clone --depth 1 --branch v2.11.1 https://github.com/pybind/pybind11.git
- name: Install vcpkg on Windows
run: |
cd C:\
rm -r -fo 'C:\vcpkg'
git clone https://github.com/microsoft/vcpkg
cd vcpkg
.\bootstrap-vcpkg.bat
- name: Cache packages installed through vcpkg on Windows
uses: actions/cache@v4
env:
cache-name: vckpg_binary_cache
with:
path: C:\Users\runneradmin\AppData\Local\vcpkg\archives
key: ${{ runner.os }}-build-VS2022-${{ env.cache-name }}-${{ hashFiles('vcpkg*.json') }}
# Enable tmate debugging of manually-triggered workflows if the input option was provided
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
- name: Build 64-bit wheels on Windows
run: pipx run cibuildwheel --output-dir wheelhouse
env:
CIBW_ENVIRONMENT: >
PYBAMM_USE_VCPKG=ON
VCPKG_ROOT_DIR=C:\vcpkg
VCPKG_DEFAULT_TRIPLET=x64-windows-static-md
VCPKG_FEATURE_FLAGS=manifests,registries
CMAKE_GENERATOR="Visual Studio 17 2022"
CMAKE_GENERATOR_PLATFORM=x64
CMAKE_BUILD_PARALLEL_LEVEL=${{ steps.get_num_cores.outputs.count }}
CIBW_ARCHS: AMD64
CIBW_BEFORE_BUILD: python -m pip install setuptools wheel # skip CasADi and CMake
CIBW_TEST_COMMAND: python -c "import pybamm; pybamm.IDAKLUSolver()"
- name: Upload Windows wheels
uses: actions/upload-artifact@v4
with:
name: windows_wheels
path: ./wheelhouse/*.whl
if-no-files-found: error
build_macos_and_linux_wheels:
name: Wheels (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-12]
steps:
- uses: actions/checkout@v4
name: Check out PyBaMM repository
- uses: actions/setup-python@v5
name: Set up Python
with:
python-version: 3.11
- name: Clone pybind11 repo (no history)
run: git clone --depth 1 --branch v2.11.1 https://github.com/pybind/pybind11.git
# sometimes gfortran cannot be found, so reinstall gcc just to be sure
- name: Install SuiteSparse and SUNDIALS on macOS
if: matrix.os == 'macos-12'
run: |
brew install graphviz libomp
brew reinstall gcc
python -m pip install cmake wget
python scripts/install_KLU_Sundials.py
- name: Build wheels on Linux
run: pipx run cibuildwheel --output-dir wheelhouse
if: matrix.os == 'ubuntu-latest'
env:
CIBW_ARCHS_LINUX: x86_64
CIBW_BEFORE_ALL_LINUX: >
yum -y install openblas-devel lapack-devel &&
bash scripts/install_sundials.sh 6.0.3 6.5.0
CIBW_BEFORE_BUILD_LINUX: python -m pip install cmake casadi setuptools wheel
CIBW_REPAIR_WHEEL_COMMAND_LINUX: auditwheel repair -w {dest_dir} {wheel}
CIBW_TEST_COMMAND: python -c "import pybamm; pybamm.IDAKLUSolver()"
- name: Build wheels on macOS amd64
if: matrix.os == 'macos-12'
run: pipx run cibuildwheel --output-dir wheelhouse
env:
CIBW_BEFORE_BUILD_MACOS: >
python -m pip install --upgrade cmake casadi setuptools wheel
CIBW_REPAIR_WHEEL_COMMAND_MACOS: delocate-listdeps {wheel} && delocate-wheel -v -w {dest_dir} {wheel}
CIBW_TEST_COMMAND: python -c "import pybamm; pybamm.IDAKLUSolver()"
- name: Upload wheels for Linux
uses: actions/upload-artifact@v4
if: matrix.os == 'ubuntu-latest'
with:
name: linux_wheels
path: ./wheelhouse/*.whl
if-no-files-found: error
- name: Upload wheels for macOS amd64
uses: actions/upload-artifact@v4
if: matrix.os == 'macos-12'
with:
name: macos_amd64_wheels
path: ./wheelhouse/*.whl
if-no-files-found: error
build_macos_arm64_wheels:
name: Wheels (macos-arm64)
# Current runner is macOS X 14+ on GitHub-hosted runners
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Clone pybind11 repo (no history)
run: git clone --depth 1 --branch v2.11.1 https://github.com/pybind/pybind11.git
- name: Install SuiteSparse and SUNDIALS on macOS
run: |
brew install graphviz libomp
brew reinstall gcc
python -m pip install cmake pipx
python scripts/install_KLU_Sundials.py
- name: Build wheels on macOS arm64
run: python -m pipx run cibuildwheel --output-dir wheelhouse
env:
CIBW_BEFORE_BUILD: python -m pip install cmake casadi setuptools wheel delocate
CIBW_REPAIR_WHEEL_COMMAND: delocate-listdeps {wheel} && delocate-wheel -v -w {dest_dir} {wheel}
CIBW_TEST_COMMAND: python -c "import pybamm; pybamm.IDAKLUSolver()"
- name: Upload wheels for macOS arm64
uses: actions/upload-artifact@v4
with:
name: macos_arm64_wheels
path: ./wheelhouse/*.whl
if-no-files-found: error
build_sdist:
name: Build SDist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Build SDist
run: pipx run build --sdist
- name: Upload SDist
uses: actions/upload-artifact@v4
with:
name: sdist
path: ./dist/*.tar.gz
if-no-files-found: error
publish_pypi:
# This job is only of value to PyBaMM and would always be skipped in forks
if: github.event_name != 'schedule' && github.repository == 'pybamm-team/PyBaMM'
name: Upload package to PyPI
needs: [build_macos_and_linux_wheels, build_macos_arm64_wheels, build_windows_wheels, build_sdist]
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/pybamm
permissions:
id-token: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Move all package files to files/
run: |
mkdir files
mv windows_wheels/* linux_wheels/* macos_amd64_wheels/* macos_arm64_wheels/* sdist/* files/
- name: Publish on PyPI
if: github.event.inputs.target == 'pypi' || github.event_name == 'release'
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: files/
- name: Publish on TestPyPI
if: github.event.inputs.target == 'testpypi'
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.TESTPYPI_TOKEN }}
packages-dir: files/
repository-url: https://test.pypi.org/legacy/
open_failure_issue:
needs: [build_windows_wheels, build_macos_and_linux_wheels, build_sdist]
name: Open an issue if build fails
if: ${{ always() && contains(needs.*.result, 'failure') && github.repository_owner == 'pybamm-team'}}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: JasonEtco/create-an-issue@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LOGS: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
with:
filename: .github/wheel_failure.md