f49efc67b6
Split oversized examples/006 into command-surface, generated-helper, and mobile-boundary requirements. req: examples/006 req: examples/010 req: examples/011
120 lines
5.0 KiB
Markdown
120 lines
5.0 KiB
Markdown
# Recipe: Workout mobile release
|
|
|
|
The Workout exemplar is the production-shaped mobile path for hemx. It stays
|
|
boring on purpose: hemx builds the server app and writes mobile shell metadata;
|
|
Android/iOS SDKs, store signing, provisioning, and submission remain external
|
|
vendor work. req: examples/011
|
|
|
|
## Command surface
|
|
|
|
Create a standalone phone-first starter from the public app command when you want
|
|
this path outside the repository:
|
|
|
|
```sh
|
|
cargo run -p hemx-xtask -- app new --mobile PATH
|
|
```
|
|
|
|
The created app includes app-owned `hemx-app mobile-release` and
|
|
`hemx-app mobile-verify` commands, plus `MOBILE_STARTER.md` naming the host,
|
|
recovery, and release-kit boundary. req: ceremony/006
|
|
|
|
## When to use this path
|
|
|
|
Use hemx mobile when the app is still a Rust-owned hypermedia product: forms,
|
|
lists, keyed partial updates, server-verified actions, installability, offline or
|
|
host recovery from app-owned command/event/projection truth, and a few explicit
|
|
host capabilities such as share, haptics, clipboard, notifications, or file
|
|
picking. The payoff is fewer moving parts: no client component runtime, no native
|
|
UI abstraction, no plugin marketplace, and no hidden mobile state graph. req:
|
|
ceremony/006 req: examples/011
|
|
|
|
Do not use hemx mobile as a replacement for apps whose product center is heavy
|
|
native UI, games, deep OS integration, camera-heavy capture/editing, complex
|
|
native navigation stacks, background services, or complex multi-device offline
|
|
sync. For those, keep hemx as a server/API surface or use an explicit native
|
|
shell/island where the browser should not own the interaction. req: host/002
|
|
|
|
For the in-repository exemplar:
|
|
|
|
```sh
|
|
cargo run -p hemx-xtask -- workout dev
|
|
cargo run -p hemx-xtask -- workout test
|
|
cargo run -p hemx-xtask -- workout build
|
|
cargo run -p hemx-xtask -- workout mobile-release
|
|
cargo run -p hemx-xtask -- workout mobile-verify
|
|
cargo run -p hemx-xtask -- workout doctor
|
|
```
|
|
|
|
`workout mobile-release` builds `target/release/hemx-workout-example` and writes
|
|
a release kit under `target/hemx-mobile/workout` by default:
|
|
|
|
```text
|
|
target/hemx-mobile/workout/
|
|
release-manifest.json
|
|
BLOCKERS.md
|
|
android/twa-release.json
|
|
android/README.md
|
|
ios/webview-release.json
|
|
ios/README.md
|
|
```
|
|
|
|
Use `workout mobile-verify` as the store-readiness product gate: it runs the
|
|
Workout product tests, then checks the generated kit and release binary. It
|
|
fails on broken app value/recovery/host-boundary tests, a non-HTTPS production
|
|
origin, missing/inconsistent Android or iOS metadata, or external
|
|
toolchain/signing blockers that were not written into the manifest and
|
|
`BLOCKERS.md`. Use `workout doctor` when you only want to see missing external
|
|
inputs.
|
|
|
|
## Production configuration
|
|
|
|
Set these explicitly for a real app release:
|
|
|
|
```sh
|
|
HEMX_WORKOUT_APP_ID=com.example.workout
|
|
HEMX_WORKOUT_APP_NAME="Workout Copilot"
|
|
HEMX_WORKOUT_VERSION=1.0.0
|
|
HEMX_WORKOUT_ORIGIN=https://workout.example.com
|
|
HEMX_WORKOUT_ANDROID_PACKAGE=com.example.workout
|
|
HEMX_WORKOUT_IOS_BUNDLE_ID=com.example.workout
|
|
HEMX_WORKOUT_MOBILE_OUT=target/hemx-mobile/workout
|
|
```
|
|
|
|
The generated manifest records:
|
|
|
|
- app identity and version;
|
|
- the production HTTPS origin used by Android and iOS shells;
|
|
- `target/release/hemx-workout-example` as the server artifact;
|
|
- the exact runtime asset path and SHA-256 digest served by the same release;
|
|
- `asset-integrity.tsv` as a plain-text integrity receipt for mobile shell review;
|
|
- cache policy: release-scoped HTML/CSS/runtime assets only;
|
|
- offline truth policy: app-owned command/event/projection records, never DOM
|
|
patches or UI effect payloads;
|
|
- host capability policy: Android and iOS shell metadata declare share/haptics and
|
|
the same denied, timeout, unavailable, and error result kinds handled by app
|
|
code before UI effects;
|
|
- environment/secrets boundary: public shell config in the kit, signing secrets
|
|
outside the repo;
|
|
- rollback: redeploy the previous server binary and rebuild store artifacts from
|
|
the previous shell metadata/signing inputs. req: local/001 req: host/002
|
|
|
|
## Android and iOS artifacts
|
|
|
|
The command writes release-ready metadata, not store-signed binaries. That is the
|
|
honest boundary: producing `.aab`/`.apk` and `.ipa` files requires vendor SDKs,
|
|
signing credentials, and store accounts on the release machine.
|
|
|
|
Android blockers are reported when the Android SDK/JDK/signing key or Play
|
|
Console submission target are not visible. iOS blockers are reported when Xcode,
|
|
the Apple signing team, or the App Store Connect submission team are not visible.
|
|
These blockers are copied into `BLOCKERS.md` so the release kit can be reviewed
|
|
without guessing what is still external. req: examples/006
|
|
|
|
## What this does not add
|
|
|
|
This is not a `hemx-mobile` framework, sync layer, client database, or native UI
|
|
runtime. The mobile shells load the production Workout web app and route host
|
|
capabilities such as share/haptics through the typed host boundary before UI
|
|
effects are produced; denied, timeout, unavailable, and error cases share the
|
|
same host result shape. req: host/002 req: local/002
|