build: a clone compiles before the frontend is built

rust-embed refused to derive without `web/dist`, so on a fresh clone
`cargo check`, `cargo test` and rust-analyzer failed with a derive error that
did not say what was missing. With `allow_missing` the embed is empty until
the frontend is built, and the handler gives the answer it already had for
that case, "frontend not built". The release build is unchanged once
`web/dist` is there, which `make build`, the Dockerfile and CI all see to.
This commit is contained in:
nvrl committed 2026-10-21 12:35:59 +02:00
1 parent 0e0d21506e
commit a59ba4af1b
4 files changed
+14 -9

No files matched your search

+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2 - uses: oven-sh/setup-bun@v2
# The binary embeds web/dist, so nothing compiles before the frontend is built. # Built first so the binary under test embeds the app it ships with.
- name: frontend - name: frontend
working-directory: web working-directory: web
run: | run: |
+2 -2
View File
@@ -91,8 +91,8 @@ make dev-web # vite dev server on :4243, proxying /api to :4242
``` ```
In debug builds the binary reads `web/dist` from disk, so `cargo run` alone also In debug builds the binary reads `web/dist` from disk, so `cargo run` alone also
works once the frontend has been built at least once — and not before: the works once the frontend has been built at least once. Before that it compiles,
binary embeds `web/dist`, so a fresh clone builds the frontend first. tests and runs the API, and answers every page with "frontend not built".
`make check` runs what CI runs: format, clippy, the tests, svelte-check, and a `make check` runs what CI runs: format, clippy, the tests, svelte-check, and a
check that the generated wiki pages are current. The wiki is written in check that the generated wiki pages are current. The wiki is written in
+7 -5
View File
@@ -7,9 +7,11 @@ make dev-api # cargo run, serving the API on :4242
make dev-web # vite on :4243, proxying /api to :4242 make dev-web # vite on :4243, proxying /api to :4242
``` ```
Open <http://127.0.0.1:4243>. The Rust build embeds `web/dist`, so build the Open <http://127.0.0.1:4243>. The release binary embeds `web/dist`, and a
frontend once (`cd web && bun install && bun run build`) before the first debug build reads it from disk, so build the frontend once
`cargo build`; a debug build reads `web/dist` from disk after that. (`cd web && bun install && bun run build`) for `cargo run` alone to serve the
app. Without it the Rust side still compiles and tests, and the pages answer
"frontend not built".
Point `WORKSPACE_DATA_DIR` at a throwaway directory while trying things, so the Point `WORKSPACE_DATA_DIR` at a throwaway directory while trying things, so the
real data stays out of it. real data stays out of it.
@@ -57,8 +59,8 @@ block at the bottom.
`.github/workflows/ci.yml` runs on every push and pull request: `.github/workflows/ci.yml` runs on every push and pull request:
- **rust**: builds the frontend (the binary embeds it), then format, clippy - **rust**: builds the frontend, so the tests see the app the binary ships,
and the tests; then format, clippy and the tests;
- **web**: svelte-check; - **web**: svelte-check;
- **docs**: checks that the generated wiki pages are up to date and that every - **docs**: checks that the generated wiki pages are up to date and that every
link between the pages resolves. link between the pages resolves.
+4 -1
View File
@@ -5,9 +5,12 @@ use axum::{
use rust_embed::Embed; use rust_embed::Embed;
/// The built Svelte app. In debug builds rust-embed reads from disk, so a /// The built Svelte app. In debug builds rust-embed reads from disk, so a
/// `vite build --watch` next to `cargo run` is enough for iteration. /// `vite build --watch` next to `cargo run` is enough for iteration. A clone
/// that has not built the frontend yet still compiles, tests and checks; it
/// serves the "frontend not built" answer below until it has.
#[derive(Embed)] #[derive(Embed)]
#[folder = "$CARGO_MANIFEST_DIR/web/dist"] #[folder = "$CARGO_MANIFEST_DIR/web/dist"]
#[allow_missing = true]
struct Assets; struct Assets;
pub async fn handler(uri: Uri) -> Response { pub async fn handler(uri: Uri) -> Response {