Add GET /api/me/access server endpoint that returns the authenticated user's active access grants grouped by project, with resolved names. The CLI's whoami --verify now displays this after the auth check. Gracefully degrades against older servers that lack the endpoint. |
||
|---|---|---|
| .forgejo/workflows | ||
| .vscode | ||
| api/typescript | ||
| bin | ||
| cli | ||
| components | ||
| docs | ||
| examples | ||
| scripts | ||
| sdks | ||
| servers | ||
| .gitignore | ||
| CLAUDE.md | ||
| default.do | ||
| deploy.nu | ||
| download-page-kit.nomad.hcl | ||
| go.work | ||
| go.work.sum | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| README.talk.md | ||
Get Started · Examples · Try the Demo · Docs · Discord
Download Page Kit is a release toolkit for software you ship outside the browser. We make you productive by handling the bookkeeping around testing and releasing.
You push built binaries and Download Page Kit handles storing them, getting them to your test devices, and tracking which tests you've done. When you promote a release, your download page updates on the next page load. Plus, rollback is a single click.
We also support sharing release candidates with customers via expiring links, and CI integration for automated pushes. Currently we have a CLI, a self-hosted server, and web components for React and Qwik.
How does it look? Here's a release from start to finish:
# Push binaries from CI
download-page-kit push ./dist --release 1.2.0 --commit abc123
# => Candidate: 3-quick-fox
# On your test machine, pull and test
download-page-kit pull 3-quick-fox
download-page-kit testing
# When all tests pass, promote
download-page-kit promote stable
download-page-kit promote stable --candidate 3-quick-fox
# => Your download page updates on the next page load
Want to see for yourself? Follow the quickstart to push your first release candidate.
You probably don't need this if:
- You control the environment where your software runs.
- You are deploying a web app or ship Docker images.
- You have the luxury of buildling and flashing firmware for one chipset.
- You're building a Mac only app on a Mac.
- You trust your automated tests enough to ship without clicking around the app yourself.
- You have plenty of free time. You are are not squeezing a project into the gaps between your job and life.
Motivation
Shipping software that random people worldwide install on their own machines is full of schleps. You pick a commit that might work, build for a bunch of target platforms, then test the platform-specific stuff. Does the installer work? Does it start up? (curse you SmartScreen). Then all the smoke tests so you don't look stupid when someone follows the 2 minute quickstart tutorial. None of this work is hard, just so fucking tedious and annoying.
Tell me if you tried to save some time by testing in your head and got burned. Ever been caght flat footed reasoning that the code changes haven't touched this flow, so you can skip testing it. That's tough to get away with now, when AI agents write much of the code and you're deliberately shedding deep understanding for speed.
When you get to the point of stupid obvious failures sneaking out and you've bought the device If But there's a limit to how big a test plan you can keep in your head month after month, when your attention is split into one-hour and three-hour chunks after work, trying to get customers and grow revenue. You need a system, but it's always tempting to just ship it and move on.
Could it be better?
I realized that most of the schleps we face as builders aren't hard — they're just easy enough to skip.
If you had a system that stored your binaries and wrote down the test plan for you, doing it right would be just as easy as cutting corners. If that system tracked your progress across devices, you could pick up where you left off an hour or a week later. And if you fix a bug on one platform, the test results on the other artifacts carry over — you don't have to retest everything from scratch.
So I built Download Page Kit. Download Page Kit gives you a release process that makes the path of least resistance the correct path, so you can focus on what's important: building your software, and shipping it often.
Architectural Overview
Here's how Download Page Kit works at a high level:
Under the hood, the server is simple Golang application backed by SQLite. Binaries are stored in any S3-compatible storage you bring — MinIO, Cloudflare R2, Backblaze B2, or AWS S3.
A CLI talks to the server over HTTP. It auto-detects platform and architecture by inspecting binary headers (ELF, Mach-O, PE), so pushing a directory of builds just works:
download-page-kit push ./dist --release 1.2.0 --commit abc123
For testing, I built an interactive TUI. You add test names, navigate between artifacts, and mark tests passed or failed with single keystrokes:
Testing: 3-quick-fox (v1.2.0)
──────────────────────────────────────────────────
[+] windows/amd64 Installer — my-app-Setup.exe
[+] Installs cleanly
[+] Starts without crash
(press a to add)
[.] darwin/arm64 DMG — my-app-arm64.dmg
[.] Installs cleanly
(press a to add)
> [ ] linux/amd64 AppImage — my-app.AppImage
(no tests — press a to add)
──────────────────────────────────────────────────
j/k navigate [a]dd [s]tart [p]ass [f]ail [q]uit
For the frontend, I wrote web components in Mitosis that compile to React and Qwik. Drop them into your site and they query the server's JSON API to render download buttons for the latest promoted release.
Getting Started
The easiest way to get started with Download Page Kit is the quickstart. You can push your first release candidate in about 10 minutes.
For CI integration, see the CI quickstart.
CI
The Build CLI workflow (.forgejo/workflows/build-cli.yml) cross-compiles the CLI for linux, darwin, and windows (amd64 + arm64).
Build runs on every push or pull request that touches cli/** or sdks/go/**.
Release runs only when a tag matching cli-v* is pushed (e.g. git tag cli-v0.3.0 && git push --tags). It collects the build artifacts and creates a Forgejo release with auto-generated notes.
