name: CMake build on: # For the manual run. workflow_dispatch: # To run as dependent. workflow_call: workflow_run: workflows: ['Build and push Docker image'] branches: [master] types: - completed push: branches: [ "master" ] paths: - 'knp/**' - 'examples/**' - 'CMakeLists.txt' - '.github/workflows/cmake-build.yml' - '!/doc/**' - '!/docker/**' - '!/tools/**' - '!/ci/**' pull_request: branches: [ "master" ] jobs: linux_build: runs-on: ${{ matrix.os }} strategy: # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. fail-fast: false # Set up a matrix to run the following configurations: # 1. # 2. matrix: os: [ubuntu-24.04, ubuntu-24.04-arm] build_type: [Debug] c_compiler: [gcc, clang] # arch: [amd64, arm64] include: - os: ubuntu-24.04 arch: amd64 build_threads_count: 8 - os: ubuntu-24.04-arm arch: arm64 build_threads_count: 6 - c_compiler: gcc cpp_compiler: g++ - c_compiler: clang cpp_compiler: clang++ steps: - uses: actions/checkout@v4 - name: Set git options run: git config --global --add safe.directory "*" shell: bash - name: Set reusable strings # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. id: strings shell: bash run: | echo "build-output-dir=build_${{ matrix.c_compiler }}" >> "$GITHUB_OUTPUT" - name: Set environment run: | echo "KNP_IMAGE_VERSION=v2.0.${{ github.run_number }}" >> $GITHUB_ENV echo "KNP_BUILD_IMAGE_NAME=${{ vars.DOCKERHUB_LOGIN }}/knp-build-image:latest" >> $GITHUB_ENV # Install support for non-x86 emulation in Docker via QEMU. # Platforms: linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, # linux/386, linux/arm/v7, linux/arm/v6 # - name: Set-up Docker ARM emulation # if: matrix.arch == 'arm64' # run: | # sudo apt-get update -q -y # sudo apt-get -qq install -y qemu-system-arm qemu-user-static # docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes - name: Show build parameters run: | echo "KNP_IMAGE_VERSION = ${{ steps.strings.outputs.KNP_IMAGE_VERSION }}" echo "KNP_BUILD_IMAGE_NAME = ${{ env.KNP_BUILD_IMAGE_NAME }}" - name: Configure run: > docker run --platform=linux/${{ matrix.arch }} --rm -v ${{ github.workspace }}:/KNP -w /KNP kasperskydh/knp-build-image cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DKNP_PYTHON_BUILD_WHEEL=ON -S . - name: Build run: docker run --platform=linux/${{ matrix.arch }} --rm -v ${{ github.workspace }}:/KNP -w /KNP ${{ env.KNP_BUILD_IMAGE_NAME }} cmake --build ${{ steps.strings.outputs.build-output-dir }} --parallel ${{ matrix.build_threads_count }} timeout-minutes: 180 - name: C++ tests run: docker run --platform=linux/${{ matrix.arch }} --rm -v ${{ github.workspace }}:/KNP -w /KNP/${{ steps.strings.outputs.build-output-dir }}/knp/tests ${{ env.KNP_BUILD_IMAGE_NAME }} ctest -V -E "Cuda*" timeout-minutes: 180 # TODO: run before configure? - name: Analyze C++ code with lizard run: docker run --platform=linux/${{ matrix.arch }} --rm -v ${{ github.workspace }}:/KNP -w /KNP ${{ env.KNP_BUILD_IMAGE_NAME }} ci/run_lizard.py continue-on-error: true - name: Analyze Python code with PyLint run: docker run --platform=linux/${{ matrix.arch }} --rm -v ${{ github.workspace }}:/KNP -w /KNP ${{ env.KNP_BUILD_IMAGE_NAME }} ci/run_pylint.py ${{ steps.strings.outputs.build-output-dir }}/knp_python_framework/knp ${{ steps.strings.outputs.build-output-dir }} - name: Analyze Python code with Bandit run: docker run --platform=linux/${{ matrix.arch }} --rm -v ${{ github.workspace }}:/KNP -w /KNP ${{ env.KNP_BUILD_IMAGE_NAME }} /usr/bin/bandit -r -lll -x ".*fixtures" /KNP/knp/python-framework ${{ steps.strings.outputs.build-output-dir }}/knp_python_framework/ -o ${{ steps.strings.outputs.build-output-dir }}/bandit.log - name: Python tests run: docker run --platform=linux/${{ matrix.arch }} --rm -v ${{ github.workspace }}:/KNP -w /KNP/${{ steps.strings.outputs.build-output-dir }}/knp_python_framework ${{ env.KNP_BUILD_IMAGE_NAME }} pytest - name: Create deb packages run: docker run --platform=linux/${{ matrix.arch }} --rm -v ${{ github.workspace }}:/KNP -w /KNP/${{ steps.strings.outputs.build-output-dir }} ${{ env.KNP_BUILD_IMAGE_NAME }} cpack -G DEB timeout-minutes: 180 - name: Copy SDK image files to build directory if: matrix.c_compiler == 'gcc' run: sudo cp -a ${{ github.workspace }}/docker/sdk-image/** ${{ steps.strings.outputs.build-output-dir }}/_packages/ - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_LOGIN }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Create SDK Docker image if: matrix.c_compiler == 'gcc' uses: docker/build-push-action@v7 with: platforms: linux/${{ matrix.arch }} context: ${{ steps.strings.outputs.build-output-dir }}/_packages/ load: true push: true build-args: | KNP_IMAGE_VERSION=latest KNP_VERSION=2.0.0 tags: | ${{ vars.DOCKERHUB_LOGIN }}/knp-sdk-image:${{ env.KNP_IMAGE_VERSION }} ${{ vars.DOCKERHUB_LOGIN }}/knp-sdk-image:latest timeout-minutes: 180 continue-on-error: false - name: Upload deb packages if: matrix.c_compiler == 'gcc' uses: actions/upload-artifact@v7 with: name: pkg-deb-${{ matrix.arch }} path: ${{ steps.strings.outputs.build-output-dir }}/_packages/knp-*.deb - name: Upload Python wheel if: matrix.c_compiler == 'gcc' uses: actions/upload-artifact@v7 with: name: pkg-python-${{ matrix.arch }} path: ${{ steps.strings.outputs.build-output-dir }}/knp_python_framework/dist/knp-*.whl non_linux_build: runs-on: ${{ matrix.os }} strategy: # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. fail-fast: false # Set up a matrix to run: matrix: os: [macos-26, windows-2022] build_type: [Debug] c_compiler: [clang, cl] include: - os: macos-26 c_compiler: clang cpp_compiler: clang++ boost_install_dir: /Users/runner/work/boost/knp boost_version: 1.81.0 boost_platform_version: 26 boost_toolset: clang - os: windows-2022 c_compiler: cl cpp_compiler: cl boost_install_dir: C:/ boost_version: 1.81.0 boost_platform_version: 2022 boost_toolset: msvc exclude: - os: windows-2022 c_compiler: clang - os: macos-26 c_compiler: cl steps: # NTFS protection must be enabled to prevent files with names containing '\'. # - run: git config --global core.protectNTFS false - uses: actions/checkout@v4 - name: Set git options run: git config --global --add safe.directory "*" shell: bash - name: Set reusable strings # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. id: strings shell: bash run: | echo "build-output-dir=build" >> "$GITHUB_OUTPUT" - name: Install Boost uses: MarkusJx/install-boost@v2 id: install-boost with: boost_version: ${{ matrix.boost_version }} boost_install_dir: ${{ matrix.boost_install_dir }} platform_version: ${{ matrix.boost_platform_version }} toolset: ${{ matrix.boost_toolset }} - name: Install OpenCV via vcpkg if: matrix.c_compiler == 'cl' run: vcpkg install opencv:x64-windows - name: Configure CMake env: BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }} run: > cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -S . - name: Build # Build with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} --parallel 8 timeout-minutes: 180 - name: Test run: ctest --build-config ${{ matrix.build_type }} -V timeout-minutes: 180 working-directory: ${{ steps.strings.outputs.build-output-dir }}/knp/tests - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: ${{ matrix.os }}_executables path: ${{ steps.strings.outputs.build-output-dir }}/bin publish: needs: [linux_build, non_linux_build] runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Download build artifacts uses: actions/download-artifact@v4 with: pattern: pkg-* - shell: bash run: | ls -1 - name: Create new release id: create_release if: startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v2 env: # This token is provided by Actions. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: Release ${{ github.ref }} files: | pkg-deb pkg-python LICENSE.txt NOTICE.txt body: | Release creating added to CI draft: false prerelease: false # - name: Publish package to the PyPI # Already on push in the master branch. # if: startsWith(github.head_ref, 'master') # if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') # uses: pypa/gh-action-pypi-publish@release/v1 # with: # password: ${{ secrets.PYPI_API_TOKEN }} # repository_url: https://upload.pypi.org/legacy/ # skip_existing: true # print_hash: true