CI adaption

AuthorKonata <konata@posteo.jp>
Date
Commitc843875fe746da0478af607b4d8c8f933665702f
Parent95eaa67
1 file changed, 40 insertions(+), 27 deletions(-)
▾M.hearthforge-ci.toml
@@ -1,11 +1,13 @@
# Steps run in file order, in one container, sharing /ci/build.
# Alpine, so the published binary is the same static musl build the
# Containerfile ships.
image = "docker.io/rust:1.90-bookworm"
image = "docker.io/rust:1.90-alpine3.22"
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"]
# busybox ash, which does support `set -o pipefail`.
shell = ["/bin/sh", "-c"]
# CARGO_TARGET_DIR must stay outside clone_project_to: the cache volume is
# mounted before the clone runs, and git refuses to clone into a non-empty
@@ -18,46 +20,49 @@ export CARGO_TARGET_DIR=/ci/cache/target
timeout = 5400
memory_limit = "6g"
# Caps are a safety valve against unbounded growth, not a budget: hitting one
# costs a full rebuild. Sized roughly twice the working set. A local target
# holding all three profiles measures 26G, of which debug is 22G.
cache = [
"/usr/local/cargo/registry",
"/ci/cache/target",
"/root/.bun/install/cache",
{ path = "/ci/cache/target", max_size = "20g" },
{ path = "/usr/local/cargo/registry", max_size = "4g" },
{ path = "/root/.bun/install/cache", max_size = "2g" },
]
[on]
push = ["master"]
tag = true
# bun publishes no musl installer, so take the binary from the official image.
# This mirrors the Containerfile's COPY --from. The -alpine tag is required:
# the glibc build will not run here. bun also needs libstdc++, which setup
# installs before anything executes it.
[[copy]]
image = "docker.io/oven/bun:1.4.0-alpine"
from = "/usr/local/bin/bun"
to = "/usr/local/bin"
[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."
# ── toolchain ────────────────────────────────────────────────────────────────
# binaryen supplies wasm-opt, so trunk does not download its own.
[setup]
# binaryen supplies wasm-opt. Without it trunk downloads a glibc build that
# cannot run on musl. just comes from apk here, so no install script.
[[steps]]
name = "setup"
timeout = 900
run_sh = """
apt-get update -qq
apt-get install -y --no-install-recommends binaryen unzip
apk add --no-cache musl-dev binaryen just curl libstdc++
# The official rust images use rustup's minimal profile, so rustfmt and
# clippy are absent. `just lint` needs both.
rustup component add rustfmt clippy
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}"
# The gnu build, not the musl one: the image is Debian.
url="https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz"
url="https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-musl.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
@@ -68,30 +73,38 @@ cargo fmt --version && cargo clippy --version
"""
# ── checks ───────────────────────────────────────────────────────────────────
[lint]
# Formatting and clippy findings are reported, not gated. The CI toolchain is
# 1.90 and local machines run newer, so clippy disagrees across versions.
[[steps]]
name = "lint"
run_sh = "cd project && just lint"
warn_on_fail = true
# `just test` covers server and api-types only, hence the extra web run.
[test]
[[steps]]
name = "test"
run_sh = "cd project && just test && cargo test -p web"
# ── build ────────────────────────────────────────────────────────────────────
[build]
[[steps]]
name = "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]
[[steps]]
name = "e2e"
run_sh = "cd project && cargo test -p server --features embedded"
# ── release ──────────────────────────────────────────────────────────────────
[release]
[[steps]]
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"
"dist/filebrowser-ng-${CI_COMMIT_TAG}-x86_64-linux-musl"
"""
publish_gzip = ["/ci/build/project/dist/"]