# Bundled client assets

Holds the Android APK (`minstrel.apk` + `minstrel.apk.version`) that the
server serves via `/api/client/version` and `/api/client/apk` for the
in-app update flow (#397).

## Production

CI populates this directory in `release.yml` (no Flutter — the client is
native Android, built by the `android-release` job):

- **Tag release (`v*`):** the `android-release` job builds + signs the
  APK, uploads it as a workflow artifact, and attaches it to the Gitea
  release as `minstrel-<TAG>.apk`. The `image-release` job
  (`needs: android-release`) downloads that artifact into this directory
  as `minstrel.apk` and writes the computed versionName to
  `minstrel.apk.version`.
- **Main push (non-tag `:latest` / `:main`):** no APK is built, but the
  image still moves `:latest`, so `image-release` pulls the most-recent
  release's signed APK from the Gitea API and reconstructs its exact
  versionName — keeping the in-app update channel alive on `:latest`
  instead of stripping it until the next tag.

Either way, `docker buildx build` bakes both files into the image via
`COPY client/ /app/client/`.

## Development

Empty directory works fine — the endpoints return 404 and the Android
update banner stays hidden ("no update channel" graceful degradation).

To smoke-test the update flow locally, drop a real APK + a version
file into this directory:

```sh
cp /path/to/app-release.apk client/minstrel.apk
echo "v0.2.0" > 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 operators override at runtime via volume
mount on `/app/client/` if they want to ship their own build.
