ci: put the launcher's update pointer in a release, and delete the dist branch
Some checks failed
CI / linux-portable (push) Failing after 3m22s
CI / windows-gate (push) Successful in 5m27s
CI / release (push) Has been skipped

The dist branch existed to carry ~120 MB payloads that could not go on main.
Once payloads became release attachments it held one 500-byte manifest.json,
so it was a whole branch for a reason that no longer applied.

The pointer is now a release asset too: each publish recreates a one-asset
 release naming the versioned build. Forgejo has no
/releases/latest/download/ route (404), so a pointer is still required — but
keeping it in a release means nothing about distribution lives in git: no
payload branch, no bot commits on main, and no push that could retrigger the
pipeline (which is why writing the manifest to main was not the answer either).

Recreating the tag deletes the old release AND its tag; the tag outlives its
release and would otherwise block recreation.

Versioned releases are retained, so older builds stay downloadable.
tools/publish-dist.ps1 is removed — publishing is CI's job now.
This commit is contained in:
Erik 2026-08-19 14:40:41 +02:00
parent 353231fe6e
commit ff01423f3f
6 changed files with 87 additions and 218 deletions

View file

@ -13,7 +13,7 @@ git push origin main
├─ linux-portable (eriktestLinux) portable closure, Linux lanes
└─ release (needs BOTH green) publish a Gitea Release
+ repoint the launcher manifest
+ republish the `latest` pointer
```
Workflow: [`.gitea/workflows/ci.yml`](../.gitea/workflows/ci.yml). A red gate
@ -58,28 +58,40 @@ Windows uses Gitea's `act_runner`. Forgejo speaks the same Actions protocol.
## Releases
Payloads are **release attachments**, deliberately outside git history: a build
is ~120 MB and would otherwise land in a branch every push. Only the ~500-byte
`manifest.json` is committed, to the payload-free `dist` branch.
Everything about distribution lives under **Releases** — nothing in git. A build
is ~120 MB, so payloads are release attachments; and the pointer the launcher
polls is itself a release asset, so there is no payload branch, no bot commit on
`main`, and no push that could retrigger the pipeline.
```
Release 0.1.0-build.<yyyyMMddHHmm>
Release 0.1.0-build.<yyyyMMddHHmm> <- the actual build
client-win-x64.zip AcDream.App.exe + acdream-headless.exe
launcher-win-x64.zip acdream-launcher.exe + acdream-bake.exe
manifest.json
dist branch (manifest only, force-replaced each publish)
bin/manifest.json -> points at the release attachment URLs
Release latest <- pointer, replaced every publish
manifest.json names the version above and its asset URLs
```
The launcher polls the manifest at a fixed raw URL
(`ReleaseManifestClient.ProductionManifestUri`). **Forgejo has no
`/releases/latest/download/` route** (verified: 404), which is why the manifest
cannot simply live in the release itself.
The launcher polls the pointer at a URL that never changes
(`ReleaseManifestClient.ProductionManifestUri`):
`tools/publish-bin.ps1 -BaseUrl <release asset base>` builds the payloads; the
pipeline passes the tag's asset base. With no `-BaseUrl` it falls back to the
dist-branch layout for a manual local publish.
```
https://git.snakedesert.se/erik/acdream/releases/download/latest/manifest.json
```
A pointer is needed because **Forgejo has no `/releases/latest/download/`
route** (verified: 404) — unlike GitHub, there is no built-in stable URL for
"the newest release". Publishing it recreates the `latest` tag each time, which
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.
`tools/publish-bin.ps1 -BaseUrl <release asset base>` builds the payloads; CI
passes the tag's asset base. Running it locally is for inspection only —
publishing is CI's job.
### Verifying a release