ci / web (push) Successful in 51s
ci / docs-site (push) Successful in 1m5s
apple / swift (push) Successful in 1m25s
decky / build-publish (push) Successful in 21s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 9s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 10s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 9s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 10s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 10s
ci / bench (push) Successful in 6m55s
apple / screenshots (push) Successful in 6m47s
deb / build-publish (push) Successful in 11m23s
android / android (push) Successful in 12m36s
arch / build-publish (push) Successful in 12m46s
docker / deploy-docs (push) Successful in 23s
deb / build-publish-host (push) Successful in 12m32s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 16m9s
ci / rust (push) Successful in 26m29s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 20m30s
Release notes now live in the repo at docs/releases/vX.Y.Z.md, authored during the version bump (before the tag). ensure_release (gitea-release.sh + .ps1 twin) seeds the Gitea release body from that file in the create POST, so the release is born WITH its notes instead of being created empty and PATCHed afterward. canary/rc have no file -> empty body, unchanged. New manual `announce` workflow (workflow_dispatch, tag input) re-syncs the notes file over the live release and posts a violet embed (title, notes lead-in, release-page link) to the Discord #releases channel via the DISCORD_RELEASE_WEBHOOK secret. Stable-only: a -rc tag is refused unless allow_prerelease=true. Pressing "go" is the quality gate, so a half-built or failed release is never announced. docs/releases/README.md documents the ritual; TEMPLATE.md is the skeleton. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
83 lines
4.1 KiB
PowerShell
83 lines
4.1 KiB
PowerShell
# Shared Gitea Release helpers for the punktfunk Windows CI workflows (pwsh / PowerShell 7).
|
|
#
|
|
# Dot-source it, then call Ensure-GiteaRelease / Upsert-GiteaAsset:
|
|
# . scripts/ci/gitea-release.ps1
|
|
# Mirrors scripts/ci/gitea-release.sh; parses JSON with ConvertFrom-Json (the Windows runner
|
|
# has no python). Same idempotent semantics: Upsert-GiteaAsset deletes an existing asset of
|
|
# the same name before uploading, so re-runs / rolling canary uploads don't 409.
|
|
#
|
|
# Env (Gitea Actions sets the first two automatically):
|
|
# GITHUB_SERVER_URL e.g. https://git.unom.io
|
|
# GITHUB_REPOSITORY e.g. unom/punktfunk
|
|
# GITEA_TOKEN a PAT with repository (release) write scope — set from secrets.REGISTRY_TOKEN
|
|
# (must carry write:repository, not only write:package)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
function _GiteaApi {
|
|
if (-not $env:GITHUB_SERVER_URL) { throw 'GITHUB_SERVER_URL unset' }
|
|
if (-not $env:GITHUB_REPOSITORY) { throw 'GITHUB_REPOSITORY unset' }
|
|
"$($env:GITHUB_SERVER_URL)/api/v1/repos/$($env:GITHUB_REPOSITORY)"
|
|
}
|
|
|
|
function _GiteaHeaders {
|
|
if (-not $env:GITEA_TOKEN) { throw 'GITEA_TOKEN unset' }
|
|
@{ Authorization = "token $($env:GITEA_TOKEN)" }
|
|
}
|
|
|
|
# Ensure-GiteaRelease TAG NAME PRERELEASE [TARGETCOMMITISH] -> release id
|
|
# Idempotently create or fetch the release for TAG. Prerelease is 'true', 'false', or 'auto'
|
|
# (auto marks it a prerelease iff TAG carries a `-` pre-release suffix, e.g. v0.2.0-rc1, so an
|
|
# rc never becomes "Latest"). TargetCommitish (optional) creates the tag if missing.
|
|
function Ensure-GiteaRelease {
|
|
param(
|
|
[Parameter(Mandatory)] [string]$Tag,
|
|
[Parameter(Mandatory)] [string]$Name,
|
|
[Parameter(Mandatory)] [string]$Prerelease,
|
|
[string]$TargetCommitish
|
|
)
|
|
$pre = if ($Prerelease -eq 'auto') { [bool]($Tag -match '-') } else { [System.Convert]::ToBoolean($Prerelease) }
|
|
$api = _GiteaApi; $h = _GiteaHeaders
|
|
$payload = @{ tag_name = $Tag; name = $Name; prerelease = $pre }
|
|
if ($TargetCommitish) { $payload.target_commitish = $TargetCommitish }
|
|
# Seed the body from docs/releases/<Tag>.md (the source of truth) so a Windows job winning the
|
|
# create race is born WITH its notes, exactly like the bash twin. Missing file (canary/rc) -> no
|
|
# body key. $PSScriptRoot is scripts/ci; walk up two levels to the repo root.
|
|
$notes = Join-Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) "docs/releases/$Tag.md"
|
|
if (Test-Path $notes) { $payload.body = Get-Content -Raw -Encoding utf8 $notes }
|
|
try {
|
|
$r = Invoke-RestMethod -Method Post -Uri "$api/releases" -Headers $h `
|
|
-ContentType 'application/json' -Body ($payload | ConvertTo-Json -Compress)
|
|
return $r.id
|
|
} catch {
|
|
# Almost always: the release already exists. Fetch it by tag; error if that fails too.
|
|
$r = Invoke-RestMethod -Method Get -Uri "$api/releases/tags/$Tag" -Headers $h
|
|
if (-not $r.id) { throw "gitea-release: could not create or find a release for tag '$Tag'" }
|
|
return $r.id
|
|
}
|
|
}
|
|
|
|
# Upsert-GiteaAsset RELEASEID FILE [NAME]
|
|
# Attach FILE, replacing any existing asset of the same name first (idempotent).
|
|
function Upsert-GiteaAsset {
|
|
param(
|
|
[Parameter(Mandatory)] [string]$ReleaseId,
|
|
[Parameter(Mandatory)] [string]$File,
|
|
[string]$Name
|
|
)
|
|
if (-not (Test-Path $File)) { throw "gitea-release: asset file not found: $File" }
|
|
if (-not $Name) { $Name = Split-Path $File -Leaf }
|
|
$api = _GiteaApi; $h = _GiteaHeaders
|
|
$assets = Invoke-RestMethod -Method Get -Uri "$api/releases/$ReleaseId/assets" -Headers $h
|
|
$existing = $assets | Where-Object { $_.name -eq $Name } | Select-Object -First 1
|
|
if ($existing) {
|
|
Invoke-RestMethod -Method Delete -Uri "$api/releases/$ReleaseId/assets/$($existing.id)" -Headers $h | Out-Null
|
|
}
|
|
$enc = [uri]::EscapeDataString($Name)
|
|
# curl.exe for the multipart upload — matches the rest of the windows workflows.
|
|
curl.exe -fsS -H "Authorization: token $($env:GITEA_TOKEN)" -o NUL `
|
|
-X POST "$api/releases/$ReleaseId/assets?name=$enc" -F "attachment=@$File"
|
|
if ($LASTEXITCODE -ne 0) { throw "gitea-release: asset upload failed ($LASTEXITCODE): $Name" }
|
|
Write-Output "gitea-release: uploaded '$Name' -> release $ReleaseId"
|
|
}
|