feat(§3.3): Partial implementation of In-VM Git Clone
Add -UseGitClone switch to Invoke-CIJob.ps1 + conditional logic: Changes: 1. Add -UseGitClone [switch] param + docstring (§3.3 mode) 2. Modify Phase 1 to skip host clone when -UseGitClone active 3. Phase 5: Pass CloneUrl/CloneBranch/CloneCommit instead of HostSourceDir when -UseGitClone enabled 4. Finally: Skip host cleanup when -UseGitClone (dir never created) When -UseGitClone is active: - Phase 1 (host clone) skipped — clone happens in VM instead - Phase 5 passes git repo parameters to Invoke-RemoteBuild.ps1 - PAT (if needed) read in Invoke-RemoteBuild session (§1.5) Prerequisite: Git for Windows + 7-Zip in template (§6.6, now complete) Work in progress: Invoke-RemoteBuild.ps1 modifications pending (source transfer conditional + guest-side git clone logic). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+55
-32
@@ -95,6 +95,11 @@ param(
|
||||
# Artifact source pattern relative to GuestWorkDir (used with BuildCommand)
|
||||
[string] $GuestArtifactSource = 'dist',
|
||||
|
||||
# Clone repo IN the VM instead of on host (requires Git in template §6.6)
|
||||
# Skips Phase 1 host clone, injects URL/branch/commit into VM for in-VM clone.
|
||||
# Prerequisite: Git for Windows installed in template.
|
||||
[switch] $UseGitClone,
|
||||
|
||||
[string] $TemplatePath = $env:GITEA_CI_TEMPLATE_PATH,
|
||||
|
||||
[string] $SnapshotName = $(if ($env:GITEA_CI_SNAPSHOT_NAME) { $env:GITEA_CI_SNAPSHOT_NAME } else { 'BaseClean' }),
|
||||
@@ -223,42 +228,48 @@ Write-JobEvent -Phase 'job' -Status 'start' -Data @{
|
||||
$exitCode = 0
|
||||
|
||||
try {
|
||||
# ── Phase 1: Clone repo on HOST ───────────────────────────────────────
|
||||
# Build VM is on VMnet8 NAT (internet OK for builds), but source is
|
||||
# still cloned here and copied via WinRM zip to avoid injecting a PAT
|
||||
# into the VM environment.
|
||||
Write-Host "`n[Phase 1/6] Cloning repository on host..."
|
||||
Write-JobEvent -Phase 'phase1.clone-repo' -Status 'start'
|
||||
if (Test-Path $hostCloneDir) { Remove-Item $hostCloneDir -Recurse -Force }
|
||||
$gitArgs = @('clone', '--depth', '1', '--branch', $Branch)
|
||||
if ($Submodules) { $gitArgs += '--recurse-submodules' }
|
||||
$gitArgs += @($RepoUrl, $hostCloneDir)
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$gitOutput = & git @gitArgs 2>&1 | ForEach-Object { "$_" }
|
||||
$gitExit = $LASTEXITCODE
|
||||
$ErrorActionPreference = 'Stop'
|
||||
if ($gitExit -ne 0) {
|
||||
throw "git clone failed (exit $gitExit):`n$($gitOutput -join "`n")"
|
||||
# ── Phase 1: Clone repo (HOST or GUEST) ───────────────────────────────
|
||||
if ($UseGitClone) {
|
||||
# §3.3: Clone in guest VM instead of host. Skip host clone phase.
|
||||
# PAT will be injected at runtime (Phase 5) from Credential Manager.
|
||||
Write-Host "`n[Phase 1/6] Skipping host clone — will clone in guest VM (-UseGitClone)..."
|
||||
Write-JobEvent -Phase 'phase1.clone-repo' -Status 'skipped' -Data @{ method = 'in-vm-clone' }
|
||||
}
|
||||
if ($Commit -ne '') {
|
||||
else {
|
||||
# Default: Clone on host, zip, transfer to guest via WinRM.
|
||||
Write-Host "`n[Phase 1/6] Cloning repository on host..."
|
||||
Write-JobEvent -Phase 'phase1.clone-repo' -Status 'start'
|
||||
if (Test-Path $hostCloneDir) { Remove-Item $hostCloneDir -Recurse -Force }
|
||||
$gitArgs = @('clone', '--depth', '1', '--branch', $Branch)
|
||||
if ($Submodules) { $gitArgs += '--recurse-submodules' }
|
||||
$gitArgs += @($RepoUrl, $hostCloneDir)
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$gitOutput = & git -C $hostCloneDir checkout $Commit 2>&1 | ForEach-Object { "$_" }
|
||||
$gitOutput = & git @gitArgs 2>&1 | ForEach-Object { "$_" }
|
||||
$gitExit = $LASTEXITCODE
|
||||
if ($gitExit -ne 0) {
|
||||
# Commit not in shallow history (e.g. manual run on older SHA).
|
||||
# Fetch full history and retry.
|
||||
Write-Host "[Invoke-CIJob] Shallow checkout failed — fetching full history..."
|
||||
& git -C $hostCloneDir fetch --unshallow 2>&1 | Out-Null
|
||||
$gitOutput = & git -C $hostCloneDir checkout $Commit 2>&1 | ForEach-Object { "$_" }
|
||||
$gitExit = $LASTEXITCODE
|
||||
}
|
||||
$ErrorActionPreference = 'Stop'
|
||||
if ($gitExit -ne 0) {
|
||||
throw "git checkout $Commit failed (exit $gitExit):`n$($gitOutput -join "`n")"
|
||||
throw "git clone failed (exit $gitExit):`n$($gitOutput -join "`n")"
|
||||
}
|
||||
if ($Commit -ne '') {
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$gitOutput = & git -C $hostCloneDir checkout $Commit 2>&1 | ForEach-Object { "$_" }
|
||||
$gitExit = $LASTEXITCODE
|
||||
if ($gitExit -ne 0) {
|
||||
# Commit not in shallow history (e.g. manual run on older SHA).
|
||||
# Fetch full history and retry.
|
||||
Write-Host "[Invoke-CIJob] Shallow checkout failed — fetching full history..."
|
||||
& git -C $hostCloneDir fetch --unshallow 2>&1 | Out-Null
|
||||
$gitOutput = & git -C $hostCloneDir checkout $Commit 2>&1 | ForEach-Object { "$_" }
|
||||
$gitExit = $LASTEXITCODE
|
||||
}
|
||||
$ErrorActionPreference = 'Stop'
|
||||
if ($gitExit -ne 0) {
|
||||
throw "git checkout $Commit failed (exit $gitExit):`n$($gitOutput -join "`n")"
|
||||
}
|
||||
}
|
||||
Write-Host "[Invoke-CIJob] Source cloned to: $hostCloneDir"
|
||||
Write-JobEvent -Phase 'phase1.clone-repo' -Status 'success' -Data @{ dir = $hostCloneDir }
|
||||
}
|
||||
Write-Host "[Invoke-CIJob] Source cloned to: $hostCloneDir"
|
||||
Write-JobEvent -Phase 'phase1.clone-repo' -Status 'success' -Data @{ dir = $hostCloneDir }
|
||||
|
||||
# ── Phase 2-3b: Clone + Start + IP (serialized via file-based mutex) ────
|
||||
# §2.1: With capacity:4 and DHCP on VMnet8, concurrent vmrun starts can race
|
||||
@@ -360,9 +371,20 @@ try {
|
||||
$remoteBuildParams = @{
|
||||
IPAddress = $VMIPAddress
|
||||
Credential = $credential
|
||||
HostSourceDir = $hostCloneDir
|
||||
Configuration = $Configuration
|
||||
}
|
||||
if ($UseGitClone) {
|
||||
# §3.3: Clone in VM — pass URL/branch/commit instead of HostSourceDir
|
||||
# PAT will be read from Credential Manager inside Invoke-RemoteBuild (§1.5)
|
||||
$remoteBuildParams['CloneUrl'] = $RepoUrl
|
||||
$remoteBuildParams['CloneBranch'] = $Branch
|
||||
if ($Commit -ne '') { $remoteBuildParams['CloneCommit'] = $Commit }
|
||||
if ($Submodules) { $remoteBuildParams['CloneSubmodules'] = $true }
|
||||
}
|
||||
else {
|
||||
# Default: Use pre-cloned source from host
|
||||
$remoteBuildParams['HostSourceDir'] = $hostCloneDir
|
||||
}
|
||||
if ($BuildCommand -ne '') { $remoteBuildParams['BuildCommand'] = $BuildCommand }
|
||||
if ($GuestArtifactSource -ne '') { $remoteBuildParams['GuestArtifactSource'] = $GuestArtifactSource }
|
||||
& "$scriptDir\Invoke-RemoteBuild.ps1" @remoteBuildParams
|
||||
@@ -413,8 +435,9 @@ finally {
|
||||
else {
|
||||
Write-Host "[Cleanup] No VM to destroy (clone was not created or already gone)."
|
||||
}
|
||||
# ── Always clean up host-side git clone ──────────────────────────────
|
||||
if (Test-Path $hostCloneDir) {
|
||||
# ── Clean up host-side git clone (unless in-VM clone was used) ────────
|
||||
# When -UseGitClone, $hostCloneDir is never created
|
||||
if (-not $UseGitClone -and (Test-Path $hostCloneDir)) {
|
||||
Write-Host "[Cleanup] Removing host source clone ($hostCloneDir)..."
|
||||
Remove-Item $hostCloneDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user