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
|
Validation: MSBuild.exe exists, executes, PATH, VC dir present
|
||||||
Step 10 — Toolchain cross-check (dotnet, python, msbuild)
|
Step 10 — Toolchain cross-check (dotnet, python, msbuild)
|
||||||
Throws on any missing tool
|
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
|
Cleanup — Disk cleanup: cleanmgr, SoftwareDistribution, CBS, TEMP, Prefetch, DISM
|
||||||
wuauserv already Disabled (Step 6b) — not restarted after cache clear
|
wuauserv already Disabled (Step 6b) — not restarted after cache clear
|
||||||
Validation: wuauserv StartType Disabled
|
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
|
Throws if any check fails — prevents snapshot of broken state
|
||||||
|
|
||||||
Step ordering rationale:
|
Step ordering rationale:
|
||||||
@@ -70,9 +73,10 @@
|
|||||||
WU (Step 6) — all prereqs validated; WU runs with Firewall+Defender already off
|
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
|
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
|
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
|
NOTE: Step 11 installs Git for Windows + 7-Zip (Tier-1 Toolchain §6.6).
|
||||||
for the planned addition. The host clones and copies source via WinRM until then.
|
This enables §3.3 (In-VM Git clone) and cross-platform build support.
|
||||||
|
|
||||||
╔══════════════════════════════════════════════════════════════════════╗
|
╔══════════════════════════════════════════════════════════════════════╗
|
||||||
║ NETWORK REQUIREMENT DURING SETUP ║
|
║ NETWORK REQUIREMENT DURING SETUP ║
|
||||||
@@ -137,7 +141,13 @@ param(
|
|||||||
|
|
||||||
# Administrator password — used only to write DefaultPassword for autologin.
|
# Administrator password — used only to write DefaultPassword for autologin.
|
||||||
# Optional: if empty, DefaultPassword registry value is left as-is (Deploy may have set it).
|
# 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
|
Set-StrictMode -Version Latest
|
||||||
@@ -199,6 +209,14 @@ $script:Hashes = @{
|
|||||||
# vs_buildtools.exe bootstrapper from aka.ms/vs/stable/vs_buildtools.exe
|
# vs_buildtools.exe bootstrapper from aka.ms/vs/stable/vs_buildtools.exe
|
||||||
# Stable within a VS release cycle — update when VS major version changes.
|
# Stable within a VS release cycle — update when VS major version changes.
|
||||||
'VSBuildToolsBootstrapper' = ''
|
'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 ───────────────
|
# ── Pre-flight: remove temp files from any previous partial run ───────────────
|
||||||
@@ -207,7 +225,7 @@ $script:Hashes = @{
|
|||||||
$knownTempFiles = @(
|
$knownTempFiles = @(
|
||||||
'C:\CI\wu_worker.ps1', 'C:\CI\wu_result.txt', 'C:\CI\wu_reboot.txt', 'C:\CI\wu_log.txt',
|
'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\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) {
|
foreach ($f in $knownTempFiles) {
|
||||||
if (Test-Path $f) {
|
if (Test-Path $f) {
|
||||||
@@ -960,6 +978,115 @@ if (-not $allOk) {
|
|||||||
}
|
}
|
||||||
Write-Host "All toolchain checks passed." -ForegroundColor Green
|
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 ───────────────────────────────────────────────────────────────────
|
# ── Cleanup ───────────────────────────────────────────────────────────────────
|
||||||
if ($SkipCleanup) {
|
if ($SkipCleanup) {
|
||||||
Write-Host "`n[Setup] Skipping disk cleanup (-SkipCleanup switch set)." -ForegroundColor Yellow
|
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\python_installer.exe') -and
|
||||||
-not (Test-Path 'C:\CI\vs_BuildTools.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\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
|
Write-Host "All pre-snapshot checks passed." -ForegroundColor Green
|
||||||
|
|||||||
Reference in New Issue
Block a user