From d5f3ab77de11b05bfcc47e6a09f4ad075856bad9 Mon Sep 17 00:00:00 2001 From: Tom Birdsong Date: Tue, 23 Aug 2022 10:48:16 -0400 Subject: [PATCH] ENH: Add ITK C++ and Python CI reusable workflows --- .github/workflows/build-test-cxx.yml | 140 ++++++++++++++ .../workflows/build-test-package-python.yml | 178 ++++++++++++++++++ 2 files changed, 318 insertions(+) create mode 100644 .github/workflows/build-test-cxx.yml create mode 100644 .github/workflows/build-test-package-python.yml diff --git a/.github/workflows/build-test-cxx.yml b/.github/workflows/build-test-cxx.yml new file mode 100644 index 0000000..a80647a --- /dev/null +++ b/.github/workflows/build-test-cxx.yml @@ -0,0 +1,140 @@ +name: 'Build, Test, Package ITK Remote Module' + +on: + workflow_call: + inputs: + cmake-options: + required: false + type: string + itk-cmake-options: + required: false + type: string + itk-git-tag: + required: false + type: string + default: '171fb2ba33a87041f99328a2f26612ff33aa9cc8' + +jobs: + build-test-cxx: + runs-on: ${{ matrix.os }} + strategy: + max-parallel: 3 + matrix: + os: [ubuntu-20.04, windows-2019, macos-11] + include: + - os: ubuntu-20.04 + c-compiler: "gcc" + cxx-compiler: "g++" + cmake-build-type: "MinSizeRel" + - os: windows-2019 + c-compiler: "cl.exe" + cxx-compiler: "cl.exe" + cmake-build-type: "Release" + - os: macos-11 + c-compiler: "clang" + cxx-compiler: "clang++" + cmake-build-type: "MinSizeRel" + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + python -m pip install ninja + + - name: Get specific version of CMake, Ninja + uses: lukka/get-cmake@v3.18.3 + + - name: Download ITK + run: | + cd .. + git clone https://github.com/InsightSoftwareConsortium/ITK.git + cd ITK + git checkout ${{ inputs.itk-git-tag }} + + - name: Build ITK + if: matrix.os != 'windows-2019' + run: | + cd .. + mkdir ITK-build + cd ITK-build + cmake -DCMAKE_C_COMPILER:FILEPATH="${{ matrix.c-compiler }}" -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_CXX_COMPILER="${{ matrix.cxx-compiler }}" -DCMAKE_BUILD_TYPE:STRING=${{ matrix.cmake-build-type }} -DBUILD_TESTING:BOOL=OFF ${{ inputs.itk-cmake-options }} -GNinja ../ITK + ninja + + - name: Build ITK + if: matrix.os == 'windows-2019' + run: | + cd .. + mkdir ITK-build + cd ITK-build + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + cmake -DCMAKE_C_COMPILER:FILEPATH="${{ matrix.c-compiler }}" -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_CXX_COMPILER="${{ matrix.cxx-compiler }}" -DCMAKE_BUILD_TYPE:STRING=${{ matrix.cmake-build-type }} -DBUILD_TESTING:BOOL=OFF ${{ inputs.itk-cmake-options }} -GNinja ../ITK + ninja + shell: cmd + + - name: Fetch CTest driver script + run: | + curl -L https://raw.githubusercontent.com/InsightSoftwareConsortium/ITK/dashboard/itk_common.cmake -O + + - name: Configure CTest script + shell: bash + run: | + operating_system="${{ matrix.os }}" + cat > dashboard.cmake << EOF + set(CTEST_SITE "GitHubActions") + file(TO_CMAKE_PATH "\$ENV{GITHUB_WORKSPACE}/.." CTEST_DASHBOARD_ROOT) + file(TO_CMAKE_PATH "\$ENV{GITHUB_WORKSPACE}/" CTEST_SOURCE_DIRECTORY) + file(TO_CMAKE_PATH "\$ENV{GITHUB_WORKSPACE}/../build" CTEST_BINARY_DIRECTORY) + set(dashboard_source_name "${GITHUB_REPOSITORY}") + if((ENV{GITHUB_REF_NAME} MATCHES "master" OR ENV{GITHUB_REF_NAME} MATCHES "main")) + set(branch "-master") + set(dashboard_model "Continuous") + else() + set(branch "-${GITHUB_REF}") + set(dashboard_model "Experimental") + endif() + set(CTEST_BUILD_NAME "${GITHUB_REPOSITORY}-${operating_system}-\${branch}") + set(CTEST_UPDATE_VERSION_ONLY 1) + set(CTEST_TEST_ARGS \${CTEST_TEST_ARGS} PARALLEL_LEVEL \${PARALLEL_LEVEL}) + set(CTEST_BUILD_CONFIGURATION "Release") + set(CTEST_CMAKE_GENERATOR "Ninja") + set(CTEST_CUSTOM_WARNING_EXCEPTION + \${CTEST_CUSTOM_WARNING_EXCEPTION} + # macOS Azure VM Warning + "ld: warning: text-based stub file" + ) + set(dashboard_no_clean 1) + set(ENV{CC} ${{ matrix.c-compiler }}) + set(ENV{CXX} ${{ matrix.cxx-compiler }}) + if(WIN32) + set(ENV{PATH} "\${CTEST_DASHBOARD_ROOT}/ITK-build/bin;\$ENV{PATH}") + endif() + set(dashboard_cache " + ITK_DIR:PATH=\${CTEST_DASHBOARD_ROOT}/ITK-build + BUILD_TESTING:BOOL=ON + ${{ inputs.cmake-options }} + ") + string(TIMESTAMP build_date "%Y-%m-%d") + message("CDash Build Identifier: \${build_date} \${CTEST_BUILD_NAME}") + message("CTEST_SITE = \${CTEST_SITE}") + include(\${CTEST_SCRIPT_DIRECTORY}/itk_common.cmake) + EOF + cat dashboard.cmake + + - name: Build and test + if: matrix.os != 'windows-2019' + run: | + ctest --output-on-failure -j 2 -V -S dashboard.cmake + + - name: Build and test + if: matrix.os == 'windows-2019' + run: | + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + ctest --output-on-failure -j 2 -V -S dashboard.cmake + shell: cmd diff --git a/.github/workflows/build-test-package-python.yml b/.github/workflows/build-test-package-python.yml new file mode 100644 index 0000000..5c9e8ba --- /dev/null +++ b/.github/workflows/build-test-package-python.yml @@ -0,0 +1,178 @@ +name: 'Build, Test, Package ITK Remote Module' + +on: + workflow_call: + inputs: + cmake-options: + required: false + type: string + default: "" + itk-wheel-tag: + required: false + type: string + default: 'v5.3rc04.post3' + secrets: + pypi_password: + required: false # Packages will not be uploaded to PyPI if not set + +jobs: + build-linux-python-packages: + runs-on: ubuntu-20.04 + strategy: + max-parallel: 2 + matrix: + python-version: [37, 38, 39, 310] + + steps: + - uses: actions/checkout@v2 + + - name: 'Free up disk space' + run: | + # Workaround for https://github.com/actions/virtual-environments/issues/709 + df -h + sudo apt-get clean + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + df -h + + - name: 'Fetch build script' + run: | + curl -L https://raw.githubusercontent.com/InsightSoftwareConsortium/ITKPythonPackage/master/scripts/dockcross-manylinux-download-cache-and-build-module-wheels.sh -O + chmod u+x dockcross-manylinux-download-cache-and-build-module-wheels.sh + + - name: 'Build 🐍 Python 📦 package' + shell: bash + run: | + export ITK_PACKAGE_VERSION=${{ inputs.itk-wheel-tag }} + if [ -z ${{ inputs.cmake-options }}]; then + CMAKE_OPTIONS="" + else + CMAKE_OPTIONS="--cmake_options ${{ inputs.cmake-options }}" + fi + + for tarball in "-manylinux_2_28" "-manylinux2014"; do + rm -rf ITKPythonPackage + export TARBALL_SPECIALIZATION=${tarball} + ./dockcross-manylinux-download-cache-and-build-module-wheels.sh cp${{ matrix.python-version }} $CMAKE_OPTIONS + done + + - name: Publish Python package as GitHub Artifact + uses: actions/upload-artifact@v1 + with: + name: LinuxWheel${{ matrix.python-version }} + path: dist + + build-macos-python-packages: + runs-on: macos-11 + strategy: + max-parallel: 2 + + steps: + - uses: actions/checkout@v2 + + - name: 'Specific XCode version' + run: | + sudo xcode-select -s "/Applications/Xcode_13.2.1.app" + + - name: Get specific version of CMake, Ninja + uses: lukka/get-cmake@v3.18.3 + + - name: 'Fetch build script' + run: | + curl -L https://raw.githubusercontent.com/InsightSoftwareConsortium/ITKPythonPackage/master/scripts/macpython-download-cache-and-build-module-wheels.sh -O + chmod u+x macpython-download-cache-and-build-module-wheels.sh + + - name: 'Build 🐍 Python 📦 package' + shell: bash + run: | + export ITK_PACKAGE_VERSION=${{ inputs.itk-wheel-tag }} + export MACOSX_DEPLOYMENT_TARGET=10.9 + if [ -z ${{ inputs.cmake-options }}]; then + CMAKE_OPTIONS="" + else + CMAKE_OPTIONS="--cmake_options ${{ inputs.cmake-options }}" + fi + ./macpython-download-cache-and-build-module-wheels.sh $CMAKE_OPTIONS + + - name: Publish Python package as GitHub Artifact + uses: actions/upload-artifact@v1 + with: + name: MacOSWheels + path: dist + + build-windows-python-packages: + runs-on: windows-2019 + strategy: + max-parallel: 2 + matrix: + python-version-minor: [7, 8, 9, 10] + + steps: + - name: Get specific version of CMake, Ninja + uses: lukka/get-cmake@v3.18.3 + + - uses: actions/checkout@v2 + with: + path: "im" + + - name: 'Install Python' + run: | + $pythonArch = "64" + $pythonVersion = "3.${{ matrix.python-version-minor }}" + iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/scikit-build/scikit-ci-addons/master/windows/install-python.ps1')) + + - name: 'Fetch build dependencies' + shell: bash + run: | + mv im ../../ + cd ../../ + curl -L "https://github.com/InsightSoftwareConsortium/ITKPythonBuilds/releases/download/${{ inputs.itk-wheel-tag }}/ITKPythonBuilds-windows.zip" -o "ITKPythonBuilds-windows.zip" + 7z x ITKPythonBuilds-windows.zip -o/c/P -aoa -r + curl -L "https://data.kitware.com/api/v1/file/5c0ad59d8d777f2179dd3e9c/download" -o "doxygen-1.8.11.windows.bin.zip" + 7z x doxygen-1.8.11.windows.bin.zip -o/c/P/doxygen -aoa -r + curl -L "https://data.kitware.com/api/v1/file/5bbf87ba8d777f06b91f27d6/download/grep-win.zip" -o "grep-win.zip" + 7z x grep-win.zip -o/c/P/grep -aoa -r + + - name: 'Build 🐍 Python 📦 package' + shell: cmd + run: | + cd ../../im + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + set PATH=C:\P\grep;%PATH% + set CC=cl.exe + set CXX=cl.exe + C:\Python3${{ matrix.python-version-minor }}-x64\python.exe C:\P\IPP\scripts\windows_build_module_wheels.py --py-envs "3${{ matrix.python-version-minor }}-x64" --no-cleanup + + - name: Publish Python package as GitHub Artifact + uses: actions/upload-artifact@v1 + with: + name: WindowsWheel3.${{ matrix.python-version-minor }} + path: ../../im/dist + + publish-python-packages-to-pypi: + needs: + - build-linux-python-packages + - build-macos-python-packages + - build-windows-python-packages + runs-on: ubuntu-18.04 + + steps: + - name: Download Python Packages + uses: actions/download-artifact@v2 + + - name: Prepare packages for upload + run: | + ls -R + for d in */; do + mv ${d}/*.whl . + done + mkdir dist + mv *.whl dist/ + ls dist + + - name: Publish 🐍 Python 📦 package to PyPI + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.pypi_password }}