.hearthforge-ci.toml
⎇
Raw
1# HearthForge CI for filebrowser-ng.
2# Steps run in file order, in one container, sharing /ci/build.
3# The steps call the `just` recipes that already live in the repo.
4
5image = "docker.io/rust:1.90-bookworm"
6work_dir = "/ci/build"
7clone_project_to = "/ci/build/project"
8
9# The rust image ships bash. /bin/sh is dash and has no `pipefail`.
10shell = ["/bin/bash", "-c"]
11
12# shell_setup is prepended to every step, so this exports the target dir once.
13# It must sit outside the clone path: a cache volume mounted under
14# /ci/build/project would create that directory, and `git clone` refuses to
15# clone into a directory that is not empty.
16shell_setup = """
17set -euo pipefail
18export CARGO_TARGET_DIR=/ci/cache/target
19"""
20
21timeout = 5400
22memory_limit = "6g"
23
24# Without these every run recompiles the whole dependency tree from scratch.
25cache = [
26 "/usr/local/cargo/registry",
27 "/ci/cache/target",
28 "/root/.bun/install/cache",
29]
30
31[on]
32push = ["master"]
33tag = true
34
35[variables]
36
37 [variables.TRUNK_VERSION]
38 default = "0.21.14"
39 description = "Trunk release that builds the wasm frontend. Matches the Containerfile."
40
41 [variables.BUN_VERSION]
42 default = "1.4.0"
43 description = "Bun release that bundles web/cm6.js. Matches the Containerfile."
44
45# ── toolchain ────────────────────────────────────────────────────────────────
46# The rust image has cargo only. The build also needs the wasm target, just,
47# bun and trunk. binaryen supplies wasm-opt, so trunk does not download one.
48[setup]
49timeout = 900
50run_sh = """
51apt-get update -qq
52apt-get install -y --no-install-recommends binaryen unzip
53
54rustup target add wasm32-unknown-unknown
55
56curl -fsSL https://just.systems/install.sh | bash -s -- --to /usr/local/bin
57
58# BUN_INSTALL controls the prefix, so the binary lands in /usr/local/bin.
59curl -fsSL https://bun.sh/install | BUN_INSTALL=/usr/local bash -s "bun-v${BUN_VERSION}"
60
61# Pinned and checksum-checked, same as the Containerfile. This is the gnu
62# build, not the musl one, because the image is Debian.
63url="https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz"
64curl -fsSL -o /tmp/trunk.tar.gz "$url"
65curl -fsSL "$url.sha256" | awk '{print $1 " /tmp/trunk.tar.gz"}' | sha256sum -c -
66tar xzf /tmp/trunk.tar.gz -C /usr/local/bin
67rm -f /tmp/trunk.tar.gz
68
69just --version && bun --version && trunk --version
70"""
71
72# ── checks ───────────────────────────────────────────────────────────────────
73# `just lint` is cargo fmt --check plus clippy with warnings denied.
74[lint]
75run_sh = "cd project && just lint"
76
77# `just test` covers server and api-types. The web crate has its own tests.
78[test]
79run_sh = "cd project && just test && cargo test -p web"
80
81# ── build ────────────────────────────────────────────────────────────────────
82# `just build` bundles CodeMirror, builds the frontend, stages it into
83# server/dist and links the single binary with the `embedded` feature.
84[build]
85timeout = 2400
86run_sh = "cd project && just build"
87publish_file = ["/ci/cache/target/release/filebrowser-ng"]
88
89# `just e2e` would rebuild the frontend. The build step already staged
90# server/dist, so run the embedded suite against it directly.
91[e2e]
92run_sh = "cd project && cargo test -p server --features embedded"
93
94# ── release ──────────────────────────────────────────────────────────────────
95# Tags only. Ships the binary under a versioned name.
96[release]
97run_if = 'test -n "${CI_COMMIT_TAG}"'
98run_sh = """
99cd project
100install -Dm755 "${CARGO_TARGET_DIR}/release/filebrowser-ng" \
101 "dist/filebrowser-ng-${CI_COMMIT_TAG}-x86_64-linux-gnu"
102"""
103publish_gzip = ["/ci/build/project/dist/"]
104