.dockerignore, .gitignore, deploy/initdb, ci-requirements.md, client/README.md, shared/README.md and two web/scripts test names: dates, issue/rule/spike ids and the stories behind each exclusion removed. Corrected: - client/README.md: the dev lane bundles its own APK; :main no longer exists; main bundles the recorded sidecar instead of re-deriving the version name. Its smoke-test step wrote a bare "v0.2.0", which the server rejects as a sidecar that is not JSON; it now writes the JSON shape, which the README documents. - ci-requirements.md: one workflow, not four; the android lane builds no debug APK; main reads the recorded sidecar. - .gitignore: CI fills client/ on every image build, not tag releases only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
2.0 KiB
Markdown
59 lines
2.0 KiB
Markdown
# 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` + `:<sha>`):** 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.
|