Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions ci/cloudbuild/builds/image-provision.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Setup log output redirection
$LogPath = "C:\image-provision.log"
Start-Transcript -Path $LogPath

try {
# 1. Ensure Chocolatey is installed
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
if (-not (Test-Path "C:\ProgramData\chocolatey\bin\choco.exe")) {
Write-Host "Installing Chocolatey..."
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}
$env:Path += ";C:\ProgramData\chocolatey\bin"
}

# 2. Ensure Git is installed and in the PATH
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-Host "Installing Git..."
choco install -y git --no-progress
$env:Path += ";C:\Program Files\Git\cmd"
}

# 3. Ensure CMake is installed and in the PATH
if (-not (Get-Command cmake -ErrorAction SilentlyContinue)) {
Write-Host "Installing CMake..."
choco install -y cmake --version 3.31.6 --no-progress
$env:Path += ";C:\Program Files\CMake\bin"
}

# 4. Ensure Ninja is installed and in the PATH
if (-not (Get-Command ninja -ErrorAction SilentlyContinue)) {
Write-Host "Installing Ninja..."
$NinjaDir = "C:\ninja"
New-Item -ItemType Directory -Force -Path $NinjaDir
Invoke-WebRequest -Uri "https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-win.zip" -OutFile "$NinjaDir\ninja.zip"
Expand-Archive -Path "$NinjaDir\ninja.zip" -DestinationPath $NinjaDir -Force
Remove-Item "$NinjaDir\ninja.zip"
$env:Path += ";$NinjaDir"
}

# 5. Download and Install sccache
if (-not (Get-Command sccache -ErrorAction SilentlyContinue)) {
Write-Host "Installing sccache..."
$SccacheDir = "C:\sccache"
New-Item -ItemType Directory -Force -Path $SccacheDir
$SccacheUrl = "https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-pc-windows-msvc.tar.gz"
Invoke-WebRequest -Uri $SccacheUrl -OutFile "$SccacheDir\sccache.tar.gz"
tar -xzf "$SccacheDir\sccache.tar.gz" -C $SccacheDir --strip-components=1
$env:Path += ";$SccacheDir"
}

# Set machine-level persistent PATH for Git, CMake, Ninja, sccache
[Environment]::SetEnvironmentVariable("Path", $env:Path, [EnvironmentVariableTarget]::Machine)

# 6. Download and bootstrap vcpkg
Write-Host "Setting up vcpkg..."
$VcpkgDir = "C:\vcpkg"
New-Item -ItemType Directory -Force -Path $VcpkgDir
# Default version to bake in: matching the repository version in ci/etc/vcpkg-version.txt
$VcpkgVersion = "3895230f38e498525f2560a281223d12066fa74a"
$VcpkgUrl = "https://github.com/microsoft/vcpkg/archive/$VcpkgVersion.tar.gz"
Invoke-WebRequest -Uri $VcpkgUrl -OutFile "$VcpkgDir\vcpkg.tar.gz"
tar -xzf "$VcpkgDir\vcpkg.tar.gz" -C $VcpkgDir --strip-components=1
& "$VcpkgDir\bootstrap-vcpkg.sh" -disableMetrics

# Save the baked vcpkg version to a file
$VcpkgVersion | Out-File -FilePath "C:\vcpkg_version.txt" -Encoding ascii
[Environment]::SetEnvironmentVariable("VCPKG_ROOT", $VcpkgDir, [EnvironmentVariableTarget]::Machine)

# 7. Install Visual Studio 2022 Build Tools
if (-not (Test-Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe")) {
Write-Host "Installing Visual Studio 2022 Build Tools..."
$VsBootstrapperPath = "C:\vs_buildtools.exe"
Invoke-WebRequest -Uri "https://aka.ms/vs/17/release/vs_buildtools.exe" -OutFile $VsBootstrapperPath

Write-Host "Running Visual Studio Installer..."
$Process = Start-Process -FilePath $VsBootstrapperPath -ArgumentList "--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --passive --norestart --wait" -Wait -NoNewWindow -PassThru

if ($Process.ExitCode -ne 0 -and $Process.ExitCode -ne 3010) {
throw "Visual Studio Build Tools installation failed with exit code: $($Process.ExitCode)"
}
Write-Host "Visual Studio Build Tools installed successfully."
}

# 8. Run Sysprep generalization and shutdown
Write-Host "Running Sysprep generalization and shutdown..."
& $env:SystemRoot\System32\Sysprep\Sysprep.exe /oobe /generalize /shutdown /quiet
}
catch {
Write-Error "Error occurred during image provisioning: $_"
exit 1
}
finally {
Stop-Transcript
}
120 changes: 120 additions & 0 deletions ci/cloudbuild/builds/windows-startup.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Setup log output redirection
$LogPath = "C:\build.log"
Start-Transcript -Path $LogPath

try {
# 1. Fetch metadata values
$MetadataUrl = "http://metadata.google.internal/computeMetadata/v1/instance/attributes"
$Headers = @{"Metadata-Flavor"="Google"}

$SourceArchive = Invoke-RestMethod -Headers $Headers -Uri "$MetadataUrl/source-archive"
$BuildType = Invoke-RestMethod -Headers $Headers -Uri "$MetadataUrl/build-type"
$Features = Invoke-RestMethod -Headers $Headers -Uri "$MetadataUrl/features"
$LogsBucket = Invoke-RestMethod -Headers $Headers -Uri "$MetadataUrl/logs-bucket"
$VcpkgVersion = Invoke-RestMethod -Headers $Headers -Uri "$MetadataUrl/vcpkg-version"

# Start background job to periodically upload build.log to GCS for streaming logs
$LogUploadJob = Start-Job -ScriptBlock {
param($LogPath, $LogsBucket)
while ($true) {
if (Test-Path $LogPath) {
# Use Out-Null to suppress output to avoid writing back to the transcript log
& gcloud storage cp $LogPath "$LogsBucket/build.log" 2>&1 | Out-Null
}
Start-Sleep -Seconds 20
}
} -ArgumentList $LogPath, $LogsBucket

Write-Host "Source Archive: $SourceArchive"
Write-Host "Build Type: $BuildType"
Write-Host "Features: $Features"
Write-Host "Vcpkg Version: $VcpkgVersion"

# 2. Check if the pre-baked vcpkg version matches the requested version
$VcpkgDir = "C:\vcpkg"
$BakedVersion = ""
if (Test-Path "C:\vcpkg_version.txt") {
$BakedVersion = (Get-Content "C:\vcpkg_version.txt").Trim()
}
if ($BakedVersion -ne $VcpkgVersion) {
Write-Host "Vcpkg version mismatch! Baked: $BakedVersion, Requested: $VcpkgVersion. Re-setting up vcpkg..."
Remove-Item -Recurse -Force $VcpkgDir -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force -Path $VcpkgDir
$VcpkgUrl = "https://github.com/microsoft/vcpkg/archive/$VcpkgVersion.tar.gz"
Invoke-WebRequest -Uri $VcpkgUrl -OutFile "$VcpkgDir\vcpkg.tar.gz"
tar -xzf "$VcpkgDir\vcpkg.tar.gz" -C $VcpkgDir --strip-components=1
& "$VcpkgDir\bootstrap-vcpkg.sh" -disableMetrics
$VcpkgVersion | Out-File -FilePath "C:\vcpkg_version.txt" -Encoding ascii
} else {
Write-Host "Using pre-baked vcpkg version: $VcpkgVersion"
}

# 8. Extract workspace source codebase
Write-Host "Extracting source..."
$Workspace = "C:\workspace"
New-Item -ItemType Directory -Force -Path $Workspace
Set-Location $Workspace
gcloud storage cp $SourceArchive source.tar.gz
tar -xzf source.tar.gz
Remove-Item source.tar.gz

# 9. Configure environment for build
$env:VCPKG_ROOT = $VcpkgDir
$env:CMAKE_OUT = "C:\b" # Directory for build output (keep it short)
$env:EXECUTE_INTEGRATION_TESTS = "false"

# 10. Run MSVC Developer Environment Config

# Locates and runs vcvarsall.bat to configure compile paths
Write-Host "Locating VS / MSVC compiler..."
$VsInstallPath = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationPath
if (-not $VsInstallPath) {
throw "Visual Studio installation not found!"
}
$VcVarsPath = Join-Path $VsInstallPath "VC\Auxiliary\Build\vcvarsall.x64.bat"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There is no vcvarsall.x64.bat file in the Visual Studio installation. To configure the environment for 64-bit MSVC compilation, you should use vcvars64.bat (or vcvarsall.bat with the x64 argument). Using vcvars64.bat is simpler as it does not require any arguments.

    $VcVarsPath = Join-Path $VsInstallPath "VC\Auxiliary\Build\vcvars64.bat"

Write-Host "Running vcvarsall.bat: $VcVarsPath"
cmd.exe /c "`"$VcVarsPath`" && set" | Foreach-Object {
if ($_ -match "^(.*?)=(.*)$") {
Set-Content "env:\$($Matches[1])" $Matches[2]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using Set-Content with the env: drive can fail or behave unexpectedly when environment variable names contain parentheses (such as ProgramFiles(x86) or CommonProgramFiles(x86)), which are common in Windows environments. Using [System.Environment]::SetEnvironmentVariable is much more robust and avoids provider path parsing issues.

            [System.Environment]::SetEnvironmentVariable($Matches[1], $Matches[2])

}
}

# 11. Run the build script using Git Bash
$GitBashPath = "C:\Program Files\Git\bin\bash.exe"
Write-Host "Executing windows-cmake.sh..."
& $GitBashPath -c "ci/gha/builds/windows-cmake.sh $BuildType $Features" 2>&1
if ($LastExitCode -ne 0) {
throw "windows-cmake.sh failed with exit code: $LastExitCode"
}

# Report success status
$Status = @{ status = "success" }
$Status | ConvertTo-Json | Out-File -FilePath "C:\status.json" -Encoding ascii
}
catch {
Write-Host "Error occurred during build: $_"
$Status = @{ status = "failed"; error = $_.Exception.Message }
$Status | ConvertTo-Json | Out-File -FilePath "C:\status.json" -Encoding ascii
}
finally {
if ($LogUploadJob) {
Stop-Job $LogUploadJob -ErrorAction SilentlyContinue
Remove-Job $LogUploadJob -ErrorAction SilentlyContinue
}
Stop-Transcript
if (Test-Path "C:\vcpkg\buildtrees") {
Get-ChildItem -Path "C:\vcpkg\buildtrees" -Filter "*.log" -Recurse | ForEach-Object {
$RelativePath = $_.FullName.Substring("C:\vcpkg\buildtrees\".Length).Replace("\", "/")
gcloud storage cp $_.FullName "$LogsBucket/build-logs/vcpkg/$RelativePath"
}
}
if (Test-Path "C:\b") {
Get-ChildItem -Path "C:\b" -Filter "*.log" -Recurse | ForEach-Object {
$RelativePath = $_.FullName.Substring("C:\b\".Length).Replace("\", "/")
gcloud storage cp $_.FullName "$LogsBucket/build-logs/cmake/$RelativePath"
}
}
# Upload final logs and status to GCS bucket
gcloud storage cp C:\build.log "$LogsBucket/build.log"
gcloud storage cp C:\status.json "$LogsBucket/status.json"
}
29 changes: 29 additions & 0 deletions ci/cloudbuild/triggers/windows-cmake-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

filename: ci/cloudbuild/windows.yaml
github:
name: google-cloud-cpp
owner: googleapis
push:
branch: main
includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS
name: windows-cmake-ci
substitutions:
_BUILD_TYPE: Release
_FEATURES: all # Run full features on pushes to main
_TRIGGER_TYPE: ci
tags:
- ci
- windows
30 changes: 30 additions & 0 deletions ci/cloudbuild/triggers/windows-cmake-pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

filename: ci/cloudbuild/windows.yaml
github:
name: google-cloud-cpp
owner: googleapis
pullRequest:
branch: main
commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY
includeBuildLogs: INCLUDE_BUILD_LOGS_WITH_STATUS
name: windows-cmake-pr
substitutions:
_BUILD_TYPE: Debug
_FEATURES: storage # Subset of features for PR builds to run faster
_TRIGGER_TYPE: pr
tags:
- pr
- windows
Loading
Loading