#!/usr/bin/env bash # Builds the did.bot website: marketing pages, the docs/ prose, and the Rust # API documentation, into site/dist/ — ready to sync to a bucket, but this # script never touches AWS. scripts/publish-site.sh calls this and then does # the sync; a human or CI wanting a build with no credentials in scope calls # this directly. # # The inputs live in different places and this is the one place that knows # how they come together: # # 1. Marketing pages: site/src/pages/*.astro, built by `astro build`. # 2. The docs/ prose: copied and link-rewritten into site/src/content/docs/ # by site/scripts/prepare-docs.mjs (an npm prebuild step, so `npm run # build` alone already includes it — this script does not call it a # second time). # 3. The Rust API docs: `cargo doc`'s own output, copied into site/dist/api/ # after the Astro build so it is not clobbered by it. # 4. The home page's hero animation: crates/didbot-site-anim, compiled to # wasm by scripts/build-wasm.sh into site/public/wasm/, which Astro's # public/ passthrough then copies into the build untouched — so this # runs *before* `npm run build`, not after, unlike the doc mount above. # # Order matters for a fourth reason: site/tests/check-links.mjs asserts that # every page linking to /api/ finds something there, so the tests run last, # against the fully assembled tree, not against either half alone. # # Usage: scripts/build-site.sh [--skip-tests] set -euo pipefail cd "$(dirname "$0")/.." skip_tests=0 for arg in "$@"; do case "$arg" in --skip-tests) skip_tests=1 ;; *) echo "usage: $0 [--skip-tests]" >&2 exit 2 ;; esac done if ! command -v node >/dev/null 2>&1; then echo "build-site: node is required (site/ is an Astro project) and was not found" >&2 exit 1 fi if [ ! -d site/node_modules ]; then echo "build-site: site/node_modules is missing; run 'npm ci' inside site/ first" >&2 exit 1 fi echo "=== build-wasm: the home page's hero animation ===" >&2 scripts/build-wasm.sh echo "=== cargo doc: the Rust API documentation ===" >&2 # Same invocation prek.toml's cargo-doc hook uses, plus --all-features to # match it exactly; see prek.toml for why -D warnings is on (rustdocflags in # .cargo/config.toml) — a docs/*.md page that links at a Rust item which no # longer exists fails here rather than shipping a dead link. cargo doc --workspace --no-deps --all-features --document-private-items echo "=== astro build: marketing pages + docs/ prose ===" >&2 (cd site && npm run build) echo "=== mounting the API docs under /api/ ===" >&2 rm -rf site/dist/api mkdir -p site/dist/api cp -R target/doc/. site/dist/api/ # `cargo doc --workspace` writes one directory per crate and no root # index.html — there is no single "workspace" page to land on. `didbot` is # the facade crate (see crates/didbot/src/lib.rs, which include_str!s all of # docs/ into its own rustdoc), so it is the one worth landing on. cat >site/dist/api/index.html <<'EOF' Redirecting to the didbot crate docs

didbot/index.html

EOF if [ "$skip_tests" -eq 1 ]; then echo "build-site: --skip-tests passed; skipping site/tests" >&2 else echo "=== site/tests: build+link+markup+coverage checks ===" >&2 (cd site && npm test) fi echo "build-site: done — site/dist/ is ready to publish" >&2