Files
ForgeFlow/Publish-Missing-Binary-Release.ps1
T
NuklearRabbit d47c7b5e41
ForgeFlow quality gate / secret-scan (push) Failing after 32s
ForgeFlow quality gate / quality (push) Failing after 0s
feat: add safe Gitea sync and signed updates
2026-08-27 00:38:58 +02:00

117 lines
4.3 KiB
PowerShell

param(
[string]$Remote = "git@gitea.itworx.tech:Jens/ForgeFlow.git",
[string]$Branch = "main",
[string]$ExpectedVersion = "0.9.1",
[string]$UserDataPath = ""
)
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
$temp = Join-Path ([IO.Path]::GetTempPath()) ("forgeflow-binary-release-" + [guid]::NewGuid().ToString("N"))
$clone = Join-Path $temp "ForgeFlow"
function Invoke-CheckedCommand {
param(
[Parameter(Mandatory = $true)][string]$Title,
[Parameter(Mandatory = $true)][scriptblock]$Action
)
Write-Host "`n$Title" -ForegroundColor Cyan
& $Action
if ($LASTEXITCODE -ne 0) {
throw "$Title failed with exit code $LASTEXITCODE."
}
}
try {
foreach ($command in @("git", "node", "npm")) {
if (-not (Get-Command $command -ErrorAction SilentlyContinue)) {
throw "Required command '$command' was not found on PATH."
}
}
New-Item -ItemType Directory -Force -Path $temp | Out-Null
Invoke-CheckedCommand "Cloning the exact published ForgeFlow source..." {
& git clone --branch $Branch --single-branch $Remote $clone
}
$manifestPath = Join-Path $clone "package.json"
if (-not (Test-Path -LiteralPath $manifestPath)) {
throw "The cloned repository does not contain package.json."
}
$manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json
if ($manifest.name -ne "forgeflow") {
throw "The cloned repository is not ForgeFlow."
}
$version = [string]$manifest.version
if ($ExpectedVersion -and $version -ne $ExpectedVersion) {
throw "Gitea branch '$Branch' contains ForgeFlow $version, not the expected $ExpectedVersion."
}
$localCommit = (& git -C $clone rev-parse HEAD).Trim()
$remoteLines = @(& git -C $clone ls-remote origin "refs/heads/$Branch")
if ($LASTEXITCODE -ne 0 -or $remoteLines.Count -lt 1) {
throw "Could not verify origin/$Branch."
}
$remoteCommit = ($remoteLines[0] -split "`t")[0].Trim()
if ($localCommit -ne $remoteCommit) {
throw "The temporary checkout is not the current origin/$Branch commit."
}
Push-Location $clone
try {
Invoke-CheckedCommand "Installing exact dependencies..." {
& cmd.exe /d /s /c "npm ci --no-audit --no-fund"
}
Invoke-CheckedCommand "Running the complete ForgeFlow quality gate..." {
& cmd.exe /d /s /c "npm run check"
}
Invoke-CheckedCommand "Building installer and portable Windows assets..." {
& cmd.exe /d /s /c "npm run dist:win"
}
$expectedAssets = @(
"ForgeFlow-Setup-$version-win-x64.exe",
"ForgeFlow-Setup-$version-win-x64.exe.sha256",
"ForgeFlow-Portable-$version-win-x64.exe",
"ForgeFlow-Portable-$version-win-x64.exe.sha256",
"ForgeFlow-$version-provenance.json",
"ForgeFlow-$version-sbom.cdx.json",
"ForgeFlow-$version-release-manifest.json",
"ForgeFlow-$version-release-manifest.json.sig"
)
foreach ($assetName in $expectedAssets) {
$assetPath = Join-Path $clone "dist\$assetName"
if (-not (Test-Path -LiteralPath $assetPath)) {
throw "The build did not produce $assetName."
}
}
$resolvedUserData = if ($UserDataPath) { $UserDataPath } else { Join-Path $env:APPDATA "forgeflow" }
$configPath = Join-Path $resolvedUserData "forgeflow-config.json"
if (-not (Test-Path -LiteralPath $configPath)) {
throw "ForgeFlow configuration was not found at $configPath. Open ForgeFlow and sign in to Gitea once, then run this script again."
}
$previousUserData = $env:FORGEFLOW_USER_DATA
$previousBranch = $env:FORGEFLOW_RELEASE_BRANCH
try {
$env:FORGEFLOW_USER_DATA = $resolvedUserData
$env:FORGEFLOW_RELEASE_BRANCH = $Branch
Invoke-CheckedCommand "Creating the Gitea release and uploading all four assets..." {
& cmd.exe /d /s /c "npm run release:binary"
}
} finally {
$env:FORGEFLOW_USER_DATA = $previousUserData
$env:FORGEFLOW_RELEASE_BRANCH = $previousBranch
}
} finally {
Pop-Location
}
Write-Host "`nForgeFlow $version now has a published binary release for commit $($localCommit.Substring(0,7))." -ForegroundColor Green
Write-Host "Return to ForgeFlow $ExpectedVersion's predecessor and choose Check now -> Download update -> Apply & restart." -ForegroundColor Green
}
finally {
Remove-Item -LiteralPath $temp -Recurse -Force -ErrorAction SilentlyContinue
}