80 lines
3.9 KiB
PowerShell
80 lines
3.9 KiB
PowerShell
param([string]$Version, [switch]$RebuildWeb)
|
|
$ErrorActionPreference = 'Stop'
|
|
. (Join-Path $PSScriptRoot 'build-lock.ps1')
|
|
$buildLock = Enter-LinkPortBuildLock
|
|
$previousPath = $env:PATH
|
|
try {
|
|
$totalTimer = [Diagnostics.Stopwatch]::StartNew()
|
|
$phaseTimer = [Diagnostics.Stopwatch]::StartNew()
|
|
function Write-PhaseTime([string]$Name) {
|
|
Write-Host ('{0}: {1:N1}s' -f $Name, $phaseTimer.Elapsed.TotalSeconds)
|
|
$phaseTimer.Restart()
|
|
}
|
|
. (Join-Path $PSScriptRoot 'version.ps1')
|
|
$buildInfo = Get-linkportBuildInfo -Version $Version
|
|
$Version = $buildInfo.Version
|
|
$repo = Split-Path $PSScriptRoot -Parent
|
|
. (Join-Path $PSScriptRoot 'go-toolchain.ps1')
|
|
$goExecutable = Get-LinkPortGoExecutable -ProjectRoot $repo
|
|
. (Join-Path $PSScriptRoot 'node-toolchain.ps1')
|
|
$nodeExecutable = Initialize-LinkPortNodeRuntime -ProjectRoot $repo
|
|
$stamp = (Get-Date -Format 'yyyyMMdd-HHmmss-fff') + '-' + [Guid]::NewGuid().ToString('N').Substring(0, 8)
|
|
$releaseRoot = Join-Path $repo "bin/releases/$stamp"
|
|
$stage = [IO.Path]::GetFullPath((Join-Path $repo "bin/build-cache/package-$stamp"))
|
|
$binary = Join-Path $stage 'linkport.exe'
|
|
$releaseBinary = Join-Path $releaseRoot 'linkport.exe'
|
|
$previous = @{}
|
|
foreach ($key in @('GOTOOLCHAIN','GO111MODULE','GOOS','GOARCH','CGO_ENABLED','LINKPORT_NO_BROWSER')) { $previous[$key] = [Environment]::GetEnvironmentVariable($key, 'Process') }
|
|
$keepPath = Join-Path $repo 'web/dist/.gitkeep'
|
|
$hadKeep = Test-Path -LiteralPath $keepPath
|
|
$keepBytes = [byte[]]@()
|
|
if ($hadKeep) { $keepBytes = [IO.File]::ReadAllBytes($keepPath) }
|
|
Push-Location -LiteralPath $repo
|
|
try {
|
|
$env:GOTOOLCHAIN = 'go1.27.1'
|
|
$env:GO111MODULE = 'on'
|
|
$env:LINKPORT_NO_BROWSER = '1'
|
|
$env:GOOS = 'windows'
|
|
$env:GOARCH = 'amd64'
|
|
$env:CGO_ENABLED = '0'
|
|
$webArguments = @((Join-Path $PSScriptRoot 'build-web.mjs'))
|
|
if ($RebuildWeb) { $webArguments += '--force' }
|
|
& $nodeExecutable @webArguments
|
|
if ($LASTEXITCODE -ne 0) { throw 'Frontend build failed' }
|
|
Write-PhaseTime 'Frontend and dependencies'
|
|
New-Item -ItemType Directory -Path $stage | Out-Null
|
|
& $goExecutable build -trimpath -ldflags $buildInfo.LDFlags -o $binary ./cmd/linkport
|
|
if ($LASTEXITCODE -ne 0) { throw 'linkport release build failed' }
|
|
Write-PhaseTime 'Go build'
|
|
& $nodeExecutable (Join-Path $PSScriptRoot 'verify-package.mjs') $stage
|
|
if ($LASTEXITCODE -ne 0) { throw 'Package verification failed' }
|
|
Write-PhaseTime 'Executable verification'
|
|
# Publish only after verification. The generated paths must stay in this repository.
|
|
$cacheRoot = [IO.Path]::GetFullPath((Join-Path $repo 'bin/build-cache')) + [IO.Path]::DirectorySeparatorChar
|
|
$releasesRoot = [IO.Path]::GetFullPath((Join-Path $repo 'bin/releases'))
|
|
$releaseRoot = [IO.Path]::GetFullPath($releaseRoot)
|
|
if (!$stage.StartsWith($cacheRoot, [StringComparison]::OrdinalIgnoreCase) -or
|
|
!(($releaseRoot + [IO.Path]::DirectorySeparatorChar).StartsWith($releasesRoot + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase))) {
|
|
throw 'Unexpected package output path'
|
|
}
|
|
$digest = (Get-FileHash -LiteralPath $binary -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
New-Item -ItemType Directory -Path $releasesRoot -Force | Out-Null
|
|
if (Test-Path -LiteralPath $releaseRoot) { throw 'Release directory already exists' }
|
|
Move-Item -LiteralPath $stage -Destination $releaseRoot
|
|
Write-Output $releaseBinary
|
|
Write-Output "SHA256: $digest"
|
|
Write-PhaseTime 'Single EXE output'
|
|
Write-Host ('Total: {0:N1}s' -f $totalTimer.Elapsed.TotalSeconds)
|
|
} finally {
|
|
if ($hadKeep) {
|
|
New-Item -ItemType Directory -Path (Split-Path $keepPath -Parent) -Force | Out-Null
|
|
[IO.File]::WriteAllBytes($keepPath, [byte[]]$keepBytes)
|
|
}
|
|
foreach ($key in $previous.Keys) { [Environment]::SetEnvironmentVariable($key, $previous[$key], 'Process') }
|
|
Pop-Location
|
|
}
|
|
} finally {
|
|
$env:PATH = $previousPath
|
|
$buildLock.Dispose()
|
|
}
|