feat(template): Add Step 11 Tier-1 Toolchain — Git + 7-Zip installation
Implement §6.6 minimal viable product: install Git for Windows and 7-Zip to the template VM. Critical prerequisites for §3.3 (In-VM Git clone). Step 11 additions: - Git for Windows (latest LTS configurable) — silent installer, adds to PATH - 7-Zip (latest stable configurable) — MSI installer to Program Files - SHA256 hash pinning for both tools (currently unpinned, warn at runtime) - Assert-Step validation for git/7z command availability - Final pre-snapshot gate checks for both tools + cleanup of installers Parameters added: - -GitVersion (default: 2.47.0.windows.1) - -SevenZipVersion (default: 24.07) Rationale: - Enables §3.3 in-VM Git clone (git clone directly in VM instead of host-zip-transfer) - Supports cross-platform builds and multi-tool workflows - Fallback from §3.2 7-Zip compression finally available in template - Positions for future expansion of Tier-1 tools (NSIS, CMake, Node.js, WiX, etc.) Updated documentation: - Setup-WinBuild2025.ps1 docstring: Step 11 added to list + step ordering rationale - Removed NOTE about Git not being installed - Final validation now checks: 9 assertions (was 7) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -53,10 +53,13 @@
|
||||
Validation: MSBuild.exe exists, executes, PATH, VC dir present
|
||||
Step 10 — Toolchain cross-check (dotnet, python, msbuild)
|
||||
Throws on any missing tool
|
||||
Step 11 — Tier-1 Toolchain (Git for Windows + 7-Zip) — §6.6
|
||||
Installs to C:\Program Files (Git default) and C:\Program Files\7-Zip
|
||||
Validation: git and 7z commands resolvable, executables present
|
||||
Cleanup — Disk cleanup: cleanmgr, SoftwareDistribution, CBS, TEMP, Prefetch, DISM
|
||||
wuauserv already Disabled (Step 6b) — not restarted after cache clear
|
||||
Validation: wuauserv StartType Disabled
|
||||
Final — Pre-snapshot gate: 7 cross-cutting checks across all steps
|
||||
Final — Pre-snapshot gate: 9 cross-cutting checks across all steps
|
||||
Throws if any check fails — prevents snapshot of broken state
|
||||
|
||||
Step ordering rationale:
|
||||
@@ -70,9 +73,10 @@
|
||||
WU (Step 6) — all prereqs validated; WU runs with Firewall+Defender already off
|
||||
WU disable (Step 6b) — immediately after WU; snapshot captures WU permanently off
|
||||
Toolchain (7-9) — .NET/Python/VS last; WU done, no scan on installer payloads
|
||||
Tier-1 (Step 11) — Git + 7-Zip after base toolchain; enables §3.3 in-VM clone
|
||||
|
||||
NOTE: Git is NOT installed by default. See §6.6 (Tier-1 Toolchain) in TODO.md
|
||||
for the planned addition. The host clones and copies source via WinRM until then.
|
||||
NOTE: Step 11 installs Git for Windows + 7-Zip (Tier-1 Toolchain §6.6).
|
||||
This enables §3.3 (In-VM Git clone) and cross-platform build support.
|
||||
|
||||
╔══════════════════════════════════════════════════════════════════════╗
|
||||
║ NETWORK REQUIREMENT DURING SETUP ║
|
||||
@@ -137,7 +141,13 @@ param(
|
||||
|
||||
# Administrator password — used only to write DefaultPassword for autologin.
|
||||
# Optional: if empty, DefaultPassword registry value is left as-is (Deploy may have set it).
|
||||
[string] $AdminPassword = ''
|
||||
[string] $AdminPassword = '',
|
||||
|
||||
# Git for Windows version (latest LTS recommended)
|
||||
[string] $GitVersion = '2.47.0.windows.1',
|
||||
|
||||
# 7-Zip version (latest stable)
|
||||
[string] $SevenZipVersion = '24.07'
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
@@ -199,6 +209,14 @@ $script:Hashes = @{
|
||||
# vs_buildtools.exe bootstrapper from aka.ms/vs/stable/vs_buildtools.exe
|
||||
# Stable within a VS release cycle — update when VS major version changes.
|
||||
'VSBuildToolsBootstrapper' = ''
|
||||
|
||||
# Git for Windows installer from https://github.com/git-for-windows/git/releases/download/
|
||||
# Update $script:Hashes['GitForWindows'] when $GitVersion changes.
|
||||
'GitForWindows' = ''
|
||||
|
||||
# 7-Zip MSI installer from https://www.7-zip.org/download.html
|
||||
# Update $script:Hashes['SevenZip'] when $SevenZipVersion changes.
|
||||
'SevenZip' = ''
|
||||
}
|
||||
|
||||
# ── Pre-flight: remove temp files from any previous partial run ───────────────
|
||||
@@ -207,7 +225,7 @@ $script:Hashes = @{
|
||||
$knownTempFiles = @(
|
||||
'C:\CI\wu_worker.ps1', 'C:\CI\wu_result.txt', 'C:\CI\wu_reboot.txt', 'C:\CI\wu_log.txt',
|
||||
'C:\CI\vs_worker.ps1', 'C:\CI\vs_result.txt', 'C:\CI\vs_BuildTools.exe',
|
||||
'C:\CI\python_installer.exe'
|
||||
'C:\CI\python_installer.exe', 'C:\CI\git_installer.exe', 'C:\CI\7zip_installer.msi'
|
||||
)
|
||||
foreach ($f in $knownTempFiles) {
|
||||
if (Test-Path $f) {
|
||||
@@ -960,6 +978,115 @@ if (-not $allOk) {
|
||||
}
|
||||
Write-Host "All toolchain checks passed." -ForegroundColor Green
|
||||
|
||||
# ── Step 11: Tier-1 Toolchain (Git for Windows + 7-Zip) ──────────────────────
|
||||
# Critical for §3.3 (In-VM Git clone) and cross-platform build support.
|
||||
# Installed to C:\BuildTools\<tool>\ for clear separation from C:\CI\ (runtime artifacts).
|
||||
|
||||
Write-Step "Installing Tier-1 Toolchain (Git + 7-Zip)"
|
||||
|
||||
# Build tools root directory
|
||||
$buildToolsRoot = 'C:\BuildTools'
|
||||
if (-not (Test-Path $buildToolsRoot)) {
|
||||
New-Item -ItemType Directory -Path $buildToolsRoot -Force | Out-Null
|
||||
}
|
||||
|
||||
# ── Git for Windows ───────────────────────────────────────────────────────────
|
||||
$gitDir = Join-Path $buildToolsRoot 'Git'
|
||||
$gitExe = Join-Path $gitDir 'bin\git.exe'
|
||||
|
||||
if (Test-Path $gitExe) {
|
||||
Write-Host "Git for Windows already installed: $(& $gitExe --version 2>&1)"
|
||||
} else {
|
||||
$gitUrl = "https://github.com/git-for-windows/git/releases/download/v$GitVersion/Git-$GitVersion-64-bit.exe"
|
||||
$gitInstaller = 'C:\CI\git_installer.exe'
|
||||
|
||||
Write-Host "Downloading Git for Windows $GitVersion..."
|
||||
try {
|
||||
Invoke-WebRequest -Uri $gitUrl -OutFile $gitInstaller -UseBasicParsing
|
||||
} catch {
|
||||
throw "Failed to download Git from $gitUrl : $_"
|
||||
}
|
||||
|
||||
Assert-Hash -FilePath $gitInstaller -Label "Git-$GitVersion-64-bit.exe" `
|
||||
-Expected $script:Hashes['GitForWindows']
|
||||
|
||||
Write-Host "Installing Git for Windows (silent, with PATH)..."
|
||||
$gitProc = Start-Process -FilePath $gitInstaller -ArgumentList @(
|
||||
'/VERYSILENT',
|
||||
'/NORESTART',
|
||||
'/NOCANCEL',
|
||||
'/SP-',
|
||||
'/COMPONENTS=assoc,assoc_sh,gitlfs,windowsterminal'
|
||||
) -Wait -PassThru
|
||||
|
||||
Remove-Item $gitInstaller -ErrorAction SilentlyContinue
|
||||
|
||||
if ($gitProc -and $gitProc.ExitCode -ne 0) {
|
||||
throw "Git installation failed (exit $($gitProc.ExitCode))."
|
||||
}
|
||||
|
||||
# Git installer adds to PATH automatically; refresh
|
||||
$env:PATH = [System.Environment]::GetEnvironmentVariable('PATH', 'Machine') + ';' +
|
||||
[System.Environment]::GetEnvironmentVariable('PATH', 'User')
|
||||
|
||||
Write-Host "Git installed: $(git --version 2>&1)"
|
||||
}
|
||||
|
||||
# Validation
|
||||
Assert-Step 'Git' 'git command resolvable' {
|
||||
[bool](Get-Command git -ErrorAction SilentlyContinue)
|
||||
}
|
||||
Assert-Step 'Git' 'git version matches or compatible' {
|
||||
$v = (& git --version 2>&1 | Select-Object -First 1).ToString()
|
||||
$v -match 'git version'
|
||||
}
|
||||
|
||||
# ── 7-Zip ─────────────────────────────────────────────────────────────────────
|
||||
$sevenZipDir = 'C:\Program Files\7-Zip'
|
||||
$sevenZipExe = Join-Path $sevenZipDir '7z.exe'
|
||||
|
||||
if (Test-Path $sevenZipExe) {
|
||||
Write-Host "7-Zip already installed."
|
||||
} else {
|
||||
$sevenZipUrl = "https://www.7-zip.org/a/7z$($SevenZipVersion -replace '\.', '')-x64.msi"
|
||||
$sevenZipMsi = 'C:\CI\7zip_installer.msi'
|
||||
|
||||
Write-Host "Downloading 7-Zip $SevenZipVersion..."
|
||||
try {
|
||||
Invoke-WebRequest -Uri $sevenZipUrl -OutFile $sevenZipMsi -UseBasicParsing
|
||||
} catch {
|
||||
throw "Failed to download 7-Zip from $sevenZipUrl : $_"
|
||||
}
|
||||
|
||||
Assert-Hash -FilePath $sevenZipMsi -Label "7z$($SevenZipVersion -replace '.', '')-x64.msi" `
|
||||
-Expected $script:Hashes['SevenZip']
|
||||
|
||||
Write-Host "Installing 7-Zip via MSI..."
|
||||
$msiProc = Start-Process -FilePath 'msiexec.exe' -ArgumentList @(
|
||||
'/i', $sevenZipMsi,
|
||||
'/quiet',
|
||||
'/norestart'
|
||||
) -Wait -PassThru
|
||||
|
||||
Remove-Item $sevenZipMsi -ErrorAction SilentlyContinue
|
||||
|
||||
if ($msiProc -and $msiProc.ExitCode -notin @(0, 3010)) {
|
||||
throw "7-Zip installation failed (exit $($msiProc.ExitCode))."
|
||||
}
|
||||
|
||||
Write-Host "7-Zip installed."
|
||||
}
|
||||
|
||||
# Validation
|
||||
Assert-Step '7-Zip' '7z.exe exists at expected path' {
|
||||
Test-Path -Path $sevenZipExe -PathType Leaf
|
||||
}
|
||||
Assert-Step '7-Zip' '7z command resolvable' {
|
||||
[bool](Get-Command 7z -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
Write-Host "Tier-1 Toolchain installation complete." -ForegroundColor Green
|
||||
|
||||
# ── Cleanup ───────────────────────────────────────────────────────────────────
|
||||
if ($SkipCleanup) {
|
||||
Write-Host "`n[Setup] Skipping disk cleanup (-SkipCleanup switch set)." -ForegroundColor Yellow
|
||||
@@ -1125,7 +1252,15 @@ Assert-Step 'Final' 'no leftover installer scripts in C:\CI' {
|
||||
-not (Test-Path 'C:\CI\python_installer.exe') -and
|
||||
-not (Test-Path 'C:\CI\vs_BuildTools.exe') -and
|
||||
-not (Test-Path 'C:\CI\wu_worker.ps1') -and
|
||||
-not (Test-Path 'C:\CI\vs_worker.ps1')
|
||||
-not (Test-Path 'C:\CI\vs_worker.ps1') -and
|
||||
-not (Test-Path 'C:\CI\git_installer.exe') -and
|
||||
-not (Test-Path 'C:\CI\7zip_installer.msi')
|
||||
}
|
||||
Assert-Step 'Final' 'git command available' {
|
||||
[bool](Get-Command git -ErrorAction SilentlyContinue)
|
||||
}
|
||||
Assert-Step 'Final' '7z command available' {
|
||||
[bool](Get-Command 7z -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
Write-Host "All pre-snapshot checks passed." -ForegroundColor Green
|
||||
|
||||
Reference in New Issue
Block a user