feat: permanent download links for the Longshot Launcher, per channel, at /download #7

Closed
HumanBean wants to merge 1 commit from HumanBean/Site:download-links into main
Owner

Why

Forgejo's /releases/latest covers stable releases only, and there is no stable Longshot Launcher yet, so the READMEs and release pages have no link that always gives players the newest launcher. This adds permanent download links per channel on magicbean.dev, and a download page that picks the file for the visitor's computer.

What changed

  • Worker: src/index.js answers /download* (everything else is still a file of public/). It reads LongshotLauncher's release list from git.magicbean.dev's API (with a User-Agent, cached 60 s with the Cache API) and picks each channel's newest by the launcher's own rules (Core/ReleaseManifest.cs, release.py newest): never a draft; stable the newest vX.Y.Z that isn't a pre-release; rc the newest vX.Y.Z-rc.N or vX.Y.Z; nightly the newest by its count.
    • /download: a page with a big button for the visitor's system (by User-Agent), the other files, every channel, and "download the launcher, not the builder".
    • /download/launcher/<windows|windows-portable|linux>: 302 to that file of the best channel there is (stable, else rc, else nightly). The READMEs' big buttons use these.
    • /download/launcher/<stable|rc|nightly>: 302 to the channel's newest release page.
    • /download/launcher/<channel>/<os>: 302 to that file of the channel's newest release. Longshot's release pages use these, on their own channel.
    • A channel or file that isn't there: a 404 page that says so ("No stable launcher yet"), with a button to the newest there is. git.magicbean.dev unreachable: a 502 page with the releases link.
  • wrangler.jsonc: main, the ASSETS binding, and run_worker_first for /download and /download/*.
  • test/download.test.mjs (npm test, Node, no network): the channel rules, the same cases as tests/test_release.py's.
  • README: the links and how they choose.

Used by MagicBeanDev/Longshot#148 and MagicBeanDev/LongshotLauncher#15.

Flags and settings

None.

Measurements

What each link answers under wrangler dev, against the real release list (LongshotLauncher has v1.0.0-rc.1 and nightlies, no stable).

main: 96b00863 (2026-11-13)
this PR: download-links @ e42d2206
Hardware: CachyOS (Linux 7.3), Wrangler 4.160.1, Node 26
Scene: none
Method: npx wrangler dev, then curl -s -o /dev/null -w '%{http_code} %{redirect_url}' on each link, twice
How to reproduce: npm install, npm run dev, the curl above

main @ 96b00863 this PR @ e42d2206
/ 200 200
/download 404 200 (the page)
/download/launcher/windows, windows-portable, linux 404 302 to v1.0.0-rc.1's setup.exe, portable zip, AppImage
/download/launcher/rc 404 302 to the v1.0.0-rc.1 release page
/download/launcher/rc/windows, /rc/windows-portable, /rc/linux 404 302 to v1.0.0-rc.1's files
/download/launcher/nightly, /nightly/<os> 404 302 to nightly-11-00741b60's page and files
/download/launcher/stable, /stable/windows 404 404 "No stable launcher yet", a button to v1.0.0-rc.1
/download/launcher/beta, /nightly/mac 404 404 "No such download" / "has no … file"
npm test (none) 4 passed
/download/launcher/rc/linux  302 https://git.magicbean.dev/MagicBeanDev/LongshotLauncher/releases/download/v1.0.0-rc.1/LongshotLauncher-v1.0.0-rc.1-x86_64.AppImage
(followed: 200)

Testing

Tested: every link above under wrangler dev (HEAD too), a redirect followed to the file (200), the pages in a browser (screenshots), the cache (later requests answer in about 10 ms without asking git.magicbean.dev), npm test.

Not tested: the deployed Worker on magicbean.dev (Cloudflare's edge cache and the custom domain): only a deploy shows it. The 502 page (git.magicbean.dev unreachable) was not forced. Nothing here is deployed; the preview needs the preview label, since this PR is from a fork.

Needs other testers: None

Screenshots

/download (Linux browser; no stable yet, so the rc):

/download

/download/launcher/stable/linux while there is no stable:

no stable yet

Risk and rollback

Merging deploys it: .forgejo/workflows/deploy.yml runs wrangler deploy on every push to main. This is the first Worker code on the site; if it breaks, / and the other files are still served by the static assets (only /download* runs the Worker first). A broken Worker script would fail the deploy, leaving the current site up. Rollback: revert the commit (the next deploy removes the Worker code), or npx wrangler rollback to the previous version. Merge this before the Longshot and LongshotLauncher PRs, whose READMEs link these URLs.

Reviewer notes

Start with newest and download in src/index.js. The release list is read with no token (public releases only, so never a draft).

This repository has no tests/run_all.py: the checklist's run_all box stands for npm test and the link sweep above.

Issues

None.

Checklist

For everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description).
  • Rebased on current main.
  • python -I -B tests/run_all.py run and passing (any failure that also fails on main is named above).
  • Tested in the game, or what wasn't is named under Testing.
  • Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests).
  • Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported.
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

If applicable

  • Screenshots for a change that shows on screen.
  • A game-free test added for the fix, failing on main and passing here.
  • Docs updated.
## Why Forgejo's `/releases/latest` covers stable releases only, and there is no stable Longshot Launcher yet, so the READMEs and release pages have no link that always gives players the newest launcher. This adds permanent download links per channel on magicbean.dev, and a download page that picks the file for the visitor's computer. ## What changed - Worker: `src/index.js` answers `/download*` (everything else is still a file of `public/`). It reads LongshotLauncher's release list from git.magicbean.dev's API (with a User-Agent, cached 60 s with the Cache API) and picks each channel's newest by the launcher's own rules (`Core/ReleaseManifest.cs`, `release.py newest`): never a draft; stable the newest `vX.Y.Z` that isn't a pre-release; rc the newest `vX.Y.Z-rc.N` or `vX.Y.Z`; nightly the newest by its count. - `/download`: a page with a big button for the visitor's system (by User-Agent), the other files, every channel, and "download the launcher, not the builder". - `/download/launcher/<windows|windows-portable|linux>`: 302 to that file of the best channel there is (stable, else rc, else nightly). The READMEs' big buttons use these. - `/download/launcher/<stable|rc|nightly>`: 302 to the channel's newest release page. - `/download/launcher/<channel>/<os>`: 302 to that file of the channel's newest release. Longshot's release pages use these, on their own channel. - A channel or file that isn't there: a 404 page that says so ("No stable launcher yet"), with a button to the newest there is. git.magicbean.dev unreachable: a 502 page with the releases link. - `wrangler.jsonc`: `main`, the `ASSETS` binding, and `run_worker_first` for `/download` and `/download/*`. - `test/download.test.mjs` (`npm test`, Node, no network): the channel rules, the same cases as `tests/test_release.py`'s. - README: the links and how they choose. Used by MagicBeanDev/Longshot#148 and MagicBeanDev/LongshotLauncher#15. ## Flags and settings None. ## Measurements What each link answers under `wrangler dev`, against the real release list (LongshotLauncher has v1.0.0-rc.1 and nightlies, no stable). main: 96b00863 (2026-11-13) this PR: download-links @ e42d2206 Hardware: CachyOS (Linux 7.3), Wrangler 4.160.1, Node 26 Scene: none Method: `npx wrangler dev`, then `curl -s -o /dev/null -w '%{http_code} %{redirect_url}'` on each link, twice How to reproduce: `npm install`, `npm run dev`, the curl above | | main @ 96b00863 | this PR @ e42d2206 | |---|---|---| | `/` | 200 | 200 | | `/download` | 404 | 200 (the page) | | `/download/launcher/windows`, `windows-portable`, `linux` | 404 | 302 to v1.0.0-rc.1's setup.exe, portable zip, AppImage | | `/download/launcher/rc` | 404 | 302 to the v1.0.0-rc.1 release page | | `/download/launcher/rc/windows`, `/rc/windows-portable`, `/rc/linux` | 404 | 302 to v1.0.0-rc.1's files | | `/download/launcher/nightly`, `/nightly/<os>` | 404 | 302 to nightly-11-00741b60's page and files | | `/download/launcher/stable`, `/stable/windows` | 404 | 404 "No stable launcher yet", a button to v1.0.0-rc.1 | | `/download/launcher/beta`, `/nightly/mac` | 404 | 404 "No such download" / "has no … file" | | `npm test` | (none) | 4 passed | ``` /download/launcher/rc/linux 302 https://git.magicbean.dev/MagicBeanDev/LongshotLauncher/releases/download/v1.0.0-rc.1/LongshotLauncher-v1.0.0-rc.1-x86_64.AppImage (followed: 200) ``` ## Testing **Tested:** every link above under `wrangler dev` (HEAD too), a redirect followed to the file (200), the pages in a browser (screenshots), the cache (later requests answer in about 10 ms without asking git.magicbean.dev), `npm test`. **Not tested:** the deployed Worker on magicbean.dev (Cloudflare's edge cache and the custom domain): only a deploy shows it. The 502 page (git.magicbean.dev unreachable) was not forced. Nothing here is deployed; the preview needs the `preview` label, since this PR is from a fork. **Needs other testers:** None ## Screenshots `/download` (Linux browser; no stable yet, so the rc): ![/download](https://git.magicbean.dev/HumanBean/Site/raw/branch/pr-assets-download-links/site-download.png) `/download/launcher/stable/linux` while there is no stable: ![no stable yet](https://git.magicbean.dev/HumanBean/Site/raw/branch/pr-assets-download-links/site-404-stable.png) ## Risk and rollback **Merging deploys it**: `.forgejo/workflows/deploy.yml` runs `wrangler deploy` on every push to `main`. This is the first Worker code on the site; if it breaks, `/` and the other files are still served by the static assets (only `/download*` runs the Worker first). A broken Worker script would fail the deploy, leaving the current site up. Rollback: revert the commit (the next deploy removes the Worker code), or `npx wrangler rollback` to the previous version. Merge this **before** the Longshot and LongshotLauncher PRs, whose READMEs link these URLs. ## Reviewer notes Start with `newest` and `download` in `src/index.js`. The release list is read with no token (public releases only, so never a draft). This repository has no `tests/run_all.py`: the checklist's run_all box stands for `npm test` and the link sweep above. ## Issues None. ## Checklist ### For everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`). - [x] Rebased on current `main`. - [x] `python -I -B tests/run_all.py` run and passing (any failure that also fails on `main` is named above). - [x] Tested in the game, or what wasn't is named under Testing. - [x] Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests). - [x] Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### If applicable - [x] Screenshots for a change that shows on screen. - [x] A game-free test added for the fix, failing on `main` and passing here. - [x] Docs updated.
feat: permanent download links for the Longshot Launcher, per channel, at /download
Some checks were skipped
Preview / Preview on Cloudflare (pull_request) Has been skipped
e42d2206d0
HumanBean changed title from WIP: feat: permanent download links for the Longshot Launcher, per channel, at /download to feat: permanent download links for the Longshot Launcher, per channel, at /download 2026-11-13 07:10:41 +00:00
HumanBean closed this pull request 2026-11-13 07:15:45 +00:00
Author
Owner

Closing: the permanent launcher links live on longshot.magicbean.dev instead (the Longshot website, /download/launcher/<channel>/<os>).

Closing: the permanent launcher links live on longshot.magicbean.dev instead (the Longshot website, `/download/launcher/<channel>/<os>`).
Some checks were skipped
Preview / Preview on Cloudflare (pull_request) Has been skipped

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
preview
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Site!7
No description provided.