Files
Fnos-Havline/build.ps1
T

147 lines
4.6 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
param(
[string]$FnpackPath = "",
[switch]$SkipImageExport
)
$ErrorActionPreference = "Stop"
$root = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
$project = Join-Path $root "fnos\havline"
$version = (Get-Content -Raw (Join-Path $root "havline\VERSION")).Trim()
function Resolve-DockerCli {
if ($env:DOCKER_BIN) { return $env:DOCKER_BIN }
$command = Get-Command docker -ErrorAction SilentlyContinue
if ($command) { return $command.Source }
$default = "C:\Program Files\Docker\Docker\resources\bin\docker.exe"
if (Test-Path -LiteralPath $default) { return $default }
throw "找不到 docker 命令"
}
function Export-OfflineImage {
param(
[string]$DockerBin,
[string]$BuildContext,
[string]$Platform,
[string]$Arch,
[string]$Version,
[string]$OutputDir
)
$tarName = "havline-$Version-$Arch.tar"
$tar = Join-Path $OutputDir $tarName
$gz = Join-Path $OutputDir "havline-$Version-$Arch.tar.gz"
Push-Location $BuildContext
try {
& $DockerBin buildx build `
--platform $Platform `
--build-arg VERSION_FILE=VERSION `
--provenance=false `
--sbom=false `
--output "type=docker,name=havline:$Version,dest=$tar" `
.
if ($LASTEXITCODE -ne 0) {
throw "导出 $Arch 镜像失败,退出码:$LASTEXITCODE"
}
}
finally {
Pop-Location
}
Compress-GzipFile -Source $tar -Destination $gz
Remove-Item -LiteralPath $tar -Force
Write-Output "镜像归档:$gz"
}
function Compress-GzipFile {
param(
[string]$Source,
[string]$Destination
)
$sourceStream = [System.IO.File]::OpenRead($Source)
try {
$targetStream = [System.IO.File]::Create($Destination)
try {
$gzip = New-Object System.IO.Compression.GZipStream($targetStream, [System.IO.Compression.CompressionLevel]::Optimal)
try {
$sourceStream.CopyTo($gzip)
}
finally {
$gzip.Dispose()
}
}
finally {
$targetStream.Dispose()
}
}
finally {
$sourceStream.Dispose()
}
}
if (-not (Test-Path -LiteralPath $project)) {
throw "找不到飞牛应用工程:$project"
}
# 版本一致性校验:Docker 版离线镜像标签为 havline:<主仓 VERSION>,
# 而容器运行时按 ${TRIM_APPVER}=manifest.version 加载镜像,两者必须严格一致。
$manifestVersion = ([regex]::Match((Get-Content -Raw (Join-Path $project "manifest")), '(?m)^version\s*=\s*(\S+)')).Groups[1].Value
if (-not $manifestVersion) {
throw "Docker manifest 缺少 version 字段:$(Join-Path $project 'manifest')"
}
Write-Output "App version: $version; Manifest version: $manifestVersion"
if ($manifestVersion -ne $version) {
throw "版本不一致:主仓 VERSION=$version,Docker manifest=$manifestVersion。镜像标签与运行时加载版本不匹配,请先将 fnos\havline\manifest 的 version 同步为主仓 VERSION。"
}
if (-not $FnpackPath) {
$localTool = Join-Path $PSScriptRoot "fnpack.exe"
$FnpackPath = if (Test-Path -LiteralPath $localTool) { $localTool } else { "fnpack" }
}
$stamp = Get-Date -Format "yyyyMMddHHmmss"
$stage = Join-Path $PSScriptRoot ".build\havline-$stamp"
New-Item -ItemType Directory -Force $stage | Out-Null
robocopy $project $stage /E /XF .DS_Store /NFL /NDL /NJH /NJS /NP | Out-Null
if ($LASTEXITCODE -ge 8) {
throw "复制飞牛应用工程失败,robocopy 退出码:$LASTEXITCODE"
}
$imageDir = Join-Path $stage "app\docker"
New-Item -ItemType Directory -Force $imageDir | Out-Null
if (-not $SkipImageExport) {
$dockerBin = Resolve-DockerCli
$buildContext = Join-Path $root "havline"
Export-OfflineImage -DockerBin $dockerBin -BuildContext $buildContext -Platform "linux/amd64" -Arch "amd64" -Version $version -OutputDir $imageDir
Export-OfflineImage -DockerBin $dockerBin -BuildContext $buildContext -Platform "linux/arm64" -Arch "arm64" -Version $version -OutputDir $imageDir
}
else {
foreach ($arch in @("amd64", "arm64")) {
$required = Join-Path $imageDir "havline-$version-$arch.tar.gz"
if (-not (Test-Path -LiteralPath $required)) {
throw "缺少离线镜像:$required"
}
}
}
Push-Location $PSScriptRoot
try {
& $FnpackPath build -d $stage
if ($LASTEXITCODE -ne 0) {
throw "fnpack build 失败,退出码:$LASTEXITCODE"
}
$output = Join-Path $PSScriptRoot "havline.fpk"
$dist = Join-Path $PSScriptRoot "dist"
New-Item -ItemType Directory -Force $dist | Out-Null
Copy-Item -LiteralPath $output -Destination (Join-Path $dist "havline-$version.fpk") -Force
Write-Output "FPK: $(Join-Path $dist "havline-$version.fpk")"
$sizeMB = [math]::Round((Get-Item (Join-Path $dist "havline-$version.fpk")).Length / 1MB, 1)
Write-Output "FPK 大小:$sizeMB MB"
}
finally {
Pop-Location
}