I have been enjoying learning some Rust and some Macroquad game development via Olle Wreede’s tutorial (Swedish only so far, sorry!). When I sent some pull requests towards the tutorial I lacked a deployed version attached to the PR. I decided to add that, and my goto for such things is Netlify. However, the tutorial is authored with mdBook, and there doesn’t seem to be a straightforward way to get Netlify to build this.

I figured out a bit of a roundabout way, but before I describe the solution, let’s look at what the problem is about.
I want to solve it with Netlify’s build system, without involving a second CI/CD for it.
Netlify has
rustupandcargopre-installed, but the support seems to be designed to build Rust apps and/or libraries. At least to get caching of the dependencies.The book in question depends not only on
mdbook, but also onmdbook-quiz,mdbook-catppuccin, andmdbook-admonish.Doing a straight
cargo install mdbook mdbook-quiz mdbook-catppuccintakes an awful lot of time. Like 5 minutes. I don’t have that kind of patience waiting for feedback.
I did find a closed
issue, with a solution that people seemed happy with, on Netlify
about support for mdBook. It was about downloading an
mdbook binary. I imagine it is quicker than
cargo install, but I would still have to install the
plugins and it seemed a bit messy to download individual binaries for
each.
My solution was to “trick” Netlify to cache the dependencies by
creating a dummy Rust app in the repository, and add the mdBook build
tools to build-dependencies of that dummy app. Then to run
mdbook build with the directory of these binaries on the
PATH.
Here follows the relevant files to make this work. Please note that
the repository has the actual book project in a subdirectory,
macroquad-introduction-book.
Netlify needs a Rust toolchain file,
macroquad-introduction-book/rust-toolchain.toml:
[toolchain]
channel = "stable"To get the caching of the dependencies I need a cargo configuration
in macroquad-introduction-book/Cargo.toml:
# Dummy project to cache book build dependencies with Netlify
[package]
name = "macroquad-introduktion"
version = "0.1.0"
edition = "2021"
[build-dependencies]
mdbook = "*"
mdbook-quiz = "*"
mdbook-catppuccin = "*"
mdbook-admonish = "*"The cargo command needs either a
\[\[bin\]\] configuration (or so it tells me, and I am too
noobish to understand how it works) or a main.rs file. I
chose the latter,
macroquad-introduction-book/src/main.rs:
// Dummy project to cache book build dependencies with Netlify
fn main() {
println!("Hello, world!");
}We also need to configure Netlify. I like to do it via
netlify.toml, rather than clicking around in the web
UI:
[build]
base = "macroquad-introduction-book"
publish = "book"
command = "cargo build --release && export
PATH=\"$PATH:$(pwd)/target/release/build\" && mdbook build"
[context.master]
command = "cargo build --release && export
PATH=\"$PATH:$(pwd)/target/release/build\" && mdbook build"
[context.branch-deploy]
command = "cargo build --release && export
PATH=\"$PATH:$(pwd)/target/release/build\" && mdbook build"In this configuration, the important part is the
command. We use cargo build to build the dummy
app and force the caching of the mdbook tools. Then we
place the build directory on the path before we run
mdbook build. This way the mdbook command is
found and the plugins will be found as well.
And there it is. With the caching, subsequent builds of the book goes from 5+ minutes to 15 seconds. 15 seconds is an OK wait time for the result of a pull request to build, I think.