ci / bun-nix (pull_request) Successful in 28s
ci / docs-drift (pull_request) Successful in 30s
ci / web (pull_request) Successful in 1m14s
ci / docs-site (pull_request) Successful in 1m15s
ci / rust-arm64 (pull_request) Successful in 2m11s
apple / swift (pull_request) Successful in 2m11s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
ci / rust (pull_request) Successful in 5m47s
android / android (pull_request) Successful in 6m31s
nix / flake (pull_request) Successful in 6m35s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 2m52s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 6m15s
The workflow-level pins closed the bootstrap path only. On the normal path the bun that gets vendored into the published .deb/.rpm comes from the builder image, and every image still installed it with the upstream installer piped into bash — so the script still chose bytes that ship to users. rust-ci and fedora-rpm now take the same pinned, SHA-256-checked bun-v1.3.14 asset the workflows do; arch-ci takes bun from pacman, which verifies package signatures. Same class, found while sweeping and worse than the cited sites: five images fetched sccache over a version-pinned URL with no integrity check at all. sccache is RUSTC_WRAPPER for every binary we ship — it can serve poisoned object files straight into a signed package, which is the position the review called the highest-leverage in a build. Download, verify against upstream's published sum, then extract. packaging/flatpak/build-flatpak.sh took flatpak-cargo-generator.py from a mutable master, the same fetch flatpak.yml just pinned; both now name the same commit and sum, so the local build and CI agree. Arch note: bun rides the existing -Syu transaction rather than a later layer. A separate layer resolves against the DB baked into the CACHED -Syu layer, and Arch mirrors carry only current versions, so a cache-hit rebuild months on would fail to fetch a package the stale snapshot names. None of this takes effect until the images are rebuilt: docker.yml's `builders` job keys on the git tree hash of ci/, so this re-keys the whole family. Until then the workflow bun pins sit behind `command -v bun ||` and short-circuit against the image's baked bun. rustup's own installer is left piped, as apple.yml already does — pinning rustup-init is a separate decision, and the same argument reaches every image at once.
97 lines
6.0 KiB
Docker
97 lines
6.0 KiB
Docker
# CI builder for the Rust workspace — Ubuntu 26.04 to match the dev/host boxes
|
|
# (FFmpeg 8 / libavcodec 62, PipeWire 1.6). Used by .gitea/workflows/ci.yml as the job
|
|
# container; rebuilt+pushed by .gitea/workflows/docker.yml.
|
|
#
|
|
# docker build -f ci/rust-ci.Dockerfile -t punktfunk-rust-ci ci
|
|
#
|
|
# The workspace links real system libs at build time (CLAUDE.md "Pinned crate facts"):
|
|
# FFmpeg, PipeWire, Opus, GL/EGL/GBM — and libcuda, which has no real driver here; the
|
|
# zerocopy path only needs the symbols at link time, so a driver userspace package plus a
|
|
# libcuda.so -> libcuda.so.1 symlink stands in for it (CI never executes the CUDA path).
|
|
FROM ubuntu:26.04
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
# toolchain + bindgen; nodejs runs the JS actions (checkout/cache); unzip extracts the pinned bun zip
|
|
build-essential clang libclang-dev pkg-config cmake git curl ca-certificates nodejs unzip \
|
|
# mold: the link-phase accelerator. Linking is the one thing sccache cannot cache, and this
|
|
# image relinks the whole workspace on every job. Wired via cargo-config-mold.toml below.
|
|
mold \
|
|
# ffmpeg-next 9, built against whatever libav* 26.04 ships (FFmpeg 8 / libavcodec 62 today).
|
|
# The crate major is a CEILING — ffmpeg-sys-next 9 spans libavcodec 56..63 — so this image does
|
|
# not need to move in lockstep with Arch's FFmpeg 9; it just links what the distro has.
|
|
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavfilter-dev \
|
|
libavdevice-dev \
|
|
# capture / audio / display stacks (+xkbcommon for the wlr input backend)
|
|
libpipewire-0.3-dev libopus-dev libwayland-dev libxkbcommon-dev \
|
|
# zerocopy link deps (GL via libglvnd, EGL, GBM)
|
|
libgl-dev libegl-dev libgbm-dev \
|
|
# punktfunk-client-linux (GTK4/libadwaita shell, SDL3 gamepads)
|
|
libgtk-4-dev libadwaita-1-dev libsdl3-dev \
|
|
# No libvulkan-dev: nothing in the workspace compiles or links against Vulkan (pyrowave-sys
|
|
# bindgens its own vendored headers, and both host and client reach Vulkan through ash, which
|
|
# dlopens the loader), so neither the build nor deb.yml's dpkg-shlibdeps ever asks for it.
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# bun — builds the punktfunk-web console in deb.yml (which runs the web build in THIS image).
|
|
# ci.yml's web/docs jobs use the oven/bun image instead, so this is only for the deb job.
|
|
#
|
|
# A PINNED release asset, checked by SHA-256 — never `curl https://bun.sh/install | bash`.
|
|
# build-web-deb.sh VENDORS this very binary into the punktfunk-web .deb, so the installer would be
|
|
# upstream code choosing bytes a signing job then publishes. ONE bun across the repo: same version,
|
|
# asset and sum as deb.yml and rpm.yml — bump BUN_VERSION and BUN_SHA together (the sums are in the
|
|
# release's SHASUMS256.txt). `-baseline` on purpose: it needs no AVX2, so the bun we ship starts on
|
|
# every x86-64 box — something the auto-detecting installer never promised, since it reads the
|
|
# BUILDER's CPU, not the user's.
|
|
ARG BUN_VERSION=1.3.14
|
|
ARG BUN_SHA=a063908ae08b7852ca10939bbdc6ceed3ddabce8fb9402dce83d65d73b36e6c7
|
|
RUN curl -fsSL -o /tmp/bun.zip \
|
|
"https://github.com/oven-sh/bun/releases/download/bun-v${BUN_VERSION}/bun-linux-x64-baseline.zip" \
|
|
&& echo "${BUN_SHA} /tmp/bun.zip" | sha256sum -c - \
|
|
&& unzip -q -o -j /tmp/bun.zip '*/bun' -d /tmp \
|
|
&& install -m0755 /tmp/bun /usr/local/bin/bun \
|
|
&& rm -f /tmp/bun.zip /tmp/bun \
|
|
&& bun --version
|
|
|
|
# libcuda link stub: the NVIDIA userspace library (no kernel module needed) provides
|
|
# every cuXxx symbol. On 26.04 the package already ships the libcuda.so dev symlink;
|
|
# -sf keeps this idempotent if a future package drops it again.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends libnvidia-compute-580-server \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& ln -sf libcuda.so.1 /usr/lib/x86_64-linux-gnu/libcuda.so \
|
|
&& test -e /usr/lib/x86_64-linux-gnu/libcuda.so.1
|
|
|
|
# Toolchain shared across CI users (jobs may run as different uids).
|
|
ENV RUSTUP_HOME=/usr/local/rustup \
|
|
CARGO_HOME=/usr/local/cargo \
|
|
PATH=/usr/local/cargo/bin:$PATH
|
|
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
|
| sh -s -- -y --no-modify-path --profile minimal \
|
|
--component rustfmt,clippy \
|
|
&& chmod -R a+w "$RUSTUP_HOME" "$CARGO_HOME" \
|
|
&& rustc --version && cargo clippy --version && cargo fmt --version
|
|
|
|
# Shared compile cache: jobs set RUSTC_WRAPPER=sccache (backend = RustFS S3 on the LAN,
|
|
# see .gitea/workflows — the env lives there so dev use of this image stays uncached).
|
|
# musl build: one static binary serves the Ubuntu and Fedora images alike.
|
|
# Checked by SHA-256, like the bun pin: sccache is RUSTC_WRAPPER, so it sits in front of every
|
|
# rustc invocation that produces a SHIPPED binary. Bump SCCACHE_VERSION and SCCACHE_SHA together —
|
|
# upstream publishes the sum as <asset>.tar.gz.sha256 next to the release asset.
|
|
ARG SCCACHE_VERSION=0.10.0
|
|
ARG SCCACHE_SHA=1fbb35e135660d04a2d5e42b59c7874d39b3deb17de56330b25b713ec59f849b
|
|
RUN curl -fsSL -o /tmp/sccache.tar.gz \
|
|
"https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-x86_64-unknown-linux-musl.tar.gz" \
|
|
&& echo "${SCCACHE_SHA} /tmp/sccache.tar.gz" | sha256sum -c - \
|
|
&& tar -xzf /tmp/sccache.tar.gz --wildcards --strip-components=1 -C /usr/local/bin '*/sccache' \
|
|
&& rm -f /tmp/sccache.tar.gz \
|
|
&& sccache --version
|
|
|
|
# Link x86_64 with mold (see the file's own header for the rustflags-precedence traps).
|
|
#
|
|
# The assertion is the point: an image carrying the flag but NOT the linker would fail every cargo
|
|
# invocation in every consuming job, which is a catastrophic way to find out that a base image
|
|
# renamed the package. `mold --version` fails the docker build instead, so nothing is pushed and
|
|
# `:latest` keeps pointing at the previous working image — consumers never see it.
|
|
COPY cargo-config-mold.toml /usr/local/cargo/config.toml
|
|
RUN mold --version && test -r /usr/local/cargo/config.toml
|