# Bundled client assets Holds the Android APK (`minstrel.apk`) and its version sidecar (`minstrel.apk.version`) that the server serves via `/api/client/version` and `/api/client/apk` for the in-app update flow. ## Production CI fills this directory in `release.yml` before every image build: - **Dev push (`:dev`) and tag release (`v*`):** the `android-release` job builds and signs the APK and uploads it as a workflow artifact; `image-release` downloads it here as `minstrel.apk` and writes the sidecar from that build's version outputs. A tag release also attaches both files to the Gitea release. - **Main push (`:latest` + `:`):** no APK is built, but the image still moves `:latest`, so `image-release` downloads the most recent release's APK and the sidecar recorded beside it. `:latest` keeps its update channel between releases. Either way, `docker buildx build` bakes both files into the image via `COPY client/ /app/client/`. ## The sidecar `minstrel.apk.version` is JSON: ```json {"name": "2026.10.23.1200", "code": 3549060, "channel": "dev"} ``` - `name` is the version name the app shows. - `code` is the ordering key Android installs by. `null` means unknown, and clients then compare names. - `channel` says which lane built it. A sidecar that is not valid JSON, or has no `name`, is an error rather than a blank version. ## Development An empty directory works fine: the endpoints return 404 and the Android update banner stays hidden. To smoke-test the update flow locally, drop a real APK and a sidecar into this directory: ```sh cp /path/to/app-release.apk client/minstrel.apk echo '{"name":"2099.01.01.0000","code":null,"channel":"dev"}' > client/minstrel.apk.version ``` ## Why a directory and not embed.FS? The APK is 30-60 MB. Embedding bloats the Go binary and slows `go build` for everyone, even when the APK isn't being changed. File-on-disk also lets an admin override it at runtime with a volume mount on `/app/client/` to ship their own build.