~ knotless Search/
↑↓ move↵ open⇧↵ all results

grain.social/grain

photography-focused photo sharing platform

grain.social
1 collaborator
0
2

Serve minimum app versions at /app-version.json

Merged chadtmiller.com asked to merge into feature/rust from grain.social/grain:rust/app-version

Only what this pull adds. It is built on grain runs on a Rust server modelled on knotless, without hatk.

web/static/app-version.jsonnew+10−0
@@ -0,0 +1,10 @@
{
"ios": {
"minimumBuild": 0,
"storeUrl": "https://apps.apple.com/app/id6747730230"
},
"android": {
"minimumVersionCode": 0,
"storeUrl": "https://play.google.com/store/apps/details?id=social.grain"
}
}
AGENTS.md+15−0
@@ -287,6 +287,21 @@ first and falls back to `simplespace` on a 404 or 501.
When touching the space client, check a call against both servers' handlers:
`packages/spaces/src/handlers/` in pds.js, `src/atproto/space.zig` in zds.
## Minimum app versions
`web/static/app-version.json`, served at `https://grain.social/app-version.json`,
is the oldest build of each app this server still serves. grain-serve hands the
path to the pages, which answer it from `web/static`. The iOS and Android apps
read it on launch and on returning to the foreground, and a build below its
minimum shows a full-screen "Update Grain" that cannot be dismissed. Each app
remembers the last minimum it read, so a blocked build stays blocked offline.
The numbers are build numbers, not marketing versions: `ios.minimumBuild` is
`CFBundleVersion` (`CURRENT_PROJECT_VERSION` in grain-ios's `project.yml`),
`android.minimumVersionCode` is `versionCode`. `0` blocks nothing. Raise one
only once the build it names is live in its store, or people are told to
install an update they cannot get.
## Production debugging
Production is a single Hetzner host, `167.233.237.163`, running the appview,