lmjtfy.git / mise.toml
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 dev                    the Worker under wrangler dev, supervised by pitchfork
8#
9# `tools/check-versions.sh` (part of `mise run check`) fails when a version
10# written elsewhere (Cargo.toml's wasm-bindgen pin, hk.pkl's hk release) differs
11# from the one here. The nix flake only wraps this file; it holds no version of its own.
12min_version = "2026.10.0"
13
14[settings]
15# `[daemons]` below needs it.
16experimental = true
17
18[tools]
19# The Worker is Rust compiled to WebAssembly.
20rust = { version = "1.99.0", profile = "minimal", components = "rustfmt,clippy", targets = "wasm32-unknown-unknown" }
21# The wasm-bindgen CLI must equal the `wasm-bindgen` crate pinned in Cargo.toml
22# (checked by tools/check-versions.sh). worker-build downloads wasm-opt and esbuild itself.
23"cargo:wasm-bindgen-cli" = "0.2.127"
24# worker-build links OpenSSL on Linux. A system copy (and pkg-config) is not assumed: the same OpenSSL from
25# conda-forge is installed first and linked from where mise put it.
26"conda:openssl" = "3.5.9"
27"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" } }
28
29# wrangler runs the Worker locally and deploys it.
30node = "24.20.0"
31"npm:wrangler" = "4.129.0"
32
33# The jdx tools: git hooks, supervised dev daemons, secrets.
34hk = "2.5.0"
35pkl = "0.32.1"
36pitchfork = "2.29.0"
37fnox = "1.36.0"
38
39[env]
40WRANGLER_SEND_METRICS = "false"
41
42# What the owner's tasks read, never written here. Declared, without values, in fnox.toml;
43# tools/with-secrets.sh puts them in a command's environment through fnox when it is set up,
44# and a command simply finds them in the environment otherwise.
45#   CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID   wrangler (Workers AI has no local emulation)
46#   LMJTFY_TYPESAFE_API_KEY                       the Jev key, for the dev server
47#   LMJTFY_GITHUB_TOKEN                           the clone proxy's read-only token
48
49# ---------------------------------------------------------------- setup
50
51[tasks.submodules]
52description = "Fetch the git submodules (third-party/jevcrates and the pictures)"
53run = "git submodule update --init --recursive"
54
55[tasks."hooks:install"]
56description = "Install the git hooks (hk.pkl): clippy before a commit, the tests before a push"
57run = "hk install"
58
59# ---------------------------------------------------------------- checks
60
61[tasks."check-versions"]
62description = "Fail if a version written outside mise.toml differs from it"
63run = "tools/check-versions.sh"
64
65# The tree is not formatted by rustfmt, so formatting is not checked. Warnings are shown, not fatal.
66[tasks.clippy]
67description = "cargo clippy over the workspace (warnings are shown, an error-level lint fails)"
68run = "cargo clippy --workspace --all-targets"
69
70[tasks.test]
71description = "Everything but the Worker's I/O, natively (cargo test --workspace --lib)"
72run = "cargo test --workspace --lib"
73
74[tasks.check]
75description = "The fast gates: versions and the tests"
76depends = ["check-versions", "test"]
77
78# ---------------------------------------------------------------- build and run
79
80[tasks.build]
81description = "Build the Worker for WebAssembly into apps/lmjtfy/build (worker-build --release)"
82dir = "apps/lmjtfy"
83run = "worker-build --release"
84
85[tasks."dev:preflight"]
86description = "Fail at once, with the reason, if the Cloudflare credentials the dev server needs are missing"
87run = "tools/with-secrets.sh tools/wrangler --preflight"
88
89[tasks.dev]
90description = "Start the dev server (http://localhost:8787/) under pitchfork and wait until it answers"
91depends = ["dev:preflight"]
92run = ["mise daemons start worker", "echo 'the Worker is on http://localhost:8787/; mise daemons logs worker, mise daemons stop worker'"]
93
94# ---------------------------------------------------------------- the owner's tasks
95# These need the owner's Cloudflare account: CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in the
96# environment (or in fnox, see fnox.toml). Anyone else can deploy their own copy the same way.
97
98[tasks."deploy-staging"]
99description = "OWNER: deploy the staging Worker (https://staging.lmjtfy.fun, behind the owner's login)"
100run = ["mise daemons stop worker", "tools/with-secrets.sh tools/wrangler deploy --env staging"]
101
102[tasks.deploy]
103description = "OWNER: deploy the site and code.lmjtfy.fun (extra arguments go to wrangler: -- --var GIT_REDIRECT:off rolls the redirect back)"
104run = ["mise daemons stop worker", "tools/with-secrets.sh tools/wrangler deploy"]
105
106# ---------------------------------------------------------------- daemons
107
108# Supervised by pitchfork, started and stopped through mise. wrangler rebuilds the Worker itself when a
109# source changes; its watcher can start two builds off one save, which collide in build/ and take wrangler
110# down (2026-10-02). tools/wrangler-dev reports any exit pitchfork did not ask for as a failure, and
111# `retry` starts it again (five times, then `mise run dev` fails instead of waiting for ever).
112[daemons.worker]
113run = "exec tools/with-secrets.sh tools/wrangler-dev"
114ready_http = { url = "http://127.0.0.1:8787/", timeout = "10m" }
115retry = 5