# Prefer a Gitea-hosted node:20-alpine so docker build does not HEAD registry-1.docker.io. # Order: local Gitea tag → pull Gitea → local Docker Hub tag → pull Hub (retries) → tag/push Gitea. param( [Parameter(Mandatory = $true)][string]$RegistryPrefix, [string]$OutFile = '.ci-node-image', [string]$HubImage = 'node:20-alpine' ) $ErrorActionPreference = 'Continue' $mirror = "$RegistryPrefix/node:20-alpine" function Test-Image([string]$Name) { docker image inspect $Name 2>&1 | Out-Null return ($LASTEXITCODE -eq 0) } function Invoke-Pull([string]$Name, [int]$Attempts) { for ($i = 1; $i -le $Attempts; $i++) { Write-Host "docker pull $Name (attempt $i/$Attempts)" docker pull $Name if ($LASTEXITCODE -eq 0) { return $true } if ($i -lt $Attempts) { Start-Sleep -Seconds (10 * $i) } } return $false } function Save-Choice([string]$Name) { $utf8 = New-Object System.Text.UTF8Encoding $false [System.IO.File]::WriteAllText((Join-Path (Get-Location) $OutFile), $Name + "`n", $utf8) Write-Host "NODE_IMAGE=$Name" } if (Test-Image $mirror) { Write-Host "Using local $mirror" Save-Choice $mirror exit 0 } if (Invoke-Pull $mirror 2) { Save-Choice $mirror exit 0 } if (-not (Test-Image $HubImage)) { if (-not (Invoke-Pull $HubImage 5)) { Write-Host "Cannot pull $HubImage from Docker Hub (TLS timeout or blocked)." Write-Host "On the Windows runner, when Hub is reachable:" Write-Host " docker pull $HubImage" Write-Host " docker tag $HubImage $mirror" Write-Host " docker push $mirror" Write-Host "Then re-run this workflow." exit 1 } } Write-Host "Tagging $HubImage as $mirror" docker tag $HubImage $mirror if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } docker push $mirror if ($LASTEXITCODE -ne 0) { Write-Host "Could not push $mirror — docker build will use the local tag (legacy builder)." $utf8 = New-Object System.Text.UTF8Encoding $false [System.IO.File]::WriteAllText((Join-Path (Get-Location) '.ci-use-legacy-builder'), "1`n", $utf8) } Save-Choice $mirror exit 0