conan packages #1101
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: conan packages | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| conan_major_version: | |
| description: 'Conan major version to build' | |
| required: true | |
| default: '1' | |
| type: choice | |
| options: | |
| - '1' | |
| - '2' | |
| publish_dry_run: | |
| description: 'Validate publish workflow without uploading packages' | |
| required: true | |
| default: true | |
| type: boolean | |
| schedule: | |
| - cron: '25 6 * * 4' # 6:25am UTC every Thursday | |
| - cron: '25 8 * * 4' # 8:25am UTC every Thursday, Conan 2 | |
| env: | |
| conan1_version: 1.66.0 | |
| conan2_version: '>=2,<3' | |
| # Pin the macOS/iOS toolchain so published binaries (and their LTO bitcode) | |
| # stay linkable by downstream consumers instead of drifting with the runner | |
| # image's default Xcode. Must match a version installed on the runner. | |
| xcode_version: '16.4' | |
| jobs: | |
| generate-matrix: | |
| name: generate build matrix | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix-json: ${{ steps.generate-matrix.outputs.matrix }} | |
| conan_major_version: ${{ steps.select-conan-version.outputs.conan_major_version }} | |
| steps: | |
| - name: Select Conan version | |
| id: select-conan-version | |
| shell: pwsh | |
| run: | | |
| $ConanMajorVersion = '${{ inputs.conan_major_version }}' | |
| if ([string]::IsNullOrWhiteSpace($ConanMajorVersion)) { | |
| if ('${{ github.event_name }}' -eq 'schedule' -and '${{ github.event.schedule }}' -eq '25 8 * * 4') { | |
| $ConanMajorVersion = '2' | |
| } else { | |
| $ConanMajorVersion = '1' | |
| } | |
| } | |
| echo "conan_major_version=$ConanMajorVersion" >> $Env:GITHUB_OUTPUT | |
| - name: create build matrix | |
| id: generate-matrix | |
| shell: pwsh | |
| env: | |
| CONAN_MAJOR_VERSION: ${{ steps.select-conan-version.outputs.conan_major_version }} | |
| run: | | |
| $Jobs = @() | |
| if ($Env:CONAN_MAJOR_VERSION -eq '2') { | |
| @('windows', 'macos', 'linux', 'ios', 'iossimulator', 'android') | Foreach-Object { | |
| $Platform = $_ | |
| $Architectures = if ($Platform -Eq 'iossimulator') { @('arm64') } else { @('x86_64', 'aarch64') } | |
| if ($Platform -Eq 'android') { | |
| $Architectures += 'arm' | |
| $Architectures += 'x86' | |
| } | |
| $Architectures | ForEach-Object { | |
| $Architecture = $_ | |
| $BuildTypes = @('Debug', 'Release') | |
| if ($Platform -Eq 'windows' -Or $Platform -Eq 'macos' -Or $Platform -Eq 'android') { | |
| $BuildTypes += 'RelWithDebInfo' | |
| } | |
| $BuildTypes | ForEach-Object { | |
| $BuildType = $_ | |
| $Job = @{ | |
| name = "[conan2-$Platform-$Architecture-$BuildType]" | |
| arch = $Architecture | |
| build_type = $BuildType | |
| os = $Platform | |
| runner = switch ($Platform) { | |
| 'windows' { 'windows-2022' } | |
| { @('macos', 'ios', 'iossimulator') -contains $_ } { 'macos-15' } | |
| { @('linux', 'android') -contains $_ } { 'ubuntu-22.04' } | |
| } | |
| } | |
| if ($Platform -Eq 'macos' -And $Architecture -Eq 'x86_64') { | |
| $Job.runner = 'macos-15-intel' | |
| } | |
| if ($Platform -Eq 'linux') { | |
| @('ubuntu-20.04', 'ubuntu-18.04', 'ubuntu-22.04') | ForEach-Object { | |
| $LinuxJob = $Job.Clone() | |
| $LinuxJob['distro'] = $_ | |
| $LinuxJob['name'] = "[conan2-$($LinuxJob['distro'])-$Architecture-$BuildType]" | |
| $Jobs += $LinuxJob | |
| } | |
| } else { | |
| $Jobs += $Job | |
| } | |
| } | |
| } | |
| } | |
| echo "matrix=$(ConvertTo-JSON -Compress -InputObject @($Jobs))" >> $Env:GITHUB_OUTPUT | |
| return | |
| } | |
| @('windows', 'macos', 'linux', 'ios', 'iossimulator', 'android') | Foreach-Object { | |
| $Platform = $_ | |
| $Architectures = if ($Platform -Eq 'iossimulator') { @('arm64') } else { @('x86_64', 'aarch64') } | |
| if($Platform -Eq 'android') { | |
| $Architectures += 'arm' | |
| $Architectures += 'x86' | |
| } | |
| $Architectures | ForEach-Object { | |
| $Architecture = $_ | |
| $BuildTypes = @('Debug', 'Release') | |
| if ($Platform -Eq "windows" -Or $Platform -Eq "macos" -Or $Platform -Eq "Android") { | |
| $BuildTypes += "RelWithDebInfo" | |
| } | |
| $BuildTypes | ForEach-Object { | |
| $BuildType = $_ | |
| $Job = @{ | |
| name = "[$Platform-$Architecture-$BuildType]" | |
| arch = $Architecture | |
| build_type = $BuildType | |
| os = $Platform | |
| runner = switch ($Platform) { | |
| "windows" { "windows-2022" } | |
| { @("macos", "ios", "iossimulator") -contains $_ } { "macos-15" } | |
| { @("linux", "android") -contains $_ } { "ubuntu-22.04" } | |
| } | |
| } | |
| if ($Platform -Eq "macos" -And $Architecture -Eq "x86_64") { | |
| $Job.runner = "macos-15-intel" | |
| } | |
| $Jobs += $Job | |
| if ($Platform -Eq "linux") { | |
| # default distro target | |
| $Job["distro"] = "ubuntu-20.04" | |
| $Job["name"] = "[$($Job["distro"])-$Architecture-$BuildType]" | |
| $Job = $Job.Clone() | |
| $Job["distro"] = "ubuntu-18.04" | |
| $Job["name"] = "[$($Job["distro"])-$Architecture-$BuildType]" | |
| $Jobs += $Job | |
| $Job = $Job.Clone() | |
| $Job["distro"] = "ubuntu-22.04" | |
| $Job["name"] = "[$($Job["distro"])-$Architecture-$BuildType]" | |
| $Jobs += $Job | |
| } | |
| } | |
| } | |
| } | |
| echo "matrix=$(ConvertTo-JSON -Compress -InputObject @($Jobs))" >> $Env:GITHUB_OUTPUT | |
| build: | |
| name: ${{matrix.name}} | |
| runs-on: ${{matrix.runner}} | |
| needs: [generate-matrix] | |
| concurrency: | |
| group: conan-${{ needs.generate-matrix.outputs.conan_major_version }}-${{ github.ref }}-${{matrix.name}} | |
| cancel-in-progress: true | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJson(needs.generate-matrix.outputs.matrix-json) }} | |
| steps: | |
| - name: Check out ${{ github.repository }} | |
| uses: actions/checkout@v6 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v4 | |
| with: | |
| image: tonistiigi/binfmt:qemu-v7.0.0-28 # https://github.com/docker/setup-qemu-action/issues/198 | |
| if: runner.os == 'Linux' | |
| - name: Set up docker buildx | |
| uses: docker/setup-buildx-action@v4 | |
| if: runner.os == 'Linux' | |
| - name: Configure Windows runner | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| choco install --no-progress ninja | |
| choco install --no-progress 7zip | |
| choco install --no-progress python | |
| choco install --no-progress vswhere | |
| choco install --no-progress nasm | |
| # https://github.com/actions/runner-images/issues/11926 | |
| choco install cmake --version 3.31.6 --force | |
| echo "${Env:ProgramFiles}\NASM" | Out-File -FilePath $Env:GITHUB_PATH -Encoding UTF8 -Append | |
| Invoke-WebRequest -Uri 'https://www.tortall.net/projects/yasm/releases/yasm-1.2.0-win64.exe' -OutFile 'yasm.exe' | |
| Move-Item .\yasm.exe "${Env:ProgramFiles}\NASM\yasm.exe" | |
| $SetupArgs = @{ | |
| VenvRoot = "$Env:RUNNER_TEMP\conan-venvs" | |
| ShimDir = "$Env:RUNNER_TEMP\conan-bin" | |
| NoUserPathUpdate = $true | |
| } | |
| if ('${{ needs.generate-matrix.outputs.conan_major_version }}' -eq '2') { | |
| .\scripts\setup-conan-venvs.ps1 @SetupArgs -Conan2Version "${{ env.conan2_version }}" -SkipConan1 | |
| echo "CONAN_HOME=C:/tmp/.conan2" >> $Env:GITHUB_ENV | |
| } else { | |
| .\scripts\setup-conan-venvs.ps1 @SetupArgs -Conan1Version "${{ env.conan1_version }}" -SkipConan2 | |
| echo "CONAN_USER_HOME=C:/tmp" >> $Env:GITHUB_ENV | |
| } | |
| echo $PSVersionTable | |
| - name: Configure macOS runner | |
| if: runner.os == 'macOS' | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.10' | |
| # Pin Xcode for every macOS job (device, simulator and x86_64) so the | |
| # toolchain is deterministic. Silently falling back to the runner's | |
| # default Xcode lets newer toolchains ship bitcode/SDKs that older | |
| # consumers can't link (e.g. RelWithDebInfo LTO across mismatched | |
| # Xcode versions), so fail loudly if the pinned version is missing. | |
| - name: Select Xcode | |
| if: runner.os == 'macOS' | |
| run: | | |
| XCODE_APP="/Applications/Xcode_${{ env.xcode_version }}.app" | |
| if [ ! -d "$XCODE_APP" ]; then | |
| echo "::error::$XCODE_APP is not installed on this runner. Installed Xcodes:" | |
| ls -d /Applications/Xcode_*.app 2>/dev/null || true | |
| exit 1 | |
| fi | |
| sudo xcode-select --switch "$XCODE_APP" | |
| xcodebuild -version | |
| - name: Configure macOS runner | |
| if: runner.os == 'macOS' | |
| env: | |
| CMAKE_OSX_DEPLOYMENT_TARGET: "10.12" | |
| run: | | |
| if brew help trust >/dev/null 2>&1; then | |
| brew trust aws/tap azure/bicep || true | |
| fi | |
| brew install nasm yasm | |
| if [ "${{ needs.generate-matrix.outputs.conan_major_version }}" = "2" ]; then | |
| pwsh ./scripts/setup-conan-venvs.ps1 -Conan2Version "${{ env.conan2_version }}" -SkipConan1 -VenvRoot "$RUNNER_TEMP/conan-venvs" -ShimDir "$RUNNER_TEMP/conan-bin" -NoUserPathUpdate | |
| echo "CONAN_HOME=/tmp/.conan2" >> $GITHUB_ENV | |
| else | |
| pwsh ./scripts/setup-conan-venvs.ps1 -Conan1Version "${{ env.conan1_version }}" -SkipConan2 -VenvRoot "$RUNNER_TEMP/conan-venvs" -ShimDir "$RUNNER_TEMP/conan-bin" -NoUserPathUpdate | |
| echo "CONAN_USER_HOME=/tmp" >> $GITHUB_ENV | |
| fi | |
| sudo rm -rf /Library/Developer/CommandLineTools | |
| - name: Configure Linux runner | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get -o Acquire::Retries=3 update | |
| sudo apt-get install ninja-build xz-utils nasm yasm python3 python3-pip python3-venv python3-wget python3-setuptools | |
| # https://github.com/actions/runner-images/issues/11926 | |
| sudo apt-get update | |
| sudo apt-get install cmake=3.22.1-1ubuntu1.22.04.2 | |
| sudo ln -sf /usr/bin/cmake /usr/local/bin/cmake | |
| if [ "${{ needs.generate-matrix.outputs.conan_major_version }}" = "2" ]; then | |
| pwsh ./scripts/setup-conan-venvs.ps1 -Conan2Version "${{ env.conan2_version }}" -SkipConan1 -VenvRoot "$RUNNER_TEMP/conan-venvs" -ShimDir "$RUNNER_TEMP/conan-bin" -NoUserPathUpdate | |
| echo "CONAN_HOME=/tmp/.conan2" >> $GITHUB_ENV | |
| else | |
| pwsh ./scripts/setup-conan-venvs.ps1 -Conan1Version "${{ env.conan1_version }}" -SkipConan2 -VenvRoot "$RUNNER_TEMP/conan-venvs" -ShimDir "$RUNNER_TEMP/conan-bin" -NoUserPathUpdate | |
| echo "CONAN_USER_HOME=/tmp" >> $GITHUB_ENV | |
| fi | |
| - name: Setup LLVM | |
| uses: Devolutions/actions-public/setup-llvm@v1 | |
| if: runner.os == 'linux' | |
| with: | |
| version: "18.1.8" | |
| - name: Configure Android NDK | |
| if: matrix.os == 'android' | |
| run: | | |
| ## Pin the cmake version for now, libpng builds are failing on Android x86-64 | |
| ## Probably related to cmake 3.25 setting LINUX | |
| ## https://gitlab.kitware.com/cmake/cmake/-/issues/24196 | |
| ## https://gitlab.kitware.com/cmake/cmake/-/merge_requests/7963 | |
| pip3 install cmake==3.24.2 | |
| cmake --version | |
| - name: Configure conan environment | |
| shell: pwsh | |
| run: | | |
| if ('${{ needs.generate-matrix.outputs.conan_major_version }}' -eq '2') { | |
| conan2 profile detect --force | |
| } else { | |
| conan1 config init | |
| conan1 config install ./settings | |
| conan1 remote disable conancenter | |
| } | |
| $ConanManifestTime = $(git log -1 --pretty=format:%ct) | |
| echo "CONAN_MANIFEST_TIME=$ConanManifestTime" >> $Env:GITHUB_ENV | |
| - name: Build conan packages | |
| shell: pwsh | |
| run: | | |
| if ('${{ needs.generate-matrix.outputs.conan_major_version }}' -eq '2') { | |
| if ("${{ matrix.distro }}") { | |
| ./scripts/build-conan2.ps1 -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -BuildType ${{ matrix.build_type }} -Distribution ${{ matrix.distro }} | |
| } else { | |
| ./scripts/build-conan2.ps1 -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -BuildType ${{ matrix.build_type }} | |
| } | |
| } else { | |
| if ("${{ matrix.distro }}") { | |
| ./build.ps1 -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -BuildType ${{ matrix.build_type }} -Distribution ${{ matrix.distro }} | |
| } else { | |
| ./build.ps1 -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -BuildType ${{ matrix.build_type }} | |
| } | |
| } | |
| - name: Package conan cache | |
| id: package-conan-cache | |
| shell: pwsh | |
| run: | | |
| if ("${{ matrix.distro }}") { | |
| $PACKAGE_NAME="conan${{ needs.generate-matrix.outputs.conan_major_version }}-${{ matrix.arch }}-${{ matrix.distro }}-${{ matrix.build_type }}" | |
| } else { | |
| $PACKAGE_NAME="conan${{ needs.generate-matrix.outputs.conan_major_version }}-${{ matrix.arch }}-${{ matrix.os }}-${{ matrix.build_type }}" | |
| } | |
| if ('${{ needs.generate-matrix.outputs.conan_major_version }}' -eq '2') { | |
| conan2 cache clean '*' --source --build --download --temp --backup-sources | |
| $ConanHome = $Env:CONAN_HOME | |
| if ([string]::IsNullOrWhiteSpace($ConanHome)) { | |
| $ConanHome = Join-Path $HOME ".conan2" | |
| } | |
| $ConanHomeParent = Split-Path $ConanHome -Parent | |
| $ConanHomeName = Split-Path $ConanHome -Leaf | |
| tar -czf "${PACKAGE_NAME}.tar.gz" -C "$ConanHomeParent" "$ConanHomeName" | |
| } else { | |
| conan1 remove --locks | |
| $CONAN_DATA = Join-Path $Env:CONAN_USER_HOME ".conan" "data" | |
| $RemoveList = Get-ChildItem "${CONAN_DATA}" -Include @("build","source") -Directory -Depth 4 -Recurse -Name | |
| $RemoveList | ForEach-Object { Remove-Item -Path "$CONAN_DATA/$_" -Recurse -Force } | |
| $ConanManifests = Get-ChildItem $CONAN_DATA -Recurse -Include "conanmanifest.txt" | |
| $ConanManifestTime = $Env:CONAN_MANIFEST_TIME | |
| foreach ($ManifestFile in $ConanManifests) { | |
| $Manifest = Get-Content $ManifestFile | |
| $Manifest[0] = $ConanManifestTime | |
| $Manifest | Out-File $ManifestFile | |
| } | |
| tar -czf "${PACKAGE_NAME}.tar.gz" -C "$Env:CONAN_USER_HOME" ".conan" | |
| } | |
| echo "package_name=$PACKAGE_NAME" >> $Env:GITHUB_OUTPUT | |
| - name: Upload conan cache | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ steps.package-conan-cache.outputs.package_name }} | |
| path: ${{ steps.package-conan-cache.outputs.package_name }}.tar.gz | |
| publish: | |
| needs: | |
| - generate-matrix | |
| - build | |
| if: github.event_name != 'schedule' | |
| uses: ./.github/workflows/conan-publish.yml | |
| with: | |
| conan_major_version: ${{ needs.generate-matrix.outputs.conan_major_version }} | |
| dry_run: ${{ inputs.publish_dry_run }} | |
| secrets: inherit | |
| notify: | |
| name: Notify failure | |
| runs-on: ubuntu-latest | |
| if: ${{ always() && contains(needs.*.result, 'failure') && github.event_name == 'schedule' }} | |
| needs: | |
| - generate-matrix | |
| - build | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_ARCHITECTURE }} | |
| SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK | |
| steps: | |
| - name: Send slack notification | |
| id: slack | |
| uses: slackapi/slack-github-action@v1.26.0 | |
| with: | |
| payload: | | |
| { | |
| "blocks": [ | |
| { | |
| "type": "section", | |
| "text": { | |
| "type": "mrkdwn", | |
| "text": "*${{ github.repository }}* :fire::fire::fire::fire::fire: \n The scheduled build for *${{ github.repository }}* is <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|broken>" | |
| } | |
| } | |
| ] | |
| } |