.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# ── diagnose ─────────────────────────────────────────────────────────────────
46# TEMPORARY. HearthForge clones the repo before the first step and discards
47# the result, so a failed clone is invisible. This step reproduces it and
48# prints why. Delete it once the clone works.
49[diagnose]
50run_sh = """
51set +e
52echo "cwd: $PWD"
53echo "--- /ci/build ---"
54ls -la /ci/build
55echo "--- repo mount ---"
56ls -la /hearthforge-repo.git
57git -C /hearthforge-repo.git rev-parse --is-bare-repository
58echo "--- ci vars ---"
59echo "SOURCE=${CI_TRIGGER_SOURCE}"
60echo "SHA=${CI_COMMIT_SHA}"
61echo "BRANCH=${CI_COMMIT_BRANCH}"
62echo "TAG=${CI_COMMIT_TAG}"
63echo "--- manual clone ---"
64git clone /hearthforge-repo.git /ci/build/project
65echo "clone rc=$?"
66ls -la /ci/build/project | head
67exit 0
68"""
69
70# ── toolchain ────────────────────────────────────────────────────────────────
71# The rust image has cargo only. The build also needs the wasm target, just,
72# bun and trunk. binaryen supplies wasm-opt, so trunk does not download one.
73[setup]
74timeout = 900
75run_sh = """
76apt-get update -qq
77apt-get install -y --no-install-recommends binaryen unzip
78
79rustup target add wasm32-unknown-unknown
80
81curl -fsSL https://just.systems/install.sh | bash -s -- --to /usr/local/bin
82
83# BUN_INSTALL controls the prefix, so the binary lands in /usr/local/bin.
84curl -fsSL https://bun.sh/install | BUN_INSTALL=/usr/local bash -s "bun-v${BUN_VERSION}"
85
86# Pinned and checksum-checked, same as the Containerfile. This is the gnu
87# build, not the musl one, because the image is Debian.
88url="https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz"
89curl -fsSL -o /tmp/trunk.tar.gz "$url"
90curl -fsSL "$url.sha256" | awk '{print $1 " /tmp/trunk.tar.gz"}' | sha256sum -c -
91tar xzf /tmp/trunk.tar.gz -C /usr/local/bin
92rm -f /tmp/trunk.tar.gz
93
94just --version && bun --version && trunk --version
95"""
96
97# ── checks ───────────────────────────────────────────────────────────────────
98# `just lint` is cargo fmt --check plus clippy with warnings denied.
99[lint]
100run_sh = "cd project && just lint"
101
102# `just test` covers server and api-types. The web crate has its own tests.
103[test]
104run_sh = "cd project && just test && cargo test -p web"
105
106# ── build ────────────────────────────────────────────────────────────────────
107# `just build` bundles CodeMirror, builds the frontend, stages it into
108# server/dist and links the single binary with the `embedded` feature.
109[build]
110timeout = 2400
111run_sh = "cd project && just build"
112publish_file = ["/ci/cache/target/release/filebrowser-ng"]
113
114# `just e2e` would rebuild the frontend. The build step already staged
115# server/dist, so run the embedded suite against it directly.
116[e2e]
117run_sh = "cd project && cargo test -p server --features embedded"
118
119# ── release ──────────────────────────────────────────────────────────────────
120# Tags only. Ships the binary under a versioned name.
121[release]
122run_if = 'test -n "${CI_COMMIT_TAG}"'
123run_sh = """
124cd project
125install -Dm755 "${CARGO_TARGET_DIR}/release/filebrowser-ng" \
126 "dist/filebrowser-ng-${CI_COMMIT_TAG}-x86_64-linux-gnu"
127"""
128publish_gzip = ["/ci/build/project/dist/"]
129