From 9448e337414424a11e836974c730bbfafedf469b Mon Sep 17 00:00:00 2001 From: Roberto Rossini <71787608+robomics@users.noreply.github.com> Date: Wed, 16 Oct 2024 20:57:11 +0200 Subject: [PATCH] Add build-conan-deps.yml workflow [no ci] --- .github/workflows/build-conan-deps.yml | 393 +++++++++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 .github/workflows/build-conan-deps.yml diff --git a/.github/workflows/build-conan-deps.yml b/.github/workflows/build-conan-deps.yml new file mode 100644 index 0000000..0871540 --- /dev/null +++ b/.github/workflows/build-conan-deps.yml @@ -0,0 +1,393 @@ +# Copyright (C) 2024 Roberto Rossini +# SPDX-License-Identifier: MIT + +name: Build dependencies with Conan + +on: + workflow_call: + outputs: + conan-key: + description: "Conan packages" + value: ${{ jobs.collect-outputs.outputs.conan-key }} + conan-home: + description: "Conan home folder" + value: ${{ jobs.collect-outputs.outputs.conan-home }} + + inputs: + conan-version: + default: "2.8.*" + type: string + required: false + description: "Conan version to be installed with pip." + cppstd: + default: "17" + type: string + required: false + description: "Value to pass to compiler.cppstd." + os: + type: string + required: true + description: "OS used to build Conan deps." + arch: + type: string + required: true + description: "Architecture used to build deps." + +defaults: + run: + shell: bash + +jobs: + build-deps-linux: + if: startsWith(inputs.os, 'linux') + name: Build dependencies with Conan (${{ inputs.os }}) + runs-on: ubuntu-latest + + container: + image: quay.io/pypa/manylinux_2_28_${{ inputs.arch }} + + env: + CONAN_HOME: "${{ github.workspace }}/.conan2/" + + outputs: + conan-key: ${{ steps.generate-cache-key.outputs.conan-key }} + conan-home: ${{ env.CONAN_HOME }} + + steps: + - name: Checkout workflow + uses: actions/checkout@v4 + with: + ref: main + path: hictkpy-workflow + + - name: Checkout conanfile.py + uses: actions/checkout@v4 + with: + path: hictkpy-conanfile + + - name: Stage input files + run: | + # This is required because sparse cloning does not seem to work reliably + mkdir -p .github/workflows/ + mv hictkpy-workflow/.github/workflows/build-conan-deps.yml .github/workflows/ + mv hictkpy-conanfile/conanfile.py . + rm -rf hictkpy-workflow hictkpy-conanfile + + - name: Setup build deps + run: | + echo /opt/python/cp312-cp312/bin/ >> "$GITHUB_PATH" + pip install "conan==${{ inputs.conan-version }}" + conan profile detect --force + dnf install -y zstd + + - name: Generate cache key + id: generate-cache-key + run: | + set -u + set -e + + hash="${{ hashFiles('.github/workflows/build-conan-deps.yml', 'conanfile.py') }}" + + compiler="$(cc --version | head -n 1 | tr -c '[:alnum:]._-' '-' | sed 's/-\+/-/g' | sed 's/-$//')" + + suffix="${{ inputs.os }}-${{ inputs.arch }}-$compiler-c++${{ inputs.cppstd }}-$hash" + + echo "conan-key=conan-$suffix" | tee -a "$GITHUB_OUTPUT" + + - name: Restore package cache + id: cache-conan + uses: actions/cache/restore@v4 + with: + key: ${{ steps.generate-cache-key.outputs.conan-key }} + path: ${{ env.CONAN_HOME }}/p + + - name: Clean Conan cache (pre-build) + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan cache clean "*" --build + conan cache clean "*" --download + conan cache clean "*" --source + conan remove --confirm "*" + + - name: Install dependencies + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan install conanfile.py \ + --update \ + --build='missing' \ + --build='b2/*' \ + -pr:b=default \ + -pr:h=default \ + -s build_type=Release \ + -s compiler.cppstd=${{ inputs.cppstd }} \ + --options=*/*:shared=False + + - name: Clean Conan cache (post-build) + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan cache clean "*" --build + conan cache clean "*" --download + conan cache clean "*" --source + + - name: Save Conan cache + uses: actions/cache/save@v4 + if: steps.cache-conan.outputs.cache-hit != 'true' + with: + key: ${{ steps.generate-cache-key.outputs.conan-key }} + path: ${{ env.CONAN_HOME }}/p + env: + ZSTD_CLEVEL: 19 + + build-deps-macos: + if: startsWith(inputs.os, 'macos') + name: Build dependencies with Conan (${{ inputs.os }}) + runs-on: ${{ inputs.os }} + + env: + CONAN_HOME: "${{ github.workspace }}/.conan2" + HOMEBREW_NO_AUTO_UPDATE: "1" + + outputs: + conan-key: ${{ steps.generate-cache-key.outputs.conan-key }} + conan-home: ${{ env.CONAN_HOME }} + + steps: + - name: Checkout workflow + uses: actions/checkout@v4 + with: + ref: main + path: hictkpy-workflow + + - name: Checkout conanfile.py + uses: actions/checkout@v4 + with: + path: hictkpy-conanfile + + - name: Stage input files + run: | + # This is required because sparse cloning does not seem to work reliably + mkdir -p .github/workflows/ + mv hictkpy-workflow/.github/workflows/build-conan-deps.yml .github/workflows/ + mv hictkpy-conanfile/conanfile.py . + rm -rf hictkpy-workflow hictkpy-conanfile + + - name: Generate cache key + id: generate-cache-key + run: | + set -u + set -e + + hash="${{ hashFiles('.github/workflows/build-conan-deps.yml', 'conanfile.py') }}" + + compiler="$(cc --version | head -n 1 | tr -c '[:alnum:]._-' '-' | sed 's/-\+/-/g' | sed 's/-$//')" + + suffix="${{ inputs.os }}-${{ inputs.arch }}-$compiler-c++${{ inputs.cppstd }}-$hash" + + echo "conan-key=conan-$suffix" | tee -a "$GITHUB_OUTPUT" + + - name: Restore package cache + id: cache-conan + uses: actions/cache/restore@v4 + with: + key: ${{ steps.generate-cache-key.outputs.conan-key }} + path: ${{ env.CONAN_HOME }}/p + + - uses: actions/setup-python@v5 + if: steps.cache-conan.outputs.cache-hit != 'true' + with: + python-version: "3.12" + + - name: Update build deps + if: steps.cache-conan.outputs.cache-hit != 'true' + run: pip install "conan==${{ inputs.conan-version }}" + + - name: Configure Conan + if: steps.cache-conan.outputs.cache-hit != 'true' + run: conan profile detect --force + + - name: Clean Conan cache (pre-build) + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan cache clean "*" --build + conan cache clean "*" --download + conan cache clean "*" --source + conan remove --confirm "*" + + - name: Install dependencies + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan install conanfile.py \ + --update \ + --build='missing' \ + --build='b2/*' \ + -pr:b=default \ + -pr:h=default \ + -s build_type=Release \ + -s compiler.libcxx=libc++ \ + -s compiler.cppstd=${{ inputs.cppstd }} \ + --options=*/*:shared=False + + - name: Clean Conan cache (post-build) + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan cache clean "*" --build + conan cache clean "*" --download + conan cache clean "*" --source + + - name: Save Conan cache + uses: actions/cache/save@v4 + if: steps.cache-conan.outputs.cache-hit != 'true' + with: + key: ${{ steps.generate-cache-key.outputs.conan-key }} + path: ${{ env.CONAN_HOME }}/p + env: + ZSTD_CLEVEL: 19 + + build-deps-windows: + if: startsWith(inputs.os, 'windows') + name: Build dependencies with Conan (${{ inputs.os }}) + runs-on: ${{ inputs.os }} + + env: + CONAN_HOME: "${{ github.workspace }}\\.conan2" + + outputs: + conan-key: ${{ steps.generate-cache-key.outputs.conan-key }} + conan-home: ${{ env.CONAN_HOME }} + + steps: + - name: Checkout workflow + uses: actions/checkout@v4 + with: + ref: main + path: hictkpy-workflow + + - name: Checkout conanfile.py + uses: actions/checkout@v4 + with: + path: hictkpy-conanfile + + - name: Stage input files + run: | + # This is required because sparse cloning does not seem to work reliably + mkdir -p .github/workflows/ + mv hictkpy-workflow/.github/workflows/build-conan-deps.yml .github/workflows/ + mv hictkpy-conanfile/conanfile.py . + rm -rf hictkpy-workflow hictkpy-conanfile + + - name: Add devtools to PATH + uses: ilammy/msvc-dev-cmd@v1 + + - name: Generate cache key + id: generate-cache-key + run: | + set -u + set -e + + hash="${{ hashFiles('.github/workflows/build-conan-deps.yml', 'conanfile.py') }}" + + cl.exe 1> /dev/null 2> version.txt + compiler="msvc-$(head -n 1 version.txt | grep -o '[[:digit:].]\+' | head -n 1)" + + suffix="${{ inputs.os }}-${{ inputs.arch }}-$compiler-c++${{ inputs.cppstd }}-$hash" + + echo "conan-key=conan-$suffix" | tee -a "$GITHUB_OUTPUT" + + - name: Restore package cache + id: cache-conan + uses: actions/cache/restore@v4 + with: + key: ${{ steps.generate-cache-key.outputs.conan-key }} + path: ${{ env.CONAN_HOME }}\p + + - uses: actions/setup-python@v5 + if: steps.cache-conan.outputs.cache-hit != 'true' + with: + python-version: "3.12" + + - name: Update build deps + if: steps.cache-conan.outputs.cache-hit != 'true' + run: pip install "conan==${{ inputs.conan-version }}" + + - name: Configure Conan + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan profile detect --force + conan_profile="$(conan profile path default)" + + sed -i 's/compiler\.cppstd=.*/compiler.cppstd=${{ inputs.cppstd }}/' "$conan_profile" + + - name: Clean Conan cache (pre-build) + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan cache clean "*" --build + conan cache clean "*" --download + conan cache clean "*" --source + conan remove --confirm "*" + + - name: Install dependencies + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan install conanfile.py \ + --update \ + --build='missing' \ + --build='b2/*' \ + -pr:b=default \ + -pr:h=default \ + -s build_type=Release \ + -s compiler.runtime_type=Release \ + -s compiler.cppstd=${{ inputs.cppstd }} \ + --options=*/*:shared=False + + - name: Clean Conan cache (post-build) + if: steps.cache-conan.outputs.cache-hit != 'true' + run: | + conan cache clean "*" --build + conan cache clean "*" --download + conan cache clean "*" --source + + - name: Save Conan cache + uses: actions/cache/save@v4 + if: steps.cache-conan.outputs.cache-hit != 'true' + with: + key: ${{ steps.generate-cache-key.outputs.conan-key }} + path: ${{ env.CONAN_HOME }}\p + env: + ZSTD_CLEVEL: 19 + + collect-outputs: + name: Collect output + runs-on: ubuntu-latest + if: always() + needs: + - build-deps-macos + - build-deps-linux + - build-deps-windows + + outputs: + conan-key: ${{ steps.collect-cache-key.outputs.conan-key }} + conan-home: ${{ steps.collect-cache-key.outputs.conan-home }} + + steps: + - name: Collect job outputs + id: collect-cache-key + run: | + if [ "${{ needs.build-deps-linux.result }}" == 'success' ]; then + echo "conan-key=${{ needs.build-deps-linux.outputs.conan-key }}" | tee -a "$GITHUB_OUTPUT" + echo "conan-home=${{ needs.build-deps-linux.outputs.conan-home }}" | tee -a "$GITHUB_OUTPUT" + exit 0 + fi + + if [ "${{ needs.build-deps-macos.result }}" == 'success' ]; then + echo "conan-key=${{ needs.build-deps-macos.outputs.conan-key }}" | tee -a "$GITHUB_OUTPUT" + echo "conan-home=${{ needs.build-deps-macos.outputs.conan-home }}" | tee -a "$GITHUB_OUTPUT" + exit 0 + fi + + if [ "${{ needs.build-deps-windows.result }}" == 'success' ]; then + echo "conan-key=${{ needs.build-deps-windows.outputs.conan-key }}" | tee -a "$GITHUB_OUTPUT" + echo "conan-home=${{ needs.build-deps-windows.outputs.conan-home }}" | tee -a "$GITHUB_OUTPUT" + exit 0 + fi + + exit 1