From b2c0b986c4c432526b5aae6959184e84168e017d Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 25 Aug 2025 13:17:16 +0800 Subject: [PATCH] =?UTF-8?q?build:=20=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E5=B9=B6=E9=87=8D=E6=9E=84=E5=8F=91=E5=B8=83=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -重构 release-linux.ps1 脚本,添加版本号读取和输出路径定义 - 新增 release-windows.ps1 脚本,实现 Windows 版本的构建和打包 - 添加 dotenv.ps1工具脚本,用于统一解析 .env 文件 --- .env | 2 +- build/release-linux.ps1 | 37 ++++++++++-- build/release-windows.ps1 | 117 ++++++++++++++++++++++++++++++++++++++ build/tools/dotenv.ps1 | 53 +++++++++++++++++ 4 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 build/release-windows.ps1 create mode 100644 build/tools/dotenv.ps1 diff --git a/.env b/.env index 528ad70..0d696e3 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ # Auto-generated by build\tools\generate-dotenv.ps1 -SNOW_VERSION=0.7.0 +SNOW_VERSION=0.8.0 diff --git a/build/release-linux.ps1 b/build/release-linux.ps1 index b3a332b..5503242 100644 --- a/build/release-linux.ps1 +++ b/build/release-linux.ps1 @@ -1,11 +1,17 @@ # run-linux-snow-export.ps1 +# Build and package linux-snow-export, version read from SNOW_VERSION in .env + +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" + +# Import shared dotenv parser function +. "$PSScriptRoot\tools\dotenv.ps1" Write-Host "Step 0: Generate .env..." try { & "$PSScriptRoot\tools\generate-dotenv.ps1" -ErrorAction Stop -} -catch { - Write-Error "Failed to generate .env: $($_.Exception.Message)" +} catch { + Write-Error "Failed to generate .env: $( $_.Exception.Message )" exit 1 } @@ -23,4 +29,27 @@ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } -Write-Host "All steps completed successfully!" +# ===== Step 3: Read version from .env ===== +$projectRoot = Resolve-Path (Join-Path $PSScriptRoot "..") +$dotenvPath = Join-Path $projectRoot ".env" + +if (-not (Test-Path -LiteralPath $dotenvPath)) { + Write-Error ".env not found at: $dotenvPath" + exit 1 +} + +$version = Read-DotEnvValue -FilePath $dotenvPath -Key 'SNOW_VERSION' +if (-not $version) { + Write-Error "SNOW_VERSION not found in .env" + exit 1 +} + +# ===== Step 4: Define output paths ===== +$targetDir = Join-Path $projectRoot "target\release" +$outDir = Join-Path $targetDir "Snow-v$version-linux-x64" +$tgzPath = Join-Path $targetDir "Snow-v$version-linux-x64.tgz" + +Write-Host ">>> Package ready!" -ForegroundColor Green +Write-Host "Version : $version" +Write-Host "Output Dir : $outDir" +Write-Host "Tgz File : $tgzPath" \ No newline at end of file diff --git a/build/release-windows.ps1 b/build/release-windows.ps1 new file mode 100644 index 0000000..f3c24f7 --- /dev/null +++ b/build/release-windows.ps1 @@ -0,0 +1,117 @@ +# release-windows.ps1 + +$ErrorActionPreference = 'Stop' +$ProgressPreference = 'SilentlyContinue' +Set-StrictMode -Version Latest + +# Import shared dotenv parser function +. "$PSScriptRoot\tools\dotenv.ps1" + +# ===== Utility Functions ===== +function Find-PomUpwards([string]$startDir) { + $dir = Resolve-Path $startDir + while ($true) { + $pom = Join-Path $dir "pom.xml" + if (Test-Path $pom) { return $pom } + $parent = Split-Path $dir -Parent + if ($parent -eq $dir -or [string]::IsNullOrEmpty($parent)) { return $null } + $dir = $parent + } +} + +# ===== Step 0: Generate .env ===== +Write-Host "Step 0: Generate .env..." +try { + & "$PSScriptRoot\tools\generate-dotenv.ps1" -ErrorAction Stop +} catch { + Write-Error "Failed to generate .env: $($_.Exception.Message)" + exit 1 +} + +# ===== Step 1: Locate project root & build ===== +Write-Host "Step 1: Locate project root and build..." +$pom = Find-PomUpwards -startDir $PSScriptRoot +if (-not $pom) { + Write-Error "pom.xml not found. Please run this script within the project." + exit 1 +} + +$projectRoot = Split-Path $pom -Parent +Push-Location $projectRoot +try { + Write-Host "→ Running: mvn clean package" + mvn clean package + if ($LASTEXITCODE -ne 0) { + Write-Error "Maven build failed, exiting script." + exit $LASTEXITCODE + } + + # ===== Step 2: Read SNOW_VERSION ===== + Write-Host "Step 2: Read SNOW_VERSION from .env..." + $dotenvPath = Join-Path $projectRoot ".env" + $snowVersion = Read-DotEnvValue -FilePath $dotenvPath -Key "SNOW_VERSION" + if (-not $snowVersion) { + Write-Host "SNOW_VERSION not found in .env, using placeholder 0.0.0." -ForegroundColor Yellow + $snowVersion = "0.0.0" + } + Write-Host "SNOW_VERSION = $snowVersion" + + # ===== Step 3: Prepare release directory structure ===== + Write-Host "Step 3: Prepare release directory structure..." + $targetDir = Join-Path $projectRoot "target" + $exePath = Join-Path $targetDir "Snow.exe" + if (-not (Test-Path $exePath)) { + Write-Error "Expected build artifact not found: $exePath" + exit 1 + } + + $verName = "Snow-v${snowVersion}-windows-x64" + $releaseRoot = Join-Path $targetDir "release" + $outDir = Join-Path $releaseRoot $verName + $binDir = Join-Path $outDir "bin" + $libDir = Join-Path $outDir "lib" + + # Clean old directory + if (Test-Path $outDir) { + Write-Host "→ Cleaning previous output directory..." + Remove-Item $outDir -Recurse -Force + } + + New-Item -ItemType Directory -Force -Path $binDir | Out-Null + Copy-Item -Path $exePath -Destination (Join-Path $binDir "Snow.exe") -Force + Write-Host ">>> Collected Snow.exe" + + # Optional lib + $projectLib = Join-Path $projectRoot "lib" + if (Test-Path $projectLib) { + New-Item -ItemType Directory -Force -Path $libDir | Out-Null + Copy-Item -Path (Join-Path $projectLib "*") -Destination $libDir -Recurse -Force + Write-Host ">>> Copied lib directory" + } else { + Write-Host ">>> lib directory not found, skipping." -ForegroundColor Yellow + } + + # ===== Step 4: Create zip ===== + Write-Host "Step 4: Create release zip..." + New-Item -ItemType Directory -Force -Path $releaseRoot | Out-Null + $zipPath = Join-Path $releaseRoot ("{0}.zip" -f $verName) + if (Test-Path $zipPath) { + Write-Host "→ Removing existing zip: $zipPath" + Remove-Item $zipPath -Force + } + + try { + Compress-Archive -Path $outDir -DestinationPath $zipPath -Force + } catch { + Write-Error "Failed to create zip: $($_.Exception.Message)" + exit 1 + } + + Write-Host ">>> Package ready!" -ForegroundColor Green + Write-Host "Version : $snowVersion" + Write-Host "Output Dir : $outDir" + Write-Host "Zip File : $zipPath" +} +finally { + Pop-Location +} diff --git a/build/tools/dotenv.ps1 b/build/tools/dotenv.ps1 new file mode 100644 index 0000000..f3c1eb1 --- /dev/null +++ b/build/tools/dotenv.ps1 @@ -0,0 +1,53 @@ +# tools/dotenv.ps1 +# Unified .env reader function: +# - Supports `KEY=VAL` and `export KEY=VAL` +# - Skips blank lines and comments +# - Handles quoted values (single or double quotes) +# - Allows inline comments at the end of a line (space + #) +# - If the same KEY is defined multiple times, the last one takes precedence + +Set-StrictMode -Version Latest + +function Read-DotEnvValue { + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)][string]$FilePath, + [Parameter(Mandatory=$true)][string]$Key + ) + + if (-not (Test-Path -LiteralPath $FilePath)) { return $null } + + # Match the target key (escaped), allowing optional "export" prefix + $pattern = '^(?:\s*export\s+)?(?' + [regex]::Escape($Key) + ')\s*=\s*(?.*)$' + $value = $null + + # Read line by line for large file compatibility + Get-Content -LiteralPath $FilePath | ForEach-Object { + $line = $_ + + # Skip blank lines and full-line comments + if ($line -match '^\s*$') { return } + if ($line -match '^\s*#') { return } + + if ($line -match $pattern) { + $v = $matches['v'] + + # Remove surrounding quotes if present + $trimmed = $v.Trim() + if ($trimmed -match '^\s*"(.*)"\s*$') { + $v = $matches[1] + } elseif ($trimmed -match "^\s*'(.*)'\s*$") { + $v = $matches[1] + } else { + # Strip inline comments (space + # …), ignoring escaped \# + if ($v -match '^(.*?)(?