Fix Windows release upload: idempotent get-or-create + fail-loud #6

Merged
jknapp merged 2 commits from feature/ux-improvements into main 2026-06-24 16:28:59 +00:00
+52 -10
View File
@@ -428,20 +428,62 @@ jobs:
- name: Upload to Gitea release - name: Upload to Gitea release
if: gitea.event_name == 'push' if: gitea.event_name == 'push'
shell: powershell
env: env:
TOKEN: ${{ secrets.REGISTRY_TOKEN }} TOKEN: ${{ secrets.REGISTRY_TOKEN }}
COMMIT_SHA: ${{ gitea.sha }} COMMIT_SHA: ${{ gitea.sha }}
VERSION: ${{ needs.compute-version.outputs.version }}
run: | run: |
set "TAG=v${{ needs.compute-version.outputs.version }}-win" $ErrorActionPreference = "Stop"
echo Creating release %TAG%... $tag = "v$env:VERSION-win"
curl -s -X POST -H "Authorization: token %TOKEN%" -H "Content-Type: application/json" -d "{\"tag_name\": \"%TAG%\", \"name\": \"Triple-C v${{ needs.compute-version.outputs.version }} (Windows)\", \"body\": \"Automated build from commit %COMMIT_SHA%\"}" "%GITEA_URL%/api/v1/repos/%REPO%/releases" > release.json $headers = @{ Authorization = "token $env:TOKEN" }
for /f "tokens=2 delims=:," %%a in ('findstr /c:"\"id\"" release.json') do set "RELEASE_ID=%%a" & goto :found $api = "$env:GITEA_URL/api/v1/repos/$env:REPO"
:found
echo Release ID: %RELEASE_ID% # Idempotent get-or-create. The old cmd-batch version swallowed
for %%f in (artifacts\*) do ( # curl errors and parsed the release id with findstr, so a 409 on
echo Uploading %%~nxf... # a pre-existing tag yielded an empty RELEASE_ID and uploads went to
curl -s -X POST -H "Authorization: token %TOKEN%" -H "Content-Type: application/octet-stream" --data-binary "@%%f" "%GITEA_URL%/api/v1/repos/%REPO%/releases/%RELEASE_ID%/assets?name=%%~nxf" # a malformed .../releases//assets URL while the step still reported
) # success. Look the release up by tag first; create only on 404.
try {
$release = Invoke-RestMethod -Method Get -Headers $headers -Uri "$api/releases/tags/$tag"
Write-Host "Release $tag already exists, reusing"
} catch {
if ($_.Exception.Response.StatusCode.value__ -eq 404) {
Write-Host "Release $tag not found, creating"
$body = @{
tag_name = $tag
name = "Triple-C v$env:VERSION (Windows)"
body = "Automated build from commit $env:COMMIT_SHA"
} | ConvertTo-Json
$release = Invoke-RestMethod -Method Post -Headers $headers `
-ContentType "application/json" -Body $body -Uri "$api/releases"
} else {
throw
}
}
$releaseId = $release.id
if (-not $releaseId) { throw "Failed to resolve release id for $tag" }
Write-Host "Release ID: $releaseId"
# Upload each artifact. Delete any same-named asset left over from a
# partial prior run first, so the upload replaces rather than 409s.
$existing = Invoke-RestMethod -Method Get -Headers $headers -Uri "$api/releases/$releaseId/assets"
foreach ($file in Get-ChildItem -File -Path artifacts\*) {
$name = $file.Name
$dupe = $existing | Where-Object { $_.name -eq $name }
if ($dupe) {
Write-Host "Deleting existing asset $name (id $($dupe.id))"
Invoke-RestMethod -Method Delete -Headers $headers -Uri "$api/releases/$releaseId/assets/$($dupe.id)" | Out-Null
}
Write-Host "Uploading $name..."
$uploadUri = "$api/releases/$releaseId/assets?name=$([uri]::EscapeDataString($name))"
curl.exe -fsS --retry 5 --retry-all-errors --retry-delay 5 --max-time 600 `
-X POST -H "Authorization: token $env:TOKEN" `
-H "Content-Type: application/octet-stream" `
--data-binary "@$($file.FullName)" $uploadUri
if ($LASTEXITCODE -ne 0) { throw "Upload of $name failed (curl exit $LASTEXITCODE)" }
}
create-tag: create-tag:
runs-on: ubuntu-latest runs-on: ubuntu-latest