netx/packaging/publish_forgejo_release.ps1
oliver 372138d9a1
Some checks are pending
Release Windows / build (push) Waiting to run
Make Forgejo asset upload resilient to schannel revocation-offline errors.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-08 21:11:54 +08:00

129 lines
4.1 KiB
PowerShell

param(
[string]$Version = "",
[string]$ForgejoBase = "https://git.avelo.top",
[string]$Owner = "hansjone",
[string]$Repo = "netx",
[string]$Token = "",
[string]$ReleaseDir = ""
)
# Publish Windows Setup.exe to Forgejo/Gitea (mirror sync does NOT copy GitHub Release files).
# Requires a Forgejo token with repo write (Settings → Applications → Generate New Token).
# Default: https://git.avelo.top (public domain). LAN IP only when explicitly reachable.
#
# Example:
# $env:NETX_FORGEJO_TOKEN = "..." # or User env NETX_FORGEJO_TOKEN
# .\packaging\publish_forgejo_release.ps1 -Version 0.4.11
#
# Optional LAN (when 10.0.0.131 is reachable):
# .\packaging\publish_forgejo_release.ps1 -Version 0.4.11 -ForgejoBase "http://10.0.0.131:3000"
$ErrorActionPreference = "Stop"
. "$PSScriptRoot\_common.ps1"
$repoRoot = Get-NetxRepoRoot
if (-not $Version) {
$Version = Get-NetxVersion -ProgramRoot $repoRoot
}
$tag = "v$Version"
$relDir = if ($ReleaseDir) { $ReleaseDir } else { Join-Path $PSScriptRoot "release" }
$setup = Join-Path $relDir "NetX-Setup-$Version.exe"
if (-not $Token) {
$Token = $env:NETX_FORGEJO_TOKEN
if (-not $Token) { $Token = $env:FORGEJO_TOKEN }
}
if (-not $Token) {
throw "forgejo_token_required: set NETX_FORGEJO_TOKEN or pass -Token"
}
if (-not (Test-Path $setup)) {
throw "missing_setup: $setup (run build_release.ps1 + ISCC first)"
}
$apiBase = "$ForgejoBase/api/v1/repos/$Owner/$Repo"
$headers = @{
"Authorization" = "token $Token"
"Accept" = "application/json"
}
function Invoke-ForgejoJson {
param(
[string]$Method,
[string]$Url,
[object]$Body = $null
)
$params = @{
Method = $Method
Uri = $Url
Headers = $headers
ContentType = "application/json"
}
if ($null -ne $Body) {
$params["Body"] = ($Body | ConvertTo-Json -Depth 5)
}
return Invoke-RestMethod @params
}
Write-Host "==> Forgejo publish $tag -> $ForgejoBase/$Owner/$Repo"
# Ensure git tag exists on Forgejo (mirror usually already has it).
try {
$null = Invoke-ForgejoJson -Method GET -Url "$apiBase/git/refs/tags/$tag"
Write-Host " tag $tag present on Forgejo"
} catch {
Write-Host "[WARN] tag $tag not found on Forgejo yet — run mirror-sync or push tag first" -ForegroundColor Yellow
}
$existing = $null
try {
$existing = Invoke-ForgejoJson -Method GET -Url "$apiBase/releases/tags/$tag"
} catch {
$existing = $null
}
$notes = @"
NetX $Version Windows installer (published from GitHub release build).
- NetX-Setup-$Version.exe
"@
if ($existing -and $existing.id) {
Write-Host "==> Release $tag already exists (id=$($existing.id)); deleting old release to re-upload assets"
Invoke-ForgejoJson -Method DELETE -Url "$apiBase/releases/$($existing.id)" | Out-Null
}
Write-Host "==> Creating release $tag"
$rel = Invoke-ForgejoJson -Method POST -Url "$apiBase/releases" -Body @{
tag_name = $tag
target = "main"
name = "NetX $Version"
body = $notes
draft = $false
prerelease = $false
}
$relId = $rel.id
if (-not $relId) { throw "forgejo_create_release_failed" }
function Upload-ForgejoAsset {
param([string]$Path)
if (-not (Test-Path $Path)) { return }
$name = Split-Path -Leaf $Path
Write-Host "==> Uploading $name ..."
$url = "$apiBase/releases/$relId/assets"
$curl = Get-Command curl.exe -ErrorAction SilentlyContinue
if (-not $curl) { throw "curl.exe required for asset upload" }
# --ssl-no-revoke: schannel CRYPT_E_REVOCATION_OFFLINE often fails via proxy/offline CA.
& $curl.Source -f -sS --ssl-no-revoke -X POST `
-H "Authorization: token $Token" `
-F "attachment=@$Path" `
$url
if ($LASTEXITCODE -ne 0) { throw "upload_failed: $name" }
Write-Host " OK $name" -ForegroundColor Green
}
Upload-ForgejoAsset -Path $setup
$releaseUrl = "$ForgejoBase/$Owner/$Repo/releases/tag/$tag"
Write-Host ""
Write-Host "==> Forgejo release ready: $releaseUrl" -ForegroundColor Green
Write-Host " Update API: $ForgejoBase/api/v1/repos/$Owner/$Repo/releases/latest"