# HearthForge CI for filebrowser-ng. # Steps run in file order, in one container, sharing /ci/build. # The steps call the `just` recipes that already live in the repo. image = "docker.io/rust:1.90-bookworm" work_dir = "/ci/build" clone_project_to = "/ci/build/project" # The rust image ships bash. /bin/sh is dash and has no `pipefail`. shell = ["/bin/bash", "-c"] # shell_setup is prepended to every step, so this exports the target dir once. # It must sit outside the clone path: a cache volume mounted under # /ci/build/project would create that directory, and `git clone` refuses to # clone into a directory that is not empty. shell_setup = """ set -euo pipefail export CARGO_TARGET_DIR=/ci/cache/target """ timeout = 5400 memory_limit = "6g" # Without these every run recompiles the whole dependency tree from scratch. cache = [ "/usr/local/cargo/registry", "/ci/cache/target", "/root/.bun/install/cache", ] [on] push = ["master"] tag = true [variables] [variables.TRUNK_VERSION] default = "0.21.14" description = "Trunk release that builds the wasm frontend. Matches the Containerfile." [variables.BUN_VERSION] default = "1.4.0" description = "Bun release that bundles web/cm6.js. Matches the Containerfile." # ── diagnose ───────────────────────────────────────────────────────────────── # TEMPORARY. HearthForge clones the repo before the first step and discards # the result, so a failed clone is invisible. This step reproduces it and # prints why. Delete it once the clone works. [diagnose] run_sh = """ set +e echo "cwd: $PWD" echo "--- /ci/build ---" ls -la /ci/build echo "--- repo mount ---" ls -la /hearthforge-repo.git git -C /hearthforge-repo.git rev-parse --is-bare-repository echo "--- ci vars ---" echo "SOURCE=${CI_TRIGGER_SOURCE}" echo "SHA=${CI_COMMIT_SHA}" echo "BRANCH=${CI_COMMIT_BRANCH}" echo "TAG=${CI_COMMIT_TAG}" echo "--- manual clone ---" git clone /hearthforge-repo.git /ci/build/project echo "clone rc=$?" ls -la /ci/build/project | head exit 0 """ # ── toolchain ──────────────────────────────────────────────────────────────── # The rust image has cargo only. The build also needs the wasm target, just, # bun and trunk. binaryen supplies wasm-opt, so trunk does not download one. [setup] timeout = 900 run_sh = """ apt-get update -qq apt-get install -y --no-install-recommends binaryen unzip rustup target add wasm32-unknown-unknown curl -fsSL https://just.systems/install.sh | bash -s -- --to /usr/local/bin # BUN_INSTALL controls the prefix, so the binary lands in /usr/local/bin. curl -fsSL https://bun.sh/install | BUN_INSTALL=/usr/local bash -s "bun-v${BUN_VERSION}" # Pinned and checksum-checked, same as the Containerfile. This is the gnu # build, not the musl one, because the image is Debian. url="https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz" curl -fsSL -o /tmp/trunk.tar.gz "$url" curl -fsSL "$url.sha256" | awk '{print $1 " /tmp/trunk.tar.gz"}' | sha256sum -c - tar xzf /tmp/trunk.tar.gz -C /usr/local/bin rm -f /tmp/trunk.tar.gz just --version && bun --version && trunk --version """ # ── checks ─────────────────────────────────────────────────────────────────── # `just lint` is cargo fmt --check plus clippy with warnings denied. [lint] run_sh = "cd project && just lint" # `just test` covers server and api-types. The web crate has its own tests. [test] run_sh = "cd project && just test && cargo test -p web" # ── build ──────────────────────────────────────────────────────────────────── # `just build` bundles CodeMirror, builds the frontend, stages it into # server/dist and links the single binary with the `embedded` feature. [build] timeout = 2400 run_sh = "cd project && just build" publish_file = ["/ci/cache/target/release/filebrowser-ng"] # `just e2e` would rebuild the frontend. The build step already staged # server/dist, so run the embedded suite against it directly. [e2e] run_sh = "cd project && cargo test -p server --features embedded" # ── release ────────────────────────────────────────────────────────────────── # Tags only. Ships the binary under a versioned name. [release] run_if = 'test -n "${CI_COMMIT_TAG}"' run_sh = """ cd project install -Dm755 "${CARGO_TARGET_DIR}/release/filebrowser-ng" \ "dist/filebrowser-ng-${CI_COMMIT_TAG}-x86_64-linux-gnu" """ publish_gzip = ["/ci/build/project/dist/"]