fix(TST-25): serialize the CI bootstrap fetch/checkout under the worktree lock
Acceptance-check finding (concurrency): the worktree lock in windev-worker-ci.ps1 guarded the build stage, but run-windev-ci.sh's bootstrap did git fetch + git checkout on the shared C:\build\mxaccessgw-ci clone BEFORE that lock was taken. Two concurrent runs therefore collided on .git/index.lock at the bootstrap stage (the second failed 'Another git process seems to be running', exit 1) instead of the second waiting — defeating the lock's purpose for manual/degraded-mode overlap or a future second runner. (The single Gitea runner serializes jobs, so CI pushes never actually overlapped; this is defense-in-depth being restored.) Fix: the bootstrap now acquires the same mkdir worktree lock around its fetch/ checkout and exports MXGW_CI_LOCK_HELD; windev-worker-ci.ps1 re-uses that lock (skips re-acquire/release) when the env is set, and still self-locks for a standalone/manual run. Now the second concurrent run waits at the bootstrap.
This commit is contained in:
@@ -68,19 +68,28 @@ function Invoke-Native {
|
||||
}
|
||||
|
||||
# --- acquire the worktree lock (mkdir is atomic; retry until timeout) ---
|
||||
# run-windev-ci.sh's bootstrap already holds this lock around its pre-hand-off fetch/checkout
|
||||
# (MXGW_CI_LOCK_HELD=1) so that stage can't race a concurrent run; re-use it rather than
|
||||
# re-acquire (and leave releasing to the bootstrap). A standalone/manual run (degraded mode)
|
||||
# has no such env and self-locks here as before.
|
||||
$deadline = (Get-Date).Add($lockTimeout)
|
||||
$haveLock = $false
|
||||
Write-Log "Acquiring worktree lock $lockDir (mode=$Mode sha=$Sha)"
|
||||
while (-not $haveLock) {
|
||||
try {
|
||||
New-Item -Path $lockDir -ItemType Directory -ErrorAction Stop | Out-Null
|
||||
$haveLock = $true
|
||||
}
|
||||
catch {
|
||||
if ((Get-Date) -ge $deadline) {
|
||||
throw "Timed out after $($lockTimeout.TotalMinutes) min waiting for worktree lock $lockDir. A stuck run may have left it; if no CI job is active, remove it by hand."
|
||||
if ($env:MXGW_CI_LOCK_HELD -eq '1') {
|
||||
Write-Log "Worktree lock already held by bootstrap (mode=$Mode sha=$Sha)"
|
||||
}
|
||||
else {
|
||||
Write-Log "Acquiring worktree lock $lockDir (mode=$Mode sha=$Sha)"
|
||||
while (-not $haveLock) {
|
||||
try {
|
||||
New-Item -Path $lockDir -ItemType Directory -ErrorAction Stop | Out-Null
|
||||
$haveLock = $true
|
||||
}
|
||||
catch {
|
||||
if ((Get-Date) -ge $deadline) {
|
||||
throw "Timed out after $($lockTimeout.TotalMinutes) min waiting for worktree lock $lockDir. A stuck run may have left it; if no CI job is active, remove it by hand."
|
||||
}
|
||||
Start-Sleep -Seconds 10
|
||||
}
|
||||
Start-Sleep -Seconds 10
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user