ci: harden native ARM64 build and smoke-test startup #18
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: Build Windows ARM64 Native | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: write | |
| env: | |
| qbt_version: "5.2.3" | |
| qt_version: "6.10.3" | |
| vcpkg_triplet: "arm64-windows-static-release" | |
| jobs: | |
| build-windows-arm64-native: | |
| name: Build Native ARM64 (${{ matrix.libt_variant }}) | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - libt_variant: lt12 | |
| libt_ref: c5ff6c3186a92ddec01f6f0a8146aaedb4a1c3f9 | |
| boost_version: "1.86.0" | |
| libt_version_display: "1.2.20+gitc5ff6c3186" | |
| archive_suffix: "" | |
| artifact_name: arm64-native-lt12 | |
| - libt_variant: lt20 | |
| libt_ref: da7a68a440b7abf4eb1a237df7168be0b8b17084 | |
| boost_version: "1.91.0" | |
| libt_version_display: "2.0.13+gitda7a68a440" | |
| archive_suffix: "_lt20" | |
| artifact_name: arm64-native-lt20 | |
| env: | |
| boost_root: "${{ github.workspace }}/../boost" | |
| libtorrent_root: "${{ github.workspace }}/../libtorrent-msvc-arm64" | |
| qt_target_root: "${{ github.workspace }}/../qt-msvc-arm64" | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup MSVC cross toolchain | |
| uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: amd64_arm64 | |
| - name: Install build tools | |
| shell: pwsh | |
| run: | | |
| choco install ninja | |
| - name: Setup vcpkg | |
| uses: lukka/run-vcpkg@v11 | |
| with: | |
| vcpkgGitCommitId: '84bab45d415d22042bd0b9081aea57f362da3f35' | |
| vcpkgDirectory: C:/vcpkg | |
| doNotUpdateVcpkg: true | |
| - name: Normalize vcpkg paths | |
| shell: pwsh | |
| run: | | |
| if (-not $env:RUNVCPKG_VCPKG_ROOT) { | |
| throw "RUNVCPKG_VCPKG_ROOT is not set" | |
| } | |
| $vcpkgRoot = $env:RUNVCPKG_VCPKG_ROOT -replace '\\', '/' | |
| "VCPKG_ROOT=$vcpkgRoot" >> $env:GITHUB_ENV | |
| "VCPKG_CMAKE_ROOT=$vcpkgRoot" >> $env:GITHUB_ENV | |
| - name: Install vcpkg dependencies | |
| shell: pwsh | |
| run: | | |
| $packages = @( | |
| "openssl:${{ env.vcpkg_triplet }}", | |
| "zlib:${{ env.vcpkg_triplet }}" | |
| ) | |
| & "$env:VCPKG_ROOT/vcpkg.exe" upgrade --no-dry-run | |
| & "$env:VCPKG_ROOT/vcpkg.exe" install --clean-after-build @packages | |
| - name: Build source URLs | |
| shell: pwsh | |
| run: | | |
| $boostVersion = "${{ matrix.boost_version }}" | |
| $boostVersionUnderscored = $boostVersion -replace '\.', '_' | |
| "BOOST_URL=https://archives.boost.io/release/$boostVersion/source/boost_${boostVersionUnderscored}.7z" >> $env:GITHUB_ENV | |
| "QBT_URL=https://github.com/qbittorrent/qBittorrent/archive/refs/tags/release-${{ env.qbt_version }}.tar.gz" >> $env:GITHUB_ENV | |
| - name: Download Boost | |
| shell: pwsh | |
| run: | | |
| aria2c "$env:BOOST_URL" -d "${{ runner.temp }}" -o "boost.7z" | |
| 7z x "${{ runner.temp }}/boost.7z" -o"${{ github.workspace }}/.." | |
| Move-Item "${{ github.workspace }}/../boost_*" "${{ env.boost_root }}" | |
| - name: Install Qt host tools | |
| uses: jurplel/install-qt-action@v4 | |
| with: | |
| aqtversion: '==3.3.*' | |
| version: "${{ env.qt_version }}" | |
| archives: 'qtbase qttools' | |
| set-env: 'false' | |
| dir: 'C:' | |
| - name: Show tool versions | |
| shell: pwsh | |
| run: | | |
| cmake --version | |
| ninja --version | |
| - name: Build Qt for ARM64 | |
| shell: pwsh | |
| run: | | |
| $env:Path = "C:\Qt\${{ env.qt_version }}\msvc2022_64\bin;" + $env:Path | |
| $vcpkgRoot = $env:VCPKG_ROOT | |
| git clone https://github.com/qt/qt5.git qt6 | |
| Set-Location qt6 | |
| git checkout "v${{ env.qt_version }}" | |
| ./configure -init-submodules -submodules qtbase,qtsvg | |
| Remove-Item CMakeCache.txt -ErrorAction SilentlyContinue | |
| ./configure -opensource -confirm-license -nomake tests -nomake examples ` | |
| -static -static-runtime -release -xplatform win32-arm64-msvc ` | |
| -prefix "${{ env.qt_target_root }}" ` | |
| -qt-host-path "C:/Qt/${{ env.qt_version }}/msvc2022_64" ` | |
| -system-zlib -schannel -qt-sqlite -sql-sqlite -no-sql-mysql -no-sql-odbc -no-sql-psql -c++std c++20 -- ` | |
| -DCMAKE_PREFIX_PATH="$vcpkgRoot/installed/${{ env.vcpkg_triplet }}" ` | |
| -DCMAKE_TOOLCHAIN_FILE="$vcpkgRoot/scripts/buildsystems/vcpkg.cmake" ` | |
| -DVCPKG_TARGET_TRIPLET=${{ env.vcpkg_triplet }} | |
| cmake --build . | |
| cmake --install . | |
| - name: Build libtorrent for ARM64 | |
| shell: pwsh | |
| run: | | |
| git init libtorrent | |
| Set-Location libtorrent | |
| git remote add origin https://github.com/arvidn/libtorrent.git | |
| git fetch --depth 1 origin ${{ matrix.libt_ref }} | |
| git checkout FETCH_HEAD | |
| git submodule update --init --recursive --depth 1 | |
| $boostRoot = (Get-Item "${{ env.boost_root }}").FullName.Replace('\\', '/') | |
| New-Item -ItemType Directory -Path "${{ env.libtorrent_root }}" -Force | Out-Null | |
| $libtorrentRoot = [System.IO.Path]::GetFullPath("${{ env.libtorrent_root }}").Replace('\\', '/') | |
| $toolchain = "$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" | |
| cmake ` | |
| -B build ` | |
| -G Ninja ` | |
| -DCMAKE_BUILD_TYPE=Release ` | |
| -DCMAKE_INSTALL_PREFIX="$libtorrentRoot" ` | |
| -DCMAKE_TOOLCHAIN_FILE="$toolchain" ` | |
| -DBOOST_ROOT="$boostRoot" ` | |
| -DBUILD_SHARED_LIBS=OFF ` | |
| -Dmmap-disk-io=OFF ` | |
| -Ddeprecated-functions=ON ` | |
| -Dstatic_runtime=ON ` | |
| -DVCPKG_TARGET_TRIPLET=${{ env.vcpkg_triplet }} | |
| cmake --build build | |
| cmake --install build | |
| - name: Build qBittorrent for ARM64 | |
| shell: pwsh | |
| run: | | |
| $qtTargetRoot = (Get-Item "${{ env.qt_target_root }}").FullName.Replace('\\', '/') | |
| $hostQtRoot = "C:/Qt/${{ env.qt_version }}/msvc2022_64" | |
| $vcpkgInstalled = "$env:VCPKG_ROOT/installed/${{ env.vcpkg_triplet }}" | |
| $boostRoot = (Get-Item "${{ env.boost_root }}").FullName.Replace('\\', '/') | |
| $libtorrentDir = (Get-Item "${{ env.libtorrent_root }}").FullName.Replace('\\', '/') + '/lib/cmake/LibtorrentRasterbar' | |
| $env:Path = "$qtTargetRoot/bin;$env:Path" | |
| aria2c "$env:QBT_URL" | |
| tar -xf "qbittorrent-release-${{ env.qbt_version }}.tar.gz" | |
| Set-Location "qbittorrent-release-${{ env.qbt_version }}" | |
| # Ensure the deprecation cutoff applies to every target, including qbt_app. | |
| $env:CXXFLAGS = (($env:CXXFLAGS + " /DQT_DISABLE_DEPRECATED_UP_TO=0x060A00").Trim()) | |
| cmake ` | |
| -B build ` | |
| -G Ninja ` | |
| -DCMAKE_BUILD_TYPE=RelWithDebInfo ` | |
| -DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase ` | |
| -DCMAKE_PREFIX_PATH="$qtTargetRoot;$hostQtRoot;$vcpkgInstalled" ` | |
| -DQT_HOST_PATH="$hostQtRoot" ` | |
| -DCMAKE_FIND_PACKAGE_TARGETS_GLOBAL=ON ` | |
| -DOPENSSL_ROOT_DIR="$vcpkgInstalled" ` | |
| -DZLIB_ROOT="$vcpkgInstalled" ` | |
| -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` | |
| -DVCPKG_MANIFEST_MODE=OFF ` | |
| -DBOOST_ROOT="$boostRoot" ` | |
| -DLibtorrentRasterbar_DIR="$libtorrentDir" ` | |
| -DMSVC_RUNTIME_DYNAMIC=OFF ` | |
| -DSTACKTRACE=OFF ` | |
| -DQT_NO_PRIVATE_MODULE_WARNING=ON ` | |
| -DVCPKG_TARGET_TRIPLET=${{ env.vcpkg_triplet }} | |
| cmake --build build | |
| - name: Package artifact | |
| shell: pwsh | |
| run: | | |
| $releaseDir = "release" | |
| $symbolsDir = "symbols" | |
| $artifactDir = "artifact" | |
| $archiveName = "qbittorrent_${{ env.qbt_version }}${{ matrix.archive_suffix }}_arm64.zip" | |
| New-Item -ItemType Directory -Path $releaseDir -Force | Out-Null | |
| New-Item -ItemType Directory -Path $symbolsDir -Force | Out-Null | |
| New-Item -ItemType Directory -Path $artifactDir -Force | Out-Null | |
| Copy-Item "qbittorrent-release-${{ env.qbt_version }}/build/qbittorrent.exe" $releaseDir | |
| Copy-Item "qbittorrent-release-${{ env.qbt_version }}/dist/windows/qt.conf" $releaseDir | |
| $symbols = Get-ChildItem "qbittorrent-release-${{ env.qbt_version }}/build" -Filter "*.pdb" -File -ErrorAction SilentlyContinue | |
| if ($symbols) { | |
| $symbols | Copy-Item -Destination $symbolsDir | |
| } | |
| Set-Location $releaseDir | |
| 7z a "../$archiveName" * | |
| Set-Location .. | |
| Move-Item $archiveName $artifactDir | |
| if ((Get-ChildItem $symbolsDir -File -ErrorAction SilentlyContinue).Count -gt 0) { | |
| Move-Item $symbolsDir $artifactDir | |
| } | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact_name }} | |
| path: artifact | |
| smoke-test-windows-arm64-native: | |
| name: Smoke test Native ARM64 (${{ matrix.libt_variant }}) | |
| needs: build-windows-arm64-native | |
| runs-on: windows-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - libt_variant: lt12 | |
| artifact_name: arm64-native-lt12 | |
| archive_suffix: "" | |
| - libt_variant: lt20 | |
| artifact_name: arm64-native-lt20 | |
| archive_suffix: "_lt20" | |
| steps: | |
| - name: Download build artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact_name }} | |
| path: artifact | |
| - name: Run qBittorrent smoke test | |
| shell: pwsh | |
| run: | | |
| $zipFile = Get-ChildItem artifact -Filter "qbittorrent_*.zip" -File | Select-Object -First 1 | |
| if (-not $zipFile) { | |
| throw "No packaged artifact zip found in downloaded build output" | |
| } | |
| $smokeRoot = Join-Path $env:RUNNER_TEMP "qbittorrent-smoke-${{ matrix.libt_variant }}" | |
| New-Item -ItemType Directory -Path $smokeRoot -Force | Out-Null | |
| Expand-Archive -Path $zipFile.FullName -DestinationPath $smokeRoot -Force | |
| $exePath = Join-Path $smokeRoot "qbittorrent.exe" | |
| if (-not (Test-Path $exePath)) { | |
| throw "qbittorrent.exe was not found after extracting the build artifact" | |
| } | |
| $profileDir = Join-Path $smokeRoot "profile" | |
| New-Item -ItemType Directory -Path $profileDir -Force | Out-Null | |
| $process = Start-Process -FilePath $exePath -ArgumentList @("--profile=$profileDir") -WorkingDirectory $smokeRoot -PassThru | |
| try { | |
| Wait-Process -Id $process.Id -Timeout 45 -ErrorAction Stop | |
| } catch { | |
| if (-not $process.HasExited) { | |
| Stop-Process -Id $process.Id -Force | |
| Write-Host "qBittorrent stayed alive for the smoke-test window" | |
| return | |
| } | |
| throw | |
| } | |
| if ($process.ExitCode -ne 0) { | |
| throw "qBittorrent exited with code $($process.ExitCode) during the smoke test" | |
| } | |
| publish-release: | |
| name: Publish release assets | |
| needs: build-windows-arm64-native | |
| if: startsWith(github.ref, 'refs/tags/') || (github.event_name == 'push' && github.ref == 'refs/heads/main') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Publish tagged release | |
| if: startsWith(github.ref, 'refs/tags/') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: v${{ env.qbt_version }} | |
| name: qBittorrent ${{ env.qbt_version }} (Windows ARM64 Native) | |
| files: | | |
| artifacts/arm64-native-lt12/qbittorrent_${{ env.qbt_version }}_arm64.zip | |
| artifacts/arm64-native-lt20/qbittorrent_${{ env.qbt_version }}_lt20_arm64.zip | |
| draft: false | |
| prerelease: false | |
| body: | | |
| Native Windows ARM64 builds produced by ci_windows_arm64_native.yaml | |
| Library versions: | |
| - qBittorrent: ${{ env.qbt_version }} | |
| - Qt: ${{ env.qt_version }} | |
| - vcpkg triplet: ${{ env.vcpkg_triplet }} | |
| - libtorrent (lt12): 1.2.20+gitc5ff6c3186 | |
| - Boost (lt12): 1.86.0 | |
| - libtorrent (lt20): 2.0.13+gitda7a68a440 | |
| - Boost (lt20): 1.91.0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Publish branch release | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: native-arm64-main-${{ github.run_number }} | |
| target_commitish: ${{ github.sha }} | |
| name: qBittorrent native ARM64 main release ${{ github.run_number }} | |
| files: | | |
| artifacts/arm64-native-lt12/qbittorrent_${{ env.qbt_version }}_arm64.zip | |
| artifacts/arm64-native-lt20/qbittorrent_${{ env.qbt_version }}_lt20_arm64.zip | |
| draft: false | |
| prerelease: false | |
| body: | | |
| Native ARM64 builds from branch main. | |
| Commit: ${{ github.sha }} | |
| Library versions: | |
| - qBittorrent: ${{ env.qbt_version }} | |
| - Qt: ${{ env.qt_version }} | |
| - vcpkg triplet: ${{ env.vcpkg_triplet }} | |
| - libtorrent (lt12): 1.2.20+gitc5ff6c3186 | |
| - Boost (lt12): 1.86.0 | |
| - libtorrent (lt20): 2.0.13+gitda7a68a440 | |
| - Boost (lt20): 1.91.0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |