param( [string]$Version = "", [string]$OutputDir = "dist", [ValidateSet("all", "win", "linux-x64", "linux-arm64")] [string]$Target = "all", [string]$RustImage = "docker.m.daocloud.io/library/rust:1-bookworm", [string]$CargoRegistry = "sparse+https://rsproxy.cn/index/", [string]$AptMirror = "https://mirrors.ustc.edu.cn/debian", [switch]$DockerWindows, [switch]$Clean ) $ErrorActionPreference = "Stop" $repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..") Set-Location $repoRoot if (-not $Version) { $cargoToml = Get-Content -Raw -Path "Cargo.toml" if ($cargoToml -notmatch '(?m)^version\s*=\s*"([^"]+)"') { throw "Cannot read package version from Cargo.toml" } $Version = $Matches[1] } $dist = Join-Path $repoRoot $OutputDir if ($Clean -and (Test-Path $dist)) { Remove-Item -LiteralPath $dist -Recurse -Force } New-Item -ItemType Directory -Force -Path $dist | Out-Null function Copy-ReleaseFile { param( [string]$SourceFile, [string]$OutputName ) if (-not (Test-Path $SourceFile)) { throw "Missing release binary: $SourceFile" } $outputPath = Join-Path $dist $OutputName Copy-Item -LiteralPath $SourceFile -Destination $outputPath -Force Write-Host "Wrote $outputPath" } function Build-DockerRelease { param( [string]$Name, [string]$RustTarget, [string]$Platform, [string]$ContainerBinary = "cdxs", [string]$OutputName = "cdxs-$Version-$Name" ) $safeRunId = if ($env:GITHUB_RUN_ID) { $env:GITHUB_RUN_ID } else { [guid]::NewGuid().ToString("N") } $imageTag = "cdxs-build:$Name-$safeRunId" $containerName = "cdxs-build-$Name-$safeRunId" Write-Host "Building $Name with Docker platform $Platform" docker buildx build ` --platform $Platform ` --target builder ` --build-arg "RUST_TARGET=$RustTarget" ` --build-arg "RUST_IMAGE=$RustImage" ` --build-arg "CARGO_REGISTRY=$CargoRegistry" ` --build-arg "APT_MIRROR=$AptMirror" ` --load ` -t $imageTag ` -f "scripts/docker/Dockerfile.release" ` . if ($LASTEXITCODE -ne 0) { throw "Docker build failed for $Name" } $containerId = docker create --name $containerName $imageTag if ($LASTEXITCODE -ne 0 -or -not $containerId) { throw "Docker create failed for $imageTag" } try { $tmpOutDir = Join-Path $dist ".tmp-$Name" New-Item -ItemType Directory -Force -Path $tmpOutDir | Out-Null docker cp "${containerName}:/out/$ContainerBinary" (Join-Path $tmpOutDir $ContainerBinary) if ($LASTEXITCODE -ne 0) { throw "Docker cp failed for $Name" } Copy-ReleaseFile ` -SourceFile (Join-Path $tmpOutDir $ContainerBinary) ` -OutputName $OutputName } finally { docker rm -f $containerName | Out-Null if (Test-Path $tmpOutDir) { Remove-Item -LiteralPath $tmpOutDir -Recurse -Force } } } if ($Target -eq "all" -or $Target -eq "win") { if ($DockerWindows) { Build-DockerRelease ` -Name "windows-x64" ` -RustTarget "x86_64-pc-windows-gnu" ` -Platform "linux/amd64" ` -ContainerBinary "cdxs.exe" ` -OutputName "cdxs-$Version-windows-x64.exe" } else { Write-Host "Building Windows x64" cargo build --release --target x86_64-pc-windows-msvc if ($LASTEXITCODE -ne 0) { throw "Windows build failed" } Copy-ReleaseFile ` -SourceFile (Join-Path $repoRoot "target/x86_64-pc-windows-msvc/release/cdxs.exe") ` -OutputName "cdxs-$Version-windows-x64.exe" } } if ($Target -eq "all" -or $Target -eq "linux-x64") { Build-DockerRelease ` -Name "linux-x64" ` -RustTarget "x86_64-unknown-linux-gnu" ` -Platform "linux/amd64" } if ($Target -eq "all" -or $Target -eq "linux-arm64") { Build-DockerRelease ` -Name "linux-arm64" ` -RustTarget "aarch64-unknown-linux-gnu" ` -Platform "linux/arm64" } Write-Host "Release artifacts are in $dist"