diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 9ba13531..f775e9fb 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -180,3 +180,31 @@ jobs: -Uri "$api/releases/$($pointer.id)/assets?name=manifest.json" ` -Form @{ attachment = Get-Item bin/manifest.json } | Out-Null Write-Host "latest pointer now advertises $env:TAG" + + - name: Prune old releases + shell: pwsh + env: + KEEP: '5' + TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + $ErrorActionPreference = 'Stop' + $api = "${{ github.server_url }}/api/v1/repos/${{ github.repository }}" + $headers = @{ Authorization = "token $env:TOKEN" } + $keep = [int]$env:KEEP + + # Each build is ~121 MB of attachments, so without this the server + # grows by that much on EVERY push to main. Keep the newest $keep + # versioned releases: enough to grab a previous build or bisect a + # regression, bounded at well under a gigabyte. + $releases = Invoke-RestMethod -Method Get -Headers $headers -Uri "$api/releases?limit=100" + # Never touch the `latest` pointer — it is the launcher's feed, not a build. + $builds = @($releases | Where-Object { $_.tag_name -ne 'latest' } | + Sort-Object -Property created_at -Descending) + + Write-Host "$($builds.Count) versioned release(s); keeping $keep" + foreach ($old in ($builds | Select-Object -Skip $keep)) { + Invoke-RestMethod -Method Delete -Headers $headers -Uri "$api/releases/$($old.id)" | Out-Null + # The tag survives its release and would otherwise accumulate. + Invoke-RestMethod -Method Delete -Headers $headers -Uri "$api/tags/$($old.tag_name)" -SkipHttpErrorCheck | Out-Null + Write-Host " pruned $($old.tag_name)" + } diff --git a/docs/ci-and-releases.md b/docs/ci-and-releases.md index bc64eb3c..25c3eeec 100644 --- a/docs/ci-and-releases.md +++ b/docs/ci-and-releases.md @@ -86,8 +86,11 @@ route** (verified: 404) — unlike GitHub, there is no built-in stable URL for means deleting the old release *and* its tag; the tag outlives its release and would otherwise block recreation. -Versioned releases are kept, so an older build stays downloadable and the -launcher's local rollback still has something to fall back to. +The newest **5** versioned releases are kept and older ones are pruned with +their tags. Each build is ~121 MB of attachments, so retaining every one grew +the server by that much per push — 5 builds had already reached 606 MB. Five is +enough to grab a previous build or bisect a regression while staying bounded. +The `latest` pointer is never pruned; it is the feed, not a build. `tools/publish-bin.ps1 -BaseUrl ` builds the payloads; CI passes the tag's asset base. Running it locally is for inspection only —