111 lines
3.7 KiB
PowerShell
111 lines
3.7 KiB
PowerShell
#Requires -Version 5.1
|
|
<#
|
|
.SYNOPSIS
|
|
Build and push a CI image to the Harbor registry using podman.
|
|
|
|
.EXAMPLE
|
|
.\build-and-push.ps1 -Image ci/java-builder
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Image,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$Version
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# --- Load .env ---
|
|
$envFile = Join-Path $PSScriptRoot '.env'
|
|
if (-not (Test-Path $envFile)) { throw ".env not found at $envFile" }
|
|
|
|
Get-Content $envFile | ForEach-Object {
|
|
if ($_ -match '^\s*([^#=\s]+)\s*=\s*(.*?)\s*$') {
|
|
$value = $matches[2].TrimEnd("`r")
|
|
if ($value.StartsWith('"') -and $value.EndsWith('"')) { $value = $value.Substring(1, $value.Length - 2) }
|
|
elseif ($value.StartsWith("'") -and $value.EndsWith("'")) { $value = $value.Substring(1, $value.Length - 2) }
|
|
[Environment]::SetEnvironmentVariable($matches[1], $value)
|
|
}
|
|
}
|
|
|
|
foreach ($v in 'REGISTRY', 'REGISTRY_USER', 'REGISTRY_PASS') {
|
|
if (-not (Get-Item "env:$v" -ErrorAction SilentlyContinue).Value) {
|
|
throw "$v not set in .env"
|
|
}
|
|
}
|
|
|
|
# --- Resolve paths ---
|
|
# $Image is the path to the image directory relative to the repo root, and
|
|
# also the image name pushed to the registry (e.g. "ci/java-builder").
|
|
$regHost = $env:REGISTRY -replace '^https?://', '' -replace '/$', ''
|
|
$imageName = ($Image -replace '\\', '/').Trim('/')
|
|
$imageDir = Join-Path $PSScriptRoot ($imageName -replace '/', [IO.Path]::DirectorySeparatorChar)
|
|
if (-not (Test-Path $imageDir)) { throw "Image directory not found: $imageDir" }
|
|
|
|
$repo = "$regHost/kollect-tools/$imageName"
|
|
$date = Get-Date -Format 'yyyyMMdd'
|
|
|
|
# --- Resolve version ---
|
|
# If -Version isn't given, parse the Dockerfile: find the variable referenced
|
|
# in the FROM line and read its ARG default (e.g. JAVA_VERSION=25 -> "25").
|
|
if (-not $Version) {
|
|
$dockerfile = Join-Path $imageDir 'Dockerfile'
|
|
$content = Get-Content $dockerfile -Raw
|
|
if ($content -match '(?m)^\s*FROM\s+\S*?\$\{(\w+)\}') {
|
|
$varName = $matches[1]
|
|
if ($content -match "(?m)^\s*ARG\s+$varName\s*=\s*`"?([^`"\s]+)`"?") {
|
|
$Version = $matches[1]
|
|
}
|
|
}
|
|
if (-not $Version) {
|
|
throw "Could not auto-detect version from $dockerfile. Pass -Version explicitly."
|
|
}
|
|
Write-Host "=> Auto-detected version: $Version (from $varName)"
|
|
}
|
|
|
|
$tags = @('latest', $Version, $date)
|
|
|
|
# --- Login ---
|
|
# Use .NET Process so stdin gets the raw password with no trailing newline
|
|
# (PowerShell's native pipe appends CRLF, which breaks --password-stdin).
|
|
Write-Host "=> Logging in to $regHost"
|
|
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
|
$psi.FileName = 'podman'
|
|
$psi.Arguments = "login $regHost --username `"$($env:REGISTRY_USER)`" --password-stdin"
|
|
$psi.RedirectStandardInput = $true
|
|
$psi.UseShellExecute = $false
|
|
$proc = [System.Diagnostics.Process]::Start($psi)
|
|
$proc.StandardInput.Write($env:REGISTRY_PASS)
|
|
$proc.StandardInput.Close()
|
|
$proc.WaitForExit()
|
|
if ($proc.ExitCode -ne 0) { throw "podman login failed (exit $($proc.ExitCode))" }
|
|
|
|
# --- Build ---
|
|
Write-Host "=> Building ${repo}:latest"
|
|
$buildArgs = @('build', '-t', "${repo}:latest")
|
|
if ($env:NVD_API_KEY) {
|
|
$buildArgs += @('--build-arg', "NVD_API_KEY=$env:NVD_API_KEY")
|
|
}
|
|
$buildArgs += $imageDir
|
|
|
|
& podman @buildArgs
|
|
if ($LASTEXITCODE -ne 0) { throw "podman build failed" }
|
|
|
|
# --- Tag ---
|
|
foreach ($tag in $Version, $date) {
|
|
Write-Host "=> Tagging ${repo}:$tag"
|
|
podman tag "${repo}:latest" "${repo}:$tag"
|
|
if ($LASTEXITCODE -ne 0) { throw "podman tag failed for $tag" }
|
|
}
|
|
|
|
# --- Push ---
|
|
foreach ($tag in $tags) {
|
|
Write-Host "=> Pushing ${repo}:$tag"
|
|
podman push "${repo}:$tag"
|
|
if ($LASTEXITCODE -ne 0) { throw "podman push failed for $tag" }
|
|
}
|
|
|
|
Write-Host "Done. Pushed $($tags.Count) tags to $repo"
|