Files
supern2n/scripts/build.ps1
T
chun_qiu c955401fb4
Build Windows Portable Package / portable (push) Has been cancelled
Initial Super N2N desktop application
2026-09-01 13:30:52 +08:00

151 lines
5.0 KiB
PowerShell

[CmdletBinding()]
param(
[switch]$Clean,
[switch]$SkipTests
)
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
$projectRoot = Split-Path -Parent $PSScriptRoot
$n2nRoot = Join-Path $projectRoot 'third_party\n2n'
$cargoManifest = Join-Path $projectRoot 'src-tauri\Cargo.toml'
$packageScript = Join-Path $PSScriptRoot 'package-portable.ps1'
$n2nBuildScript = Join-Path $PSScriptRoot 'build-n2n.sh'
$archivePath = Join-Path $projectRoot 'release\super-n2n-portable.zip'
$checksumPath = $archivePath + '.sha256'
function Get-RequiredCommand {
param(
[string[]]$Names,
[string]$Purpose
)
foreach ($name in $Names) {
$command = Get-Command $name -CommandType Application -ErrorAction SilentlyContinue | Select-Object -First 1
if ($command) {
return $command.Source
}
}
throw "Missing required tool for $Purpose. Expected one of: $($Names -join ', ')."
}
function Get-GitBash {
param([string]$GitExecutable)
$gitRoot = Split-Path -Parent (Split-Path -Parent $GitExecutable)
$candidatePaths = @(
(Join-Path $gitRoot 'bin\bash.exe')
)
$candidatePaths += Get-Command bash.exe -CommandType Application -All -ErrorAction SilentlyContinue | ForEach-Object Source
foreach ($bashPath in $candidatePaths | Select-Object -Unique) {
if (-not (Test-Path -LiteralPath $bashPath)) {
continue
}
$bashDirectory = Split-Path -Parent $bashPath
$gitUnixBinCandidates = @(
$bashDirectory,
(Join-Path (Split-Path -Parent $bashDirectory) 'usr\bin')
)
foreach ($gitUnixBin in $gitUnixBinCandidates) {
if ((Test-Path -LiteralPath (Join-Path $gitUnixBin 'sh.exe')) -and
(Test-Path -LiteralPath (Join-Path $gitUnixBin 'cygpath.exe'))) {
return [pscustomobject]@{
Bash = $bashPath
UnixBin = $gitUnixBin
}
}
}
}
throw 'Git Bash was not found. Install Git for Windows.'
}
function Invoke-Checked {
param(
[string]$Executable,
[string[]]$Arguments
)
& $Executable @Arguments
if ($LASTEXITCODE -ne 0) {
throw "Command failed with exit code ${LASTEXITCODE}: $Executable $($Arguments -join ' ')"
}
}
if ($env:OS -ne 'Windows_NT') {
throw 'This script builds the Windows portable package and must run on Windows.'
}
$git = Get-RequiredCommand -Names @('git.exe', 'git') -Purpose 'source checkout'
$npm = Get-RequiredCommand -Names @('npm.cmd', 'npm') -Purpose 'frontend dependency installation'
$cargo = Get-RequiredCommand -Names @('cargo.exe', 'cargo') -Purpose 'Tauri compilation'
$gitBash = Get-GitBash -GitExecutable $git
$make = Get-RequiredCommand -Names @('mingw32-make.exe', 'mingw32-make') -Purpose 'n2n compilation'
$null = Get-RequiredCommand -Names @('gcc.exe', 'gcc') -Purpose 'n2n compilation'
$null = Get-RequiredCommand -Names @('windres.exe', 'windres') -Purpose 'n2n Windows resource compilation'
# Make GNU utilities (rm, cp, gzip) available to n2n's Makefile on Windows.
$env:Path = "$($gitBash.UnixBin);$env:Path"
$env:SHELL = Join-Path $gitBash.UnixBin 'sh.exe'
Push-Location $projectRoot
try {
Invoke-Checked $git @('submodule', 'sync')
Invoke-Checked $git @('submodule', 'update', '--init')
if (-not (Test-Path -LiteralPath $n2nRoot)) {
throw "The n2n submodule was not initialized: $n2nRoot"
}
$cygpath = Join-Path $gitBash.UnixBin 'cygpath.exe'
$n2nRootUnix = (& $cygpath -u $n2nRoot).Trim()
$makeUnix = (& $cygpath -u $make).Trim()
$n2nBuildScriptUnix = (& $cygpath -u $n2nBuildScript).Trim()
Invoke-Checked $gitBash.Bash @($n2nBuildScriptUnix, $n2nRootUnix, $makeUnix, $(if ($Clean) { '1' } else { '0' }))
foreach ($binary in @('edge.exe', 'supernode.exe')) {
if (-not (Test-Path -LiteralPath (Join-Path $n2nRoot $binary))) {
throw "n2n build did not produce $binary."
}
}
Invoke-Checked $npm @('ci')
if (-not $SkipTests) {
Invoke-Checked $cargo @('test', '--manifest-path', $cargoManifest)
}
& $packageScript -Clean:$Clean
if ($LASTEXITCODE -ne 0) {
throw "Portable package script failed with exit code $LASTEXITCODE."
}
if (-not (Test-Path -LiteralPath $archivePath)) {
throw "Portable archive was not created: $archivePath"
}
$stream = [System.IO.File]::OpenRead($archivePath)
try {
$sha256 = [System.Security.Cryptography.SHA256]::Create()
try {
$hashBytes = $sha256.ComputeHash($stream)
$hash = -join ($hashBytes | ForEach-Object { $_.ToString('x2') })
}
finally {
$sha256.Dispose()
}
}
finally {
$stream.Dispose()
}
"$hash *$(Split-Path -Leaf $archivePath)" | Set-Content -LiteralPath $checksumPath -Encoding ascii
Write-Output "Build completed: $archivePath"
Write-Output "SHA-256 checksum: $checksumPath"
}
finally {
Pop-Location
}