Skip to content

Build and Test C++ and Python #4907

Build and Test C++ and Python

Build and Test C++ and Python #4907

Workflow file for this run

# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
#
# SPDX-License-Identifier: MPL-2.0
name: Build and Test C++ and Python
# Controls when the workflow will run
on:
# run pipeline on push event of main branch
push:
branches:
- main
# run pipeline on pull request
pull_request:
# run pipeline on merge queue
merge_group:
# run this workflow manually from the Actions tab
workflow_dispatch:
inputs:
create_release:
type: boolean
description: Create a (pre-)release when CI passes
default: true
required: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
acquire-python-version-build-sdist:
name: Build sdist and set version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Set PyPI Version
run: |
pip install requests build
python set_pypi_version.py
- name: Build SDist
run: python -m build --sdist --outdir wheelhouse .
- name: Keep version file
uses: actions/upload-artifact@v4
with:
name: version
path: PYPI_VERSION
- name: Keep SDist
uses: actions/upload-artifact@v4
with:
name: wheelhouse
path: ./wheelhouse/*.tar.gz
build-cpp-test-linux:
runs-on: ubuntu-latest
strategy:
matrix:
build-option: [ debug, release ]
compiler: [gcc, clang]
include:
- compiler: gcc
- compiler: clang
env:
CMAKE_PREFIX_PATH: /home/linuxbrew/.linuxbrew
PRESET: ci-${{ matrix.compiler }}-${{ matrix.build-option }}
steps:
- uses: actions/checkout@v4
- name: Install packages
run: |
sudo apt-get update
sudo apt-get install -y ninja-build gcc-12 g++-12 clang-15
sudo ln -s /usr/bin/clang-15 /usr/local/bin/clang
sudo ln -s /usr/bin/clang++-15 /usr/local/bin/clang++
sudo ln -s /usr/bin/gcc-12 /usr/local/bin/gcc
sudo ln -s /usr/bin/g++-12 /usr/local/bin/g++
- name: Enable brew
run: |
echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
- name: Install C++ dependencies
run: |
brew install boost eigen nlohmann-json msgpack-cxx doctest
- name: Build and test
run: ./build.sh -p ${{ env.PRESET }} -e -i -t
build-cpp-test-windows:
runs-on: windows-latest
strategy:
matrix:
build-option: [ debug, release ]
compiler: [msvc, clang-cl]
env:
PRESET: ${{ matrix.compiler }}-${{ matrix.build-option }}
steps:
- uses: actions/checkout@v4
- name: Activate conda
uses: conda-incubator/setup-miniconda@v3 # install miniforge instead
with:
miniforge-version: latest
- name: List conda
run: |
conda info
conda list
- name: Install conda environment
run: |
conda create --yes -p C:\conda_envs\cpp_pkgs -c conda-forge libboost-headers eigen nlohmann_json msgpack-cxx doctest
- name: Build and test
run: |
$vsPath = &(Join-Path ${env:ProgramFiles(x86)} '\Microsoft Visual Studio\Installer\vswhere.exe') -property installationpath
Import-Module (Join-Path $vsPath 'Common7\Tools\Microsoft.VisualStudio.DevShell.dll')
Enter-VsDevShell -VsInstallPath $vsPath -SkipAutomaticLocation -DevCmdArguments '-arch=x64 -host_arch=x64'
# Resolve dirty PATH environment
# TODO(mgovers): Remove after https://github.com/actions/runner-images/issues/10001 is resolved
$env:PATH = ($env:PATH -split ';' | Where-Object { $_ -ne 'C:\Program Files\LLVM\bin' }) -join ';'
# generate cmake cache
cmake --preset ${{ env.PRESET }} -DCMAKE_PREFIX_PATH=C:\conda_envs\cpp_pkgs\Library; if(!$?) { Exit $LASTEXITCODE }
# build
cmake --build --preset ${{ env.PRESET }} --verbose -j 1; if(!$?) { Exit $LASTEXITCODE }
# test
ctest --preset ${{ env.PRESET }} --output-on-failure; if(!$?) { Exit $LASTEXITCODE }
# install
cmake --build --preset ${{ env.PRESET }} --verbose -j 1 --target install; if(!$?) { Exit $LASTEXITCODE }
# build and run integration test
cd tests/package_tests; if(!$?) { Exit $LASTEXITCODE }
cmake --preset ${{ env.PRESET }}; if(!$?) { Exit $LASTEXITCODE }
cmake --build --preset ${{ env.PRESET }} --verbose -j 1; if(!$?) { Exit $LASTEXITCODE }
cmake --build --preset ${{ env.PRESET }} --verbose -j 1 --target install; if(!$?) { Exit $LASTEXITCODE }
install\${{ env.PRESET }}\bin\power_grid_model_package_test; if(!$?) { Exit $LASTEXITCODE }
build-cpp-test-macos:
runs-on: macos-14
strategy:
matrix:
build-option: [ debug, release ]
env:
CMAKE_PREFIX_PATH: /usr/local
PRESET: ci-clang-${{ matrix.build-option }}
steps:
- uses: actions/checkout@v4
- name: Set up XCode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Install cpp dependencies
run: |
brew install ninja boost eigen nlohmann-json msgpack-cxx doctest
- name: Build and test
run: ./build.sh -p ${{ env.PRESET }} -e -i -t
build-and-test-python:
strategy:
matrix:
platform: [ linux-x64, linux-aarch64, macos, windows ]
include:
- platform: linux-x64
os: ubuntu-latest
cibw_build: "*_x86_64"
- platform: linux-aarch64
os: ubuntu-latest
cibw_build: "*_aarch64"
- platform: macos
os: macos-14
cibw_build: "*"
- platform: windows
os: windows-latest
cibw_build: "*"
runs-on: ${{ matrix.os }}
needs: [acquire-python-version-build-sdist]
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: version
path: .
- name: Set up QEMU
if: matrix.os == 'ubuntu-latest'
uses: docker/setup-qemu-action@v3
- name: Set up XCode
if: matrix.os == 'macos-14'
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Build wheels
uses: pypa/cibuildwheel@v2.20.0
# GitHub Actions specific build parameters
env:
# pass GitHub runner info into Linux container
CIBW_ENVIRONMENT_PASS_LINUX: GITHUB_SHA GITHUB_REF GITHUB_RUN_NUMBER
CIBW_BUILD: ${{ matrix.cibw_build }}
- name: Keep wheel files
uses: actions/upload-artifact@v4
with:
name: wheelhouse-${{ matrix.platform }}
path: ./wheelhouse/*.whl
build-and-test-conda:
name: Build and test in Conda
runs-on: ${{ matrix.os }}-latest
strategy:
matrix:
os: ["ubuntu", "windows"] # We do not test conda for MacOS
defaults:
run:
shell: bash -el {0}
steps:
- uses: actions/checkout@v4
- uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest # use miniforge instead of miniconda
activate-environment: conda-pgm-env
environment-file: .github/conda_pgm_env.yml
auto-activate-base: false
- name: List conda
run: |
conda info
conda list
- name: Build
run: python -m pip install . -vv --no-build-isolation --no-deps
- name: Test
run: pytest
publish-wheels:
needs: [build-cpp-test-linux, build-cpp-test-windows, build-cpp-test-macos, build-and-test-python, build-and-test-conda]
# always run publish job but fail at the first step if previous jobs have been failed
if: always()
runs-on: ubuntu-latest
permissions:
contents: write
env:
TWINE_USERNAME: ${{ secrets.PYPI_USER }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASS }}
steps:
- name: Fail fast
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: |
echo "Previous jobs have failures!"
exit 1
- uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: '3.10'
architecture: x64
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v4
with:
name: version
path: .
- name: Combine wheelhouses
run: mv wheelhouse-*/* wheelhouse
- name: List assets
run: ls ./wheelhouse/ -al
- name: Get tag
id: tag
run: echo "tag=v$(cat PYPI_VERSION)" >> $GITHUB_OUTPUT
- name: Display tag
run: echo "${{ steps.tag.outputs.tag }}"
- name: Upload wheels
if: (github.event_name == 'push') || ((github.event_name == 'workflow_dispatch') && (github.event.inputs.create_release == 'true'))
run: |
pip install twine
echo "Publish to PyPI..."
twine upload --verbose wheelhouse/*
- name: Release
uses: softprops/action-gh-release@v2
if: (github.event_name == 'push') || ((github.event_name == 'workflow_dispatch') && (github.event.inputs.create_release == 'true'))
with:
files: |
./wheelhouse/*
tag_name: ${{ steps.tag.outputs.tag }}
prerelease: ${{ github.ref != 'refs/heads/main'}}
generate_release_notes: true
target_commitish: ${{ github.sha }}