whiskers.git / mise.toml
mise.tomlannotatedmise.tomlsource269 lines · 11.4 KB · raw
1# The toolchain, the environment and the tasks of this repository: the one place
2# every tool version lives. Nothing here needs nix, nix-darwin or root:
3#
4#     mise trust && mise install      the toolchain (a C compiler and git must exist)
5#     mise tasks                      what can be run
6#     mise run check                  the fast gates
7#     mise run android:debug          the APK
8#
9# `tools/check-versions.sh` (part of `mise run check`) fails when a version
10# written elsewhere (Cargo.toml's wasm-bindgen pin, the Gradle build's SDK
11# levels, hk.pkl's hk release) differs from the one here. The nix flake only
12# wraps this file; it holds no version of its own.
13min_version = "2026.10.0"
14
15[settings]
16# `[daemons]` below needs it.
17experimental = true
18
19[tools]
20# The Rust core, the service and the wasm Workers. Android targets for the app,
21# wasm for the website and the backend Worker.
22rust = { version = "1.99.0", profile = "minimal", components = "rustfmt,clippy", targets = "aarch64-linux-android,armv7-linux-androideabi,x86_64-linux-android,wasm32-unknown-unknown" }
23"cargo:cargo-ndk" = "4.1.2"
24# The wasm-bindgen CLI must equal the `wasm-bindgen` crate pinned in web/Cargo.toml and
25# backend/worker/Cargo.toml (checked by tools/check-versions.sh).
26"cargo:wasm-bindgen-cli" = "0.2.127"
27# worker-build links OpenSSL on Linux. A system copy (and pkg-config) is not assumed: the same OpenSSL from
28# conda-forge is installed first and linked from where mise put it.
29"conda:openssl" = "3.5.9"
30"cargo:worker-build" = { version = "0.8.6", depends = ["conda:openssl"], install_env = { OPENSSL_DIR = "{{ env.MISE_DATA_DIR | default(value=xdg_data_home ~ '/mise') }}/installs/conda-openssl/3.5.9", RUSTFLAGS = "-C link-arg=-Wl,-rpath,{{ env.MISE_DATA_DIR | default(value=xdg_data_home ~ '/mise') }}/installs/conda-openssl/3.5.9/lib" } }
31
32# The Android app. No Gradle wrapper by design: the version is here.
33java = "temurin-21.0.12+101"
34gradle = "9.7.1"
35# The SDK's command-line tools; the platform, build tools and NDK are installed by
36# `mise run android:sdk` at the levels in [vars].
37android-sdk = "13.0"
38
39# The website (web/) and the backend Worker.
40node = "24.20.0"
41"npm:wrangler" = "4.129.0"
42# celld, the self-hosted Durable Objects host, for the backend Worker.
43"github:denoland/celld" = "0.6.1"
44ffmpeg = "9.0.2"
45resvg = "0.48.1"
46
47# The jdx tools: git hooks, supervised dev daemons, secrets, CLI specs.
48hk = "2.5.0"
49pkl = "0.32.1"
50pitchfork = "2.29.0"
51fnox = "1.36.0"
52usage = "6.12.0"
53
54[vars]
55# Android SDK levels. build.gradle.kts must agree (tools/check-versions.sh).
56android_platform = "37.0"
57android_build_tools = "36.0.0"
58android_ndk = "29.0.14206865"
59# Only for `mise run android:emulator`.
60android_emulator_image = "system-images;android-35;google_apis;x86_64"
61
62[env]
63# Where the SDK and NDK are (the android-sdk tool sets ANDROID_HOME to its own directory;
64# tasks put the SDK packages there). Scripts read these from the environment and never
65# assume mise or nix; export them yourself if you bring your own SDK.
66ANDROID_NDK_HOME = { value = "{{ env.ANDROID_HOME }}/ndk/{{ vars.android_ndk }}", tools = true }
67WRANGLER_SEND_METRICS = "false"
68# hk runs its hooks through mise, so the hook finds hk, pkl and cargo whatever the shell of the commit.
69HK_MISE = "1"
70
71# What the tasks read, all optional. Secrets are never put in this file: whiskersd's keys come
72# from the environment, or from fnox (see fnox.toml and tools/README.md).
73#   WHISKERS_ADDR            address whiskersd listens on (private network address, not 0.0.0.0)
74#   WHISKERS_MODEL_URL       the model gateway whiskersd proxies to (required by whiskersd)
75#   WHISKERS_HOST            default service address baked into an APK (-Pwhiskers.host)
76#   WHISKERS_VERSION_NAME / WHISKERS_VERSION_CODE / WHISKERS_APPLICATION_ID / WHISKERS_ABIS
77#                            the other -Pwhiskers.* properties (see android/README.md)
78#   WHISKERS_KEYSTORE, WHISKERS_KEYSTORE_PASSWORD, WHISKERS_KEY_ALIAS, WHISKERS_KEY_PASSWORD
79#                            sign with your own key (all four or none)
80#   WHISKERS_SERVICE         address preflight checks (host:port)
81#   ADB, ANDROID_SERIAL, WHISKERS_ANDROID_USER   see tools/install-android.sh
82WHISKERS_ADDR = { value = "127.0.0.1:47900" }
83
84# ---------------------------------------------------------------- setup
85
86[tasks.submodules]
87description = "Fetch the git submodules (third-party/jevcrates)"
88run = "git submodule update --init --recursive"
89
90[tasks."hooks:install"]
91description = "Install the git hooks (hk.pkl): check-private and clippy before a commit, the web tests before a push"
92run = "hk install"
93
94[tasks."android:sdk"]
95description = "Install the Android platform, build tools, platform tools and NDK at the levels in [vars]"
96run = "tools/android-sdk.sh"
97env = { WHISKERS_ANDROID_PLATFORM = "{{ vars.android_platform }}", WHISKERS_ANDROID_BUILD_TOOLS = "{{ vars.android_build_tools }}", WHISKERS_ANDROID_NDK = "{{ vars.android_ndk }}" }
98
99[tasks."android:emulator"]
100description = "Also install the emulator and an x86_64 system image (large)"
101depends = ["android:sdk"]
102run = 'yes | sdkmanager --install emulator "{{ vars.android_emulator_image }}"'
103
104# ---------------------------------------------------------------- checks
105
106[tasks."check-private"]
107description = "Fail if a term from .private-terms appears in a tracked file"
108run = "tools/check-private.sh"
109
110[tasks."check-versions"]
111description = "Fail if a version written outside mise.toml differs from it"
112run = "tools/check-versions.sh"
113
114[tasks."check-wasm"]
115description = "The portable crates (ports, service, conformance) still build for wasm32 (a Worker)"
116run = "cargo check --target wasm32-unknown-unknown -p whiskers-ports -p whiskers-service -p whiskers-conformance"
117
118[tasks.clippy]
119description = "cargo clippy over the core workspace (an error-level lint fails; warnings are shown)"
120run = "cargo clippy --workspace"
121
122[tasks."test:core"]
123description = "The Rust workspace's tests"
124run = "cargo test --workspace"
125
126[tasks."test:web"]
127description = "The website's tests (its own workspace, natively)"
128run = "cargo test --workspace --manifest-path web/Cargo.toml"
129
130[tasks."test:backend"]
131description = "The backend Worker's pure tests, natively"
132dir = "backend/worker"
133run = "cargo test"
134
135[tasks.test]
136description = "All native tests: the core and the website"
137depends = ["test:core", "test:web"]
138
139[tasks.check]
140description = "The fast gates: private terms, versions, wasm build, clippy, core and website tests"
141depends = ["check-private", "check-versions", "check-wasm", "clippy", "test"]
142
143[tasks.preflight]
144description = "Check everything the app talks to (WHISKERS_SERVICE=host:port or pass it as an argument)"
145run = "tools/preflight.sh"
146
147# ---------------------------------------------------------------- android
148
149[tasks.core]
150description = "Build the Rust core for the tablet and generate the Kotlin bindings and the art"
151depends = ["android:sdk"]
152run = "tools/build-core.sh"
153
154[tasks."android:debug"]
155description = "Build the debug APK (optional -Pwhiskers.* from the WHISKERS_* variables)"
156depends = ["android:sdk"]
157run = "tools/android-gradle.sh :app:assembleDebug"
158
159[tasks."android:lite"]
160description = "Build the debug APK without the offline voice (about 90 MB smaller)"
161depends = ["android:sdk"]
162run = "tools/android-gradle.sh :app:assembleDebug -Pwhiskers.offlineVoice=false"
163
164[tasks."android:test"]
165description = "The app's JVM unit tests"
166depends = ["android:sdk"]
167run = "tools/android-gradle.sh :app:testDebugUnitTest"
168
169[tasks."android:record-goldens"]
170description = "Rewrite the screenshot goldens (look at the PNGs afterwards)"
171depends = ["android:sdk"]
172run = "tools/android-gradle.sh :app:recordRoborazziDebug"
173
174# record and verify in one Gradle invocation race, so they are separate tasks.
175[tasks."android:verify-goldens"]
176description = "Fail if a screenshot drifted from its golden"
177depends = ["android:sdk"]
178run = "tools/android-gradle.sh :app:verifyRoborazziDebug"
179
180[tasks."android:fetch-voices"]
181description = "Fetch the offline speech model and the offline neural voice (Gradle does this before a build)"
182run = ["tools/fetch-speech-model.sh", "tools/fetch-offline-voice.sh"]
183
184[tasks."android:install"]
185description = "Install the debug APK on a connected device and start it"
186depends = ["android:sdk"]
187run = "tools/install-android.sh"
188
189[tasks."android:inspect"]
190description = "Print who signed an APK, what it asks for and which ABIs it carries"
191depends = ["android:sdk"]
192run = "tools/inspect-apk.sh"
193
194[tasks."release:apks"]
195description = "Build the three release APKs into ~/whiskers-release/<version>/ (arguments: version code)"
196depends = ["android:sdk"]
197run = "tools/release-apks.sh"
198
199# ---------------------------------------------------------------- the service
200
201[tasks.whiskersd]
202description = "Run the service in the foreground (secrets from fnox when it is set up, else the environment)"
203run = "tools/with-secrets.sh cargo run --release -p whiskersd -- \"$WHISKERS_ADDR\""
204
205[tasks."whiskersd:service"]
206description = "Run the service as a transient systemd user service that comes back if it dies"
207run = "cargo build --release -p whiskersd && tools/with-secrets.sh tools/run-whiskersd.sh"
208
209# ---------------------------------------------------------------- the website
210
211[tasks."web:dev"]
212description = "The website under wrangler dev --local on http://localhost:8788/ (builds the Worker and the link preview)"
213dir = "web/worker"
214run = "wrangler dev --local --port 8788"
215
216[tasks."web:preview"]
217description = "Rebuild the link preview's PNG and MP4"
218run = "web/tools/preview"
219
220[tasks."web:check-preview"]
221description = "Check the link preview the way a scraper would"
222run = "web/tools/check-preview"
223
224# ---------------------------------------------------------------- the backend Worker
225
226[tasks."backend:build"]
227description = "Build the backend Worker (build/index.js and index_bg.wasm), the one build both hosts run"
228dir = "backend/worker"
229run = "worker-build --release"
230
231[tasks."backend:celld"]
232description = "The backend Worker on celld, self-hosted, on port 8801 (state in backend/worker/.celld/dev)"
233dir = "backend/worker"
234run = "celld dev . --port 8801"
235
236[tasks."backend:wrangler"]
237description = "The backend Worker under wrangler dev --local on port 8802"
238dir = "backend/worker"
239run = "wrangler dev --local --port 8802 --persist-to .wrangler/state"
240
241[tasks."backend:host"]
242description = "Start, stop or restart one backend host: native, wrangler or celld (arguments: host action)"
243run = "backend/worker/tools/host"
244
245[tasks."backend:probe"]
246description = "Show what each backend host says to a few odd requests (argument: native, wrangler or celld)"
247run = "backend/worker/tools/probe"
248
249[tasks."backend:crosscheck"]
250description = "Run the whole comparison of the three backend hosts (see backend/README.md)"
251run = "backend/worker/tools/crosscheck"
252
253# ---------------------------------------------------------------- daemons
254
255# Supervised by pitchfork, started and stopped through mise. `mise run dev` starts both and
256# waits until they answer; `mise daemons status`, `mise daemons logs`, `mise daemons stop`.
257[daemons.whiskersd]
258run = "exec tools/with-secrets.sh target/release/whiskersd \"$WHISKERS_ADDR\""
259init = "cargo build --release -p whiskersd"
260ready_port = 47900
261
262[daemons.site]
263run = "cd web/worker && exec wrangler dev --local --port 8788"
264ready_http = "http://127.0.0.1:8788/"
265
266[tasks.dev]
267description = "Start the dev daemons (whiskersd and the website) and wait until they answer"
268daemons = true
269run = "echo 'whiskersd on '\"$WHISKERS_ADDR\"', the website on http://localhost:8788/; mise daemons stop to stop them'"