Refactor proxy routing and installer flows
This commit is contained in:
606
scripts/prepare-release.ps1
Normal file
606
scripts/prepare-release.ps1
Normal file
@@ -0,0 +1,606 @@
|
||||
param(
|
||||
[string]$Version = "",
|
||||
[ValidateSet("", "patch", "minor", "major")]
|
||||
[string]$Bump = "",
|
||||
[string]$OutputRoot = "releases",
|
||||
[switch]$SkipTests,
|
||||
[switch]$SkipBuild,
|
||||
[switch]$PlanOnly,
|
||||
[switch]$Force
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$RepoRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot ".."))
|
||||
$PackageJsonPath = Join-Path $RepoRoot "package.json"
|
||||
$PackageLockPath = Join-Path $RepoRoot "package-lock.json"
|
||||
$TauriConfigPath = Join-Path $RepoRoot "src-tauri\tauri.conf.json"
|
||||
$CargoTomlPath = Join-Path $RepoRoot "src-tauri\Cargo.toml"
|
||||
$BundleRoot = Join-Path $RepoRoot "src-tauri\target\release\bundle"
|
||||
|
||||
function Write-Utf8NoBomFile {
|
||||
param(
|
||||
[string]$Path,
|
||||
[string]$Value
|
||||
)
|
||||
|
||||
$encoding = New-Object System.Text.UTF8Encoding $false
|
||||
[System.IO.File]::WriteAllText($Path, $Value, $encoding)
|
||||
}
|
||||
|
||||
function Read-JsonFile {
|
||||
param([string]$Path)
|
||||
Get-Content -Raw -LiteralPath $Path | ConvertFrom-Json
|
||||
}
|
||||
|
||||
function Write-JsonFile {
|
||||
param(
|
||||
[string]$Path,
|
||||
[object]$Value
|
||||
)
|
||||
|
||||
$json = $Value | ConvertTo-Json -Depth 100
|
||||
Write-Utf8NoBomFile -Path $Path -Value ($json + [Environment]::NewLine)
|
||||
}
|
||||
|
||||
function Replace-RegexGroup {
|
||||
param(
|
||||
[string]$Content,
|
||||
[string]$Pattern,
|
||||
[string]$GroupName,
|
||||
[string]$Value,
|
||||
[string]$Label
|
||||
)
|
||||
|
||||
$match = [regex]::Match($Content, $Pattern, [System.Text.RegularExpressions.RegexOptions]::Singleline)
|
||||
if (-not $match.Success) {
|
||||
throw "Cannot find $Label."
|
||||
}
|
||||
|
||||
$group = $match.Groups[$GroupName]
|
||||
if (-not $group.Success) {
|
||||
throw "Cannot find $Label value."
|
||||
}
|
||||
|
||||
$Content.Remove($group.Index, $group.Length).Insert($group.Index, $Value)
|
||||
}
|
||||
|
||||
function Get-FirstJsonVersion {
|
||||
param(
|
||||
[string]$Path,
|
||||
[string]$Label
|
||||
)
|
||||
|
||||
$content = Get-Content -Raw -LiteralPath $Path
|
||||
$match = [regex]::Match($content, '"version"\s*:\s*"(?<value>[^"]+)"')
|
||||
if (-not $match.Success) {
|
||||
throw "Cannot find version in $Label."
|
||||
}
|
||||
$match.Groups["value"].Value
|
||||
}
|
||||
|
||||
function Set-FirstJsonVersion {
|
||||
param(
|
||||
[string]$Path,
|
||||
[string]$TargetVersion,
|
||||
[string]$Label
|
||||
)
|
||||
|
||||
$content = Get-Content -Raw -LiteralPath $Path
|
||||
$updated = Replace-RegexGroup `
|
||||
-Content $content `
|
||||
-Pattern '"version"\s*:\s*"(?<value>[^"]+)"' `
|
||||
-GroupName "value" `
|
||||
-Value $TargetVersion `
|
||||
-Label "version in $Label"
|
||||
Write-Utf8NoBomFile -Path $Path -Value $updated
|
||||
}
|
||||
|
||||
function Get-PackageLockVersions {
|
||||
$content = Get-Content -Raw -LiteralPath $PackageLockPath
|
||||
$topMatch = [regex]::Match(
|
||||
$content,
|
||||
'^\s*\{\s*"name"\s*:\s*"[^"]+"\s*,\s*"version"\s*:\s*"(?<value>[^"]+)"',
|
||||
[System.Text.RegularExpressions.RegexOptions]::Singleline
|
||||
)
|
||||
if (-not $topMatch.Success) {
|
||||
throw "Cannot find top-level version in package-lock.json."
|
||||
}
|
||||
|
||||
$rootMatch = [regex]::Match(
|
||||
$content,
|
||||
'"packages"\s*:\s*\{\s*""\s*:\s*\{\s*"name"\s*:\s*"[^"]+"\s*,\s*"version"\s*:\s*"(?<value>[^"]+)"',
|
||||
[System.Text.RegularExpressions.RegexOptions]::Singleline
|
||||
)
|
||||
if (-not $rootMatch.Success) {
|
||||
throw "Cannot find root package version in package-lock.json."
|
||||
}
|
||||
|
||||
[ordered]@{
|
||||
packageLock = $topMatch.Groups["value"].Value
|
||||
packageLockRoot = $rootMatch.Groups["value"].Value
|
||||
}
|
||||
}
|
||||
|
||||
function Set-PackageLockVersions {
|
||||
param([string]$TargetVersion)
|
||||
|
||||
$content = Get-Content -Raw -LiteralPath $PackageLockPath
|
||||
$updated = Replace-RegexGroup `
|
||||
-Content $content `
|
||||
-Pattern '^\s*\{\s*"name"\s*:\s*"[^"]+"\s*,\s*"version"\s*:\s*"(?<value>[^"]+)"' `
|
||||
-GroupName "value" `
|
||||
-Value $TargetVersion `
|
||||
-Label "top-level version in package-lock.json"
|
||||
$updated = Replace-RegexGroup `
|
||||
-Content $updated `
|
||||
-Pattern '"packages"\s*:\s*\{\s*""\s*:\s*\{\s*"name"\s*:\s*"[^"]+"\s*,\s*"version"\s*:\s*"(?<value>[^"]+)"' `
|
||||
-GroupName "value" `
|
||||
-Value $TargetVersion `
|
||||
-Label "root package version in package-lock.json"
|
||||
Write-Utf8NoBomFile -Path $PackageLockPath -Value $updated
|
||||
}
|
||||
|
||||
function Assert-Semver {
|
||||
param([string]$Value)
|
||||
if ($Value -notmatch "^\d+\.\d+\.\d+$") {
|
||||
throw "Version '$Value' is not supported. Use numeric SemVer like 0.1.0."
|
||||
}
|
||||
}
|
||||
|
||||
function ConvertTo-VersionParts {
|
||||
param([string]$Value)
|
||||
Assert-Semver -Value $Value
|
||||
$parts = $Value.Split(".")
|
||||
[ordered]@{
|
||||
major = [int]$parts[0]
|
||||
minor = [int]$parts[1]
|
||||
patch = [int]$parts[2]
|
||||
}
|
||||
}
|
||||
|
||||
function Compare-Semver {
|
||||
param(
|
||||
[string]$Left,
|
||||
[string]$Right
|
||||
)
|
||||
|
||||
$leftParts = ConvertTo-VersionParts -Value $Left
|
||||
$rightParts = ConvertTo-VersionParts -Value $Right
|
||||
foreach ($part in @("major", "minor", "patch")) {
|
||||
if ($leftParts[$part] -gt $rightParts[$part]) { return 1 }
|
||||
if ($leftParts[$part] -lt $rightParts[$part]) { return -1 }
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function Get-NextVersion {
|
||||
param(
|
||||
[string]$Current,
|
||||
[string]$Kind
|
||||
)
|
||||
|
||||
$parts = ConvertTo-VersionParts -Value $Current
|
||||
switch ($Kind) {
|
||||
"major" { return "$($parts.major + 1).0.0" }
|
||||
"minor" { return "$($parts.major).$($parts.minor + 1).0" }
|
||||
"patch" { return "$($parts.major).$($parts.minor).$($parts.patch + 1)" }
|
||||
default { throw "Unknown bump kind '$Kind'." }
|
||||
}
|
||||
}
|
||||
|
||||
function Get-CargoPackageVersion {
|
||||
$content = Get-Content -Raw -LiteralPath $CargoTomlPath
|
||||
$packageMatch = [regex]::Match($content, "(?ms)^\[package\]\s*(.*?)(?=^\[|\z)")
|
||||
if (-not $packageMatch.Success) {
|
||||
throw "Cannot find [package] block in $CargoTomlPath."
|
||||
}
|
||||
|
||||
$versionMatch = [regex]::Match($packageMatch.Value, '(?m)^version\s*=\s*"([^"]+)"\s*$')
|
||||
if (-not $versionMatch.Success) {
|
||||
throw "Cannot find package version in $CargoTomlPath."
|
||||
}
|
||||
|
||||
$versionMatch.Groups[1].Value
|
||||
}
|
||||
|
||||
function Get-VersionState {
|
||||
$packageLock = Get-PackageLockVersions
|
||||
|
||||
[ordered]@{
|
||||
packageJson = [string](Get-FirstJsonVersion -Path $PackageJsonPath -Label "package.json")
|
||||
packageLock = [string]$packageLock.packageLock
|
||||
packageLockRoot = [string]$packageLock.packageLockRoot
|
||||
tauriConfig = [string](Get-FirstJsonVersion -Path $TauriConfigPath -Label "tauri.conf.json")
|
||||
cargoToml = [string](Get-CargoPackageVersion)
|
||||
}
|
||||
}
|
||||
|
||||
function Get-CurrentVersion {
|
||||
$state = Get-VersionState
|
||||
$versions = @(@(
|
||||
$state.packageJson,
|
||||
$state.packageLock,
|
||||
$state.packageLockRoot,
|
||||
$state.tauriConfig,
|
||||
$state.cargoToml
|
||||
) | Select-Object -Unique)
|
||||
|
||||
if ($versions.Count -ne 1) {
|
||||
$details = $state.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }
|
||||
throw "Version mismatch: $($details -join ', ')."
|
||||
}
|
||||
|
||||
Assert-Semver -Value $versions[0]
|
||||
$versions[0]
|
||||
}
|
||||
|
||||
function Resolve-TargetVersion {
|
||||
param([string]$Current)
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($Version)) {
|
||||
Assert-Semver -Value $Version
|
||||
return $Version
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($Bump)) {
|
||||
return Get-NextVersion -Current $Current -Kind $Bump
|
||||
}
|
||||
|
||||
if ($PlanOnly -or -not [Environment]::UserInteractive) {
|
||||
return Get-NextVersion -Current $Current -Kind "patch"
|
||||
}
|
||||
|
||||
$patch = Get-NextVersion -Current $Current -Kind "patch"
|
||||
$minor = Get-NextVersion -Current $Current -Kind "minor"
|
||||
$major = Get-NextVersion -Current $Current -Kind "major"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Current version: $Current"
|
||||
Write-Host "Choose release version:"
|
||||
Write-Host " 1) patch $patch"
|
||||
Write-Host " 2) minor $minor"
|
||||
Write-Host " 3) major $major"
|
||||
Write-Host " 4) custom"
|
||||
Write-Host " 5) keep current $Current"
|
||||
$choice = Read-Host "Selection [1]"
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($choice)) { $choice = "1" }
|
||||
|
||||
switch ($choice.Trim()) {
|
||||
"1" { return $patch }
|
||||
"2" { return $minor }
|
||||
"3" { return $major }
|
||||
"4" {
|
||||
$custom = Read-Host "Enter version"
|
||||
Assert-Semver -Value $custom
|
||||
return $custom
|
||||
}
|
||||
"5" { return $Current }
|
||||
default { throw "Unknown selection '$choice'." }
|
||||
}
|
||||
}
|
||||
|
||||
function Set-CargoPackageVersion {
|
||||
param([string]$TargetVersion)
|
||||
|
||||
$content = Get-Content -Raw -LiteralPath $CargoTomlPath
|
||||
$packageMatch = [regex]::Match($content, "(?ms)^\[package\]\s*(.*?)(?=^\[|\z)")
|
||||
if (-not $packageMatch.Success) {
|
||||
throw "Cannot find [package] block in $CargoTomlPath."
|
||||
}
|
||||
|
||||
$packageBlock = $packageMatch.Value
|
||||
$versionMatch = [regex]::Match($packageBlock, '(?m)^version\s*=\s*"(?<value>[^"]+)"\s*$')
|
||||
if (-not $versionMatch.Success) {
|
||||
throw "Cannot update package version in $CargoTomlPath."
|
||||
}
|
||||
|
||||
if ($versionMatch.Groups["value"].Value -eq $TargetVersion) {
|
||||
return
|
||||
}
|
||||
|
||||
$valueGroup = $versionMatch.Groups["value"]
|
||||
$updatedBlock = $packageBlock.Remove($valueGroup.Index, $valueGroup.Length).Insert($valueGroup.Index, $TargetVersion)
|
||||
$updatedContent = $content.Remove($packageMatch.Index, $packageMatch.Length).Insert($packageMatch.Index, $updatedBlock)
|
||||
Write-Utf8NoBomFile -Path $CargoTomlPath -Value $updatedContent
|
||||
}
|
||||
|
||||
function Set-ManifestVersions {
|
||||
param([string]$TargetVersion)
|
||||
|
||||
Set-FirstJsonVersion -Path $PackageJsonPath -TargetVersion $TargetVersion -Label "package.json"
|
||||
Set-PackageLockVersions -TargetVersion $TargetVersion
|
||||
Set-FirstJsonVersion -Path $TauriConfigPath -TargetVersion $TargetVersion -Label "tauri.conf.json"
|
||||
Set-CargoPackageVersion -TargetVersion $TargetVersion
|
||||
}
|
||||
|
||||
function Get-FullPath {
|
||||
param([string]$Path)
|
||||
[System.IO.Path]::GetFullPath($Path)
|
||||
}
|
||||
|
||||
function Test-IsSubPath {
|
||||
param(
|
||||
[string]$Parent,
|
||||
[string]$Child
|
||||
)
|
||||
|
||||
$parentFull = (Get-FullPath -Path $Parent).TrimEnd("\", "/") + [System.IO.Path]::DirectorySeparatorChar
|
||||
$childFull = (Get-FullPath -Path $Child).TrimEnd("\", "/") + [System.IO.Path]::DirectorySeparatorChar
|
||||
$childFull.StartsWith($parentFull, [System.StringComparison]::OrdinalIgnoreCase)
|
||||
}
|
||||
|
||||
function Get-RelativePath {
|
||||
param(
|
||||
[string]$BasePath,
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
$baseUri = [Uri]((Get-FullPath -Path $BasePath).TrimEnd("\", "/") + [System.IO.Path]::DirectorySeparatorChar)
|
||||
$pathUri = [Uri](Get-FullPath -Path $Path)
|
||||
[Uri]::UnescapeDataString($baseUri.MakeRelativeUri($pathUri).ToString()).Replace("/", "\")
|
||||
}
|
||||
|
||||
function New-ReleaseDirectory {
|
||||
param([string]$TargetVersion)
|
||||
|
||||
if ([System.IO.Path]::IsPathRooted($OutputRoot)) {
|
||||
$root = Get-FullPath -Path $OutputRoot
|
||||
} else {
|
||||
$root = Get-FullPath -Path (Join-Path $RepoRoot $OutputRoot)
|
||||
}
|
||||
|
||||
$releaseDir = Join-Path $root "proxywarden-v$TargetVersion"
|
||||
|
||||
if ((Test-Path -LiteralPath $releaseDir) -and $Force) {
|
||||
if (-not (Test-IsSubPath -Parent $root -Child $releaseDir)) {
|
||||
throw "Refusing to remove release directory outside OutputRoot: $releaseDir"
|
||||
}
|
||||
Remove-Item -LiteralPath $releaseDir -Recurse -Force
|
||||
} elseif (Test-Path -LiteralPath $releaseDir) {
|
||||
throw "Release directory already exists: $releaseDir. Use -Force to replace it."
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path (Join-Path $releaseDir "artifacts") -Force | Out-Null
|
||||
$releaseDir
|
||||
}
|
||||
|
||||
function Invoke-NativeCommand {
|
||||
param(
|
||||
[string]$Name,
|
||||
[string]$FilePath,
|
||||
[string[]]$Arguments,
|
||||
[string]$WorkingDirectory = $RepoRoot
|
||||
)
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "==> $Name"
|
||||
Push-Location $WorkingDirectory
|
||||
try {
|
||||
& $FilePath @Arguments
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "$Name failed with exit code $LASTEXITCODE."
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-ReleaseBuild {
|
||||
if ($SkipBuild) {
|
||||
Write-Host ""
|
||||
Write-Host "Skipping build because -SkipBuild was provided."
|
||||
return
|
||||
}
|
||||
|
||||
Invoke-NativeCommand -Name "Frontend build" -FilePath "npm" -Arguments @("run", "build")
|
||||
|
||||
if (-not $SkipTests) {
|
||||
Invoke-NativeCommand -Name "Rust tests" -FilePath "cargo" -Arguments @("test") -WorkingDirectory (Join-Path $RepoRoot "src-tauri")
|
||||
} else {
|
||||
Write-Host ""
|
||||
Write-Host "Skipping Rust tests because -SkipTests was provided."
|
||||
}
|
||||
|
||||
Invoke-NativeCommand -Name "Tauri release build" -FilePath "npm" -Arguments @("run", "tauri", "--", "build")
|
||||
}
|
||||
|
||||
function Copy-ReleaseArtifacts {
|
||||
param([string]$ReleaseDir)
|
||||
|
||||
if ($SkipBuild) {
|
||||
return @()
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $BundleRoot)) {
|
||||
throw "Tauri bundle output was not found: $BundleRoot"
|
||||
}
|
||||
|
||||
$artifactDir = Join-Path $ReleaseDir "artifacts"
|
||||
$files = Get-ChildItem -LiteralPath $BundleRoot -Recurse -File |
|
||||
Where-Object { $_.Extension -in @(".exe", ".msi", ".zip", ".sig") }
|
||||
|
||||
if ($files.Count -eq 0) {
|
||||
throw "No release artifacts were found under $BundleRoot."
|
||||
}
|
||||
|
||||
$copied = @()
|
||||
foreach ($file in $files) {
|
||||
$relative = Get-RelativePath -BasePath $BundleRoot -Path $file.FullName
|
||||
$destination = Join-Path $artifactDir $relative
|
||||
New-Item -ItemType Directory -Path (Split-Path -Parent $destination) -Force | Out-Null
|
||||
Copy-Item -LiteralPath $file.FullName -Destination $destination -Force
|
||||
$copied += Get-Item -LiteralPath $destination
|
||||
}
|
||||
|
||||
$copied
|
||||
}
|
||||
|
||||
function Write-Checksums {
|
||||
param(
|
||||
[string]$ReleaseDir,
|
||||
[object[]]$Files
|
||||
)
|
||||
|
||||
if ($Files.Count -eq 0) { return $null }
|
||||
|
||||
$artifactDir = Join-Path $ReleaseDir "artifacts"
|
||||
$lines = foreach ($file in $Files) {
|
||||
$hash = Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256
|
||||
$relative = Get-RelativePath -BasePath $artifactDir -Path $file.FullName
|
||||
"$($hash.Hash.ToLowerInvariant()) $relative"
|
||||
}
|
||||
|
||||
$checksumPath = Join-Path $ReleaseDir "SHA256SUMS.txt"
|
||||
Write-Utf8NoBomFile -Path $checksumPath -Value (($lines -join [Environment]::NewLine) + [Environment]::NewLine)
|
||||
$checksumPath
|
||||
}
|
||||
|
||||
function Get-GitValue {
|
||||
param([string[]]$Arguments)
|
||||
|
||||
try {
|
||||
$value = & git @Arguments 2>$null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
return ($value -join [Environment]::NewLine).Trim()
|
||||
}
|
||||
} catch {}
|
||||
return ""
|
||||
}
|
||||
|
||||
function Write-ReleaseMetadata {
|
||||
param(
|
||||
[string]$ReleaseDir,
|
||||
[string]$TargetVersion,
|
||||
[object[]]$Artifacts
|
||||
)
|
||||
|
||||
$artifactDir = Join-Path $ReleaseDir "artifacts"
|
||||
$artifactItems = foreach ($artifact in $Artifacts) {
|
||||
[ordered]@{
|
||||
path = Get-RelativePath -BasePath $ReleaseDir -Path $artifact.FullName
|
||||
sizeBytes = $artifact.Length
|
||||
sha256 = (Get-FileHash -LiteralPath $artifact.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
}
|
||||
}
|
||||
|
||||
$manifest = [ordered]@{
|
||||
product = "ProxyWarden"
|
||||
version = $TargetVersion
|
||||
builtAt = (Get-Date).ToString("o")
|
||||
source = "local"
|
||||
gitCommit = Get-GitValue -Arguments @("rev-parse", "HEAD")
|
||||
gitStatus = Get-GitValue -Arguments @("status", "--short")
|
||||
artifacts = @($artifactItems)
|
||||
}
|
||||
|
||||
Write-JsonFile -Path (Join-Path $ReleaseDir "release-manifest.json") -Value $manifest
|
||||
|
||||
$artifactList = if ($Artifacts.Count -gt 0) {
|
||||
($Artifacts | ForEach-Object {
|
||||
"- " + (Get-RelativePath -BasePath $artifactDir -Path $_.FullName)
|
||||
}) -join [Environment]::NewLine
|
||||
} else {
|
||||
"- Build was skipped; no artifacts were copied."
|
||||
}
|
||||
|
||||
$notes = @"
|
||||
# ProxyWarden v$TargetVersion
|
||||
|
||||
## Artifacts
|
||||
|
||||
$artifactList
|
||||
|
||||
## Checksums
|
||||
|
||||
See `SHA256SUMS.txt`.
|
||||
|
||||
## Release boundary
|
||||
|
||||
This release contains the ProxyWarden Control App only. ProxiFyre and Local sing-box remain explicit user-managed components.
|
||||
|
||||
"@
|
||||
|
||||
Write-Utf8NoBomFile -Path (Join-Path $ReleaseDir "release-notes.md") -Value $notes
|
||||
}
|
||||
|
||||
function New-PlanResult {
|
||||
param(
|
||||
[string]$Current,
|
||||
[string]$Target
|
||||
)
|
||||
|
||||
$outputRootFull = if ([System.IO.Path]::IsPathRooted($OutputRoot)) {
|
||||
Get-FullPath -Path $OutputRoot
|
||||
} else {
|
||||
Get-FullPath -Path (Join-Path $RepoRoot $OutputRoot)
|
||||
}
|
||||
|
||||
[ordered]@{
|
||||
success = $true
|
||||
action = "prepare-release.plan"
|
||||
changed = $false
|
||||
message = "Release plan is ready."
|
||||
details = [ordered]@{
|
||||
currentVersion = $Current
|
||||
targetVersion = $Target
|
||||
releaseDirectory = (Join-Path $outputRootFull "proxywarden-v$Target")
|
||||
skipTests = [bool]$SkipTests
|
||||
skipBuild = [bool]$SkipBuild
|
||||
manifests = @(
|
||||
$PackageJsonPath,
|
||||
$PackageLockPath,
|
||||
$TauriConfigPath,
|
||||
$CargoTomlPath
|
||||
)
|
||||
commands = @(
|
||||
"npm run build",
|
||||
"cd src-tauri; cargo test",
|
||||
"npm run tauri -- build"
|
||||
)
|
||||
}
|
||||
} | ConvertTo-Json -Depth 8
|
||||
}
|
||||
|
||||
try {
|
||||
Push-Location $RepoRoot
|
||||
|
||||
$currentVersion = Get-CurrentVersion
|
||||
$targetVersion = Resolve-TargetVersion -Current $currentVersion
|
||||
Assert-Semver -Value $targetVersion
|
||||
|
||||
if ((Compare-Semver -Left $targetVersion -Right $currentVersion) -lt 0) {
|
||||
throw "Target version $targetVersion is lower than current version $currentVersion."
|
||||
}
|
||||
|
||||
if ($PlanOnly) {
|
||||
New-PlanResult -Current $currentVersion -Target $targetVersion
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Preparing ProxyWarden release $targetVersion..."
|
||||
Write-Host "Repository: $RepoRoot"
|
||||
|
||||
Set-ManifestVersions -TargetVersion $targetVersion
|
||||
$afterUpdateVersion = Get-CurrentVersion
|
||||
if ($afterUpdateVersion -ne $targetVersion) {
|
||||
throw "Version update failed. Current version is $afterUpdateVersion."
|
||||
}
|
||||
|
||||
Invoke-ReleaseBuild
|
||||
|
||||
$releaseDir = New-ReleaseDirectory -TargetVersion $targetVersion
|
||||
$artifacts = @(Copy-ReleaseArtifacts -ReleaseDir $releaseDir)
|
||||
Write-Checksums -ReleaseDir $releaseDir -Files $artifacts | Out-Null
|
||||
Write-ReleaseMetadata -ReleaseDir $releaseDir -TargetVersion $targetVersion -Artifacts $artifacts
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Release folder is ready:"
|
||||
Write-Host $releaseDir
|
||||
Write-Host ""
|
||||
Write-Host "Upload the files from the release folder to GitHub release v$targetVersion."
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
Reference in New Issue
Block a user