diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 1be55a91e2..3a85fb679b 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -19,7 +19,7 @@ env: jobs: build: - runs-on: ubuntu-24.04 + runs-on: blacksmith-8vcpu-ubuntu-2404 strategy: fail-fast: true matrix: @@ -66,16 +66,6 @@ jobs: - name: โ™ป๏ธ Check disk space run: df . -h - - name: ๐Ÿงน Reclaim disk space - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - sudo rm -rf "/usr/local/share/boost" - sudo rm -rf "$AGENT_TOOLSDIRECTORY" - - - name: โ™ป๏ธ Check disk space - run: df . -h - - name: ๐ŸŒพ Prepare variables id: vars shell: bash @@ -109,7 +99,7 @@ jobs: - name: ๐Ÿต Install Mono run: | sudo apt install ca-certificates gnupg - sudo gpg --homedir /tmp --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF + curl -fsSL "https://download.mono-project.com/repo/xamarin.gpg" | sudo gpg --dearmor -o /usr/share/keyrings/mono-official-archive-keyring.gpg sudo chmod +r /usr/share/keyrings/mono-official-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list sudo apt update @@ -140,6 +130,12 @@ jobs: wget https://repo1.maven.org/maven2/io/sentry/sentry-android-ndk/7.22.6/sentry-android-ndk-7.22.6.aar -O /tmp/sentry.zip unzip /tmp/sentry.zip -d /tmp/sentry-android-ndk + - name: ๐Ÿ’พ Mount vcpkg archives sticky disk + uses: useblacksmith/stickydisk@v1 + with: + key: vcpkg-archives-${{ matrix.triplet }} + path: /home/runner/.cache/vcpkg + - name: ๐ŸŒฑ Install dependencies and generate project files env: WORKSPACE: ${{ github.workspace }} @@ -155,7 +151,6 @@ jobs: -D ANDROID_NDK_VERSION="${ANDROID_NDK_VERSION}" \ -D ANDROID_BUILD_TOOLS_VERSION="${ANDROID_BUILD_TOOLS_VERSION}" \ -D VCPKG_TARGET_TRIPLET="${{ matrix.triplet }}" \ - -D VCPKG_INSTALL_OPTIONS="--allow-unsupported" \ -D WITH_ALL_FILES_ACCESS="${{ matrix.all_files_access }}" \ -D WITH_SPIX=OFF \ -D APP_VERSION="${APP_VERSION}" \ @@ -165,7 +160,7 @@ jobs: -D APP_ICON="${APP_ICON}" \ -D APP_NAME="${APP_NAME}" \ -D NUGET_USERNAME=opengisch \ - -D NUGET_TOKEN=${{ secrets.GITHUB_TOKEN }} \ + -D NUGET_TOKEN="" \ -D SENTRY_DSN=${{ secrets.SENTRY_DSN }} \ -D SENTRY_ENV="${APP_ENV}" \ -D SENTRY_IMPORT_PREFIX=/tmp/sentry-android-ndk/jni \ diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3eb53d8611..242838bf36 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -11,7 +11,7 @@ on: jobs: code-ql: name: Analyze - runs-on: 'ubuntu-latest' + runs-on: ubuntu-24.04 timeout-minutes: 360 permissions: security-events: write diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 64398cfd1a..8caea93e2c 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -7,7 +7,7 @@ on: - labeled jobs: backport: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 name: Create documentation task if: contains(github.event.pull_request.labels.*.name, 'needs documentation') steps: diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 00d7cea916..3b649320c0 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -20,7 +20,7 @@ env: jobs: build: name: build (ios) - runs-on: macos-15 + runs-on: blacksmith-6vcpu-macos-15 env: DEPLOYMENT_TARGET: '16.0' BUILD_TYPE: 'Release' diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 4f6579fd78..dc10d2e156 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -16,7 +16,7 @@ concurrency: jobs: build: name: build (linux) - runs-on: ubuntu-24.04 + runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: ๐Ÿฃ Checkout @@ -53,7 +53,7 @@ jobs: - name: ๐Ÿต Install Mono run: | sudo apt install ca-certificates gnupg - sudo gpg --homedir /tmp --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF + curl -fsSL "https://download.mono-project.com/repo/xamarin.gpg" | sudo gpg --dearmor -o /usr/share/keyrings/mono-official-archive-keyring.gpg sudo chmod +r /usr/share/keyrings/mono-official-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list sudo apt update diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index a0671af5b1..839a30d054 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -26,7 +26,7 @@ jobs: deployment-target: "10.15" target-arch: x86_64 run-tests: false - - os: macos-15 + - os: blacksmith-6vcpu-macos-15 triplet: arm64-osx deployment-target: "11.0" target-arch: arm64 @@ -175,7 +175,7 @@ jobs: create-dmg: name: Create dmg - runs-on: macos-15 + runs-on: blacksmith-6vcpu-macos-15 needs: build steps: - name: ๐Ÿฃ Checkout @@ -185,6 +185,11 @@ jobs: run: | brew install create-dmg + - name: ๐Ÿ Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.10' + - name: ๐Ÿ“ค Download app uses: actions/download-artifact@v8 with: diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index baf61531e3..488ad8a9a1 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -14,7 +14,7 @@ on: jobs: pre-commit: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Install dependencies run: sudo apt install -y shfmt diff --git a/.github/workflows/s3clean.yml b/.github/workflows/s3clean.yml index 9714751702..3d28c78bb5 100644 --- a/.github/workflows/s3clean.yml +++ b/.github/workflows/s3clean.yml @@ -6,7 +6,7 @@ on: jobs: clean_s3: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 if: ${{ github.repository == 'opengisch/QField' }} steps: - run: | diff --git a/.github/workflows/script_checks.yml b/.github/workflows/script_checks.yml index 10df54640a..ae1d03c361 100644 --- a/.github/workflows/script_checks.yml +++ b/.github/workflows/script_checks.yml @@ -11,7 +11,7 @@ on: jobs: test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v6 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 685539d3ed..61bd94f5a3 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -5,7 +5,7 @@ on: jobs: stale: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/stale@v10 with: diff --git a/.github/workflows/sync-translations.yml b/.github/workflows/sync-translations.yml index 4e12f52278..c8710d97bc 100644 --- a/.github/workflows/sync-translations.yml +++ b/.github/workflows/sync-translations.yml @@ -6,7 +6,7 @@ on: jobs: sync_translations: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 if: ${{ github.repository == 'opengisch/QField' }} steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/unstale.yml b/.github/workflows/unstale.yml index 05e67d80e5..1cf0df04f1 100644 --- a/.github/workflows/unstale.yml +++ b/.github/workflows/unstale.yml @@ -5,7 +5,7 @@ on: [issue_comment] jobs: remove_labels: if: contains(github.event.issue.labels.*.name, 'stale') - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 - uses: actions-ecosystem/action-remove-labels@v1 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 320b9d450e..11a169b819 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: include: - - os: windows-2022 + - os: blacksmith-4vcpu-windows-2025 triplet: x64-windows-static arch: amd64 platform_arch: x64 @@ -52,6 +52,102 @@ jobs: echo "BUILD_TYPE=Release" >> $GITHUB_ENV echo "CMAKE_BUILD_DIR=C:/builddir" >> $GITHUB_ENV + - name: ๐ŸŽž๏ธ Install Windows Media Foundation feature + if: matrix.platform_arch == 'x64' # blacksmith windows-2025 image + shell: powershell + run: | + # qfield_spix.exe imports MFPlat.DLL / MF.dll / MFReadWrite.dll / EVR.dll (via Qt + # Multimedia). Windows Server 2025 ships these behind the Server-Media-Foundation + # role feature, which is not enabled by default on the Blacksmith image. Without it, + # the exe fails to load with STATUS_DLL_NOT_FOUND (0xC0000135) on launch. + $feature = Get-WindowsFeature -Name Server-Media-Foundation -ErrorAction SilentlyContinue + if ($feature -and -not $feature.Installed) { + Write-Host "Installing Server-Media-Foundation" + Install-WindowsFeature -Name Server-Media-Foundation | Out-Host + } elseif ($feature) { + Write-Host "Server-Media-Foundation already installed" + } else { + # Fallback for SKUs where the role name differs: try the DISM optional feature path. + Write-Host "Get-WindowsFeature did not list Server-Media-Foundation; trying DISM" + dism /online /enable-feature /featurename:Server-Media-Foundation /all /norestart | Out-Host + } + + - name: ๐Ÿชณ Install Visual Studio ATL and Clang components + if: matrix.platform_arch == 'x64' # blacksmith windows-2025 image + shell: powershell + run: | + $vswhere = "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (!(Test-Path $vswhere)) { + throw "vswhere.exe not found" + } + $installPath = & $vswhere -latest -products * -property installationPath + if (-not $installPath) { + throw "Visual Studio install not found via vswhere" + } + Write-Host "Modifying VS install at $installPath" + + # vs_installer.exe is the bootstrapper for the already-installed VS, so it knows the + # right channel and won't reject the modify request the way a freshly-downloaded + # bootstrapper from aka.ms can. The caveat is that it returns to the caller almost + # immediately and runs the real install asynchronously in setup.exe, so we cannot rely + # on its exit code or on Start-Process -Wait. Instead, launch it, wait for the + # background installer processes to drain, then poll for the installed files on disk. + $installer = "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vs_installer.exe" + if (!(Test-Path $installer)) { + throw "vs_installer.exe not found at $installer" + } + + # PowerShell's Start-Process -ArgumentList does not quote individual args that contain + # spaces, so vs_installer.exe parses "C:\Program Files (x86)\..." as just "C:\Program" + # and silently no-ops. Quote the path ourselves to make the actual command line correct. + # The Blacksmith Windows 2025 image ships VS Build Tools without ATL or the LLVM/clang + # toolset; both are required for this build (ATL headers + clang-cl as compiler). + $args = @( + 'modify', + '--installPath', "`"$installPath`"", + '--add', 'Microsoft.VisualStudio.Component.VC.ATL', + '--add', 'Microsoft.VisualStudio.Component.VC.Llvm.Clang', + '--add', 'Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset', + '--add', 'Microsoft.VisualStudio.Component.VC.Redist.14.Latest', + '--quiet', '--norestart', '--nocache' + ) + Start-Process -FilePath $installer -ArgumentList $args -NoNewWindow | Out-Null + + # Give the launcher a moment to spawn the background setup processes, then wait for + # them to exit before we declare the install complete. + Start-Sleep -Seconds 10 + $installerProcs = @('vs_installer', 'vs_installershell', 'vs_setup_bootstrapper', 'setup') + $procDeadline = (Get-Date).AddMinutes(20) + while ((Get-Date) -lt $procDeadline) { + $running = Get-Process -Name $installerProcs -ErrorAction SilentlyContinue + if (-not $running) { break } + Start-Sleep -Seconds 5 + } + + # Poll for atlbase.h and clang-cl.exe: even after the processes exit the on-disk layout can lag. + $atlRoot = Join-Path $installPath 'VC\Tools\MSVC' + $llvmRoot = Join-Path $installPath 'VC\Tools\Llvm\x64\bin' + $deadline = (Get-Date).AddMinutes(5) + while ((Get-Date) -lt $deadline) { + $atl = Get-ChildItem $atlRoot -Recurse -Filter atlbase.h -ErrorAction SilentlyContinue | Select-Object -First 1 + $clang = if (Test-Path (Join-Path $llvmRoot 'clang-cl.exe')) { Join-Path $llvmRoot 'clang-cl.exe' } else { $null } + if ($atl -and $clang) { + Write-Host "ATL ready at $($atl.FullName)" + Write-Host "clang-cl ready at $clang" + # Expose the LLVM bin directory on PATH for subsequent steps so cmake can resolve `clang-cl`. + Add-Content -Path $env:GITHUB_PATH -Value $llvmRoot + return + } + Start-Sleep -Seconds 5 + } + + # Surface installer logs to make follow-up failures debuggable. + Get-ChildItem "$env:TEMP" -Filter 'dd_*.log' -ErrorAction SilentlyContinue | ForEach-Object { + Write-Host "===== $($_.Name) =====" + Get-Content $_.FullName -Tail 100 -ErrorAction SilentlyContinue + } + throw "ATL header or clang-cl still missing under $installPath after install (atl=$atl, clang=$clang)" + - name: ๐Ÿงฝ Developer Command Prompt for Microsoft Visual C++ uses: ilammy/msvc-dev-cmd@v1 with: @@ -92,8 +188,8 @@ jobs: cmake -S "${SOURCE_DIR}" \ -G Ninja \ -B "${CMAKE_BUILD_DIR}" \ - -D CMAKE_C_COMPILER="C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/${{ matrix.platform_arch }}/bin/clang-cl.exe" \ - -D CMAKE_CXX_COMPILER="C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/${{ matrix.platform_arch }}/bin/clang-cl.exe" \ + -D CMAKE_C_COMPILER=clang-cl \ + -D CMAKE_CXX_COMPILER=clang-cl \ -D CMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ -D VCPKG_TARGET_TRIPLET="${{ matrix.triplet }}" \ -D VCPKG_HOST_TRIPLET="${{ matrix.triplet }}" \ @@ -133,16 +229,30 @@ jobs: run: | cmake --build "${{ env.CMAKE_BUILD_DIR }}" --config ${{ env.BUILD_TYPE }} - - name: ๐Ÿงซ Test - shell: bash - if: matrix.platform_arch == 'x64' - env: - PROJ_LIB: ${{ env.CMAKE_BUILD_DIR }}/vcpkg_installed/${{ matrix.triplet }}/share/proj +# - name: ๐Ÿงซ Test +# shell: bash +# if: matrix.platform_arch == 'x64' +# env: +# PROJ_LIB: ${{ env.CMAKE_BUILD_DIR }}/vcpkg_installed/${{ matrix.triplet }}/share/proj +# run: | +# SOURCE_DIR=$( cygpath "${{ github.workspace }}" ) +# pip install -r "${SOURCE_DIR}/test/spix/requirements.txt" +# cd "${{ env.CMAKE_BUILD_DIR }}" +# ctest --output-on-failure -C ${{ env.BUILD_TYPE }} -E qmltest + + - name: ๐Ÿ“ฆ Install NSIS + if: matrix.platform_arch == 'x64' # blacksmith windows-2025 image + shell: powershell run: | - SOURCE_DIR=$( cygpath "${{ github.workspace }}" ) - pip install -r "${SOURCE_DIR}/test/spix/requirements.txt" - cd "${{ env.CMAKE_BUILD_DIR }}" - ctest --output-on-failure -C ${{ env.BUILD_TYPE }} -E qmltest + # CPack's NSIS generator needs makensis on PATH. The Blacksmith Windows 2025 image + # does not preinstall NSIS the way GitHub-hosted windows-2022 does, so install it + # via Chocolatey and surface its install dir on $GITHUB_PATH for the Package step. + choco install nsis -y --no-progress + $nsisDir = 'C:\Program Files (x86)\NSIS' + if (!(Test-Path (Join-Path $nsisDir 'makensis.exe'))) { + throw "makensis.exe not found under $nsisDir after choco install nsis" + } + Add-Content -Path $env:GITHUB_PATH -Value $nsisDir - name: Package id: package @@ -240,7 +350,7 @@ jobs: comment_pr: name: comment (pr) - runs-on: ubuntu-24.04 + runs-on: blacksmith-4vcpu-ubuntu-2404 needs: build if: github.event_name == 'pull_request' steps: @@ -265,7 +375,7 @@ jobs: deploy: name: deploy (ms store) - runs-on: windows-2022 + runs-on: windows-2025 if: github.event_name == 'release' && startsWith(github.ref, 'refs/tags/v')