gitlab-ci: migrate Windows builds away from Chocolatey

The Windows builds in GitLab CI use Chocolatey to install dependencies. Unfortunately, Chocolatey seems to be very unreliable, which causes the jobs to fail very regularly. This is a limitation that seems to be somewhat known [1]: As an organization, you want 100% reliability (or at least that potential), and you may want full trust and control as well. This is something you can get with internally hosted packages, and you are unlikely to achieve from use of the Community Package Repository. So using the Community Package Repository is kind of discouraged in case one wants reliability. We _do_ want reliability though, and we cannot easily switch to an enterprise license to fix this issue. Introduce a new script that downloads and installs dependencies directly. This has a couple of benefits: - We can drop our dependency on Chocolatey completely, thus improving reliability. - We can easily cache the installers. - We get direct control over the exact versions we install. - Installing dependencies is sped up from roundabout 3 minutes to 1 minute. [1]: https://docs.chocolatey.org/en-us/community-repository/community-packages-disclaimer/#summary Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jun 15, 2026 at 14:21 UTC 0e7b51fed23c156600659bccc50b01430b9821dd
2 files changed +63 -3
.gitlab-ci.yml
+8 -3
@@ -161,11 +161,16 @@ test:mingw64:
161 TEST_OUTPUT_DIRECTORY: "C:/Git-Test"
162 tags:
163 - saas-windows-medium-amd64
164 + cache:
165 + key:
166 + files:
167 + - ci/install-dependencies.ps1
168 + paths:
169 + - .dependencies
170 before_script:
171 - *windows_before_script
166 - - choco install -y git meson ninja rust-ms
167 - - Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1
168 - - refreshenv
172 + - ./ci/install-dependencies.ps1
173 + - $env:Path = "C:\Meson;C:\Rust\bin;$env:Path"
174 - New-Item -Path $env:TEST_OUTPUT_DIRECTORY -ItemType Directory
175
176 build:msvc-meson:
ci/install-dependencies.ps1 new
+55
@@ -0,0 +1,55 @@
1 +param(
2 + [string]$DownloadDirectory = '.dependencies'
3 +)
4 +
5 +$ErrorActionPreference = 'Stop'
6 +$ProgressPreference = 'SilentlyContinue'
7 +
8 +$GitVersion = '2.54.0.windows.1'
9 +$MesonVersion = '1.11.0'
10 +$RustVersion = '1.96.0'
11 +
12 +New-Item -Path $DownloadDirectory -ItemType Directory -Force | Out-Null
13 +New-Item -Path .git/info -ItemType Directory -Force | Out-Null
14 +New-Item -Path .git/info/exclude -ItemType File -Force | Out-Null
15 +Add-Content -Path .git/info/exclude -Value "/$DownloadDirectory"
16 +
17 +function Get-Installer {
18 + param(
19 + [Parameter(Mandatory = $true)][string]$Name,
20 + [Parameter(Mandatory = $true)][string]$Url
21 + )
22 +
23 + $path = Join-Path $DownloadDirectory $Name
24 + if (-not (Test-Path $path)) {
25 + Write-Host "Downloading $Url"
26 + Invoke-WebRequest $Url -OutFile $path -TimeoutSec 300
27 + }
28 + return $path
29 +}
30 +
31 +function Invoke-Installer {
32 + param(
33 + [Parameter(Mandatory = $true)][string]$FilePath,
34 + [Parameter(Mandatory = $true)][string[]]$ArgumentList
35 + )
36 +
37 + Write-Host "Running $FilePath $($ArgumentList -join ' ')"
38 + $process = Start-Process -Wait -PassThru -FilePath $FilePath -ArgumentList $ArgumentList
39 + if ($process.ExitCode -ne 0) {
40 + throw "$FilePath failed with exit code $($process.ExitCode)"
41 + }
42 +}
43 +
44 +$gitAssetVersion = $GitVersion -replace '\.windows\.\d+$', ''
45 +$gitInstaller = Get-Installer "Git-Installer.exe" `
46 + "https://github.com/git-for-windows/git/releases/download/v$GitVersion/PortableGit-$gitAssetVersion-64-bit.7z.exe"
47 +Invoke-Installer $gitInstaller @('-y', '-o"C:\Program Files\Git"')
48 +
49 +$mesonMsi = Get-Installer "meson.msi" `
50 + "https://github.com/mesonbuild/meson/releases/download/$MesonVersion/meson-$MesonVersion-64.msi"
51 +Invoke-Installer msiexec.exe @('/i', $mesonMsi, 'INSTALLDIR=C:\Meson', '/quiet', '/norestart')
52 +
53 +$rustMsi = Get-Installer "rust.msi" `
54 + "https://static.rust-lang.org/dist/rust-$RustVersion-x86_64-pc-windows-msvc.msi"
55 +Invoke-Installer msiexec.exe @('/i', $rustMsi, 'INSTALLDIR=C:\Rust', 'ADDLOCAL=Rustc,Cargo,Std', '/quiet', '/norestart')