The Rust toolchain was unpinned on both sides, and the two sides had drifted five releases apart: the CI builder image ships rustc 1.97.1, the development machine was on 1.92.0. Clippy's lint set and rustfmt's output both change between releases, so a green `cargo clippy` / `cargo fmt --check` locally said nothing about CI and vice versa — which is the reason the clippy gate could not be trusted enough to turn on. src-tauri/rust-toolchain.toml pins channel 1.97.1 with the rustfmt and clippy components. Deliberately no `targets` list: that would make rustup fetch the Android and Windows std libraries on every plain `cargo test`, including on machines that never cross-compile. The image already has them. Dockerfile.builder installs that exact version instead of "latest stable at rebuild time", and prints rustc/clippy versions so a mismatch is visible in the build log. The pin only becomes authoritative once the image is rebuilt and pushed (scripts/build-builder-image.sh). Until then CI still runs whatever rustc the current image has, and if that is not 1.97.1 rustup will download the pinned toolchain at job time — a toolchain install in CI, which CLAUDE.md forbids. Both files carry that warning next to the version. Note: the clippy step in .gitea/workflows/build-and-test.yml is left advisory here; tightening it wants a warning count measured on 1.97.1 first.
158 lines
6.6 KiB
Docker
158 lines
6.6 KiB
Docker
# JellyTau Builder Image
|
|
# Pre-built image with all dependencies for building, testing, and packaging:
|
|
# - Android APK (SDK/NDK), Linux desktop (deb/rpm),
|
|
# - Windows cross via the official Tauri path: MSVC target + cargo-xwin + NSIS
|
|
# Arch packages build in a separate archlinux image (Dockerfile.arch) since
|
|
# makepkg is Arch-specific.
|
|
# Push to your registry: docker build -f Dockerfile.builder -t gitea.tourolle.paris/dtourolle/jellytau-builder:latest .
|
|
|
|
FROM ubuntu:24.04
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive \
|
|
ANDROID_HOME=/opt/android-sdk \
|
|
NDK_VERSION=27.0.11902837 \
|
|
SDK_VERSION=36 \
|
|
BUILD_TOOLS_VERSION=35.0.0 \
|
|
RUST_BACKTRACE=1 \
|
|
PATH="/root/.bun/bin:/root/.cargo/bin:$PATH" \
|
|
CARGO_HOME=/root/.cargo
|
|
|
|
# Install system dependencies
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
curl \
|
|
wget \
|
|
git \
|
|
ca-certificates \
|
|
unzip \
|
|
jq \
|
|
openjdk-17-jdk-headless \
|
|
pkg-config \
|
|
libssl-dev \
|
|
libclang-dev \
|
|
llvm-dev \
|
|
# Tauri Linux desktop dependencies (needed for `cargo test` on the host target)
|
|
libglib2.0-dev \
|
|
libgtk-3-dev \
|
|
libwebkit2gtk-4.1-dev \
|
|
libjavascriptcoregtk-4.1-dev \
|
|
libsoup-3.0-dev \
|
|
librsvg2-dev \
|
|
libayatana-appindicator3-dev \
|
|
# mpv player library (linked via libmpv-sys)
|
|
libmpv-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install Node.js 20.x from NodeSource
|
|
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
|
|
apt-get install -y --no-install-recommends nodejs && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install Bun
|
|
RUN curl -fsSL https://bun.sh/install | bash && \
|
|
ln -s /root/.bun/bin/bun /usr/local/bin/bun
|
|
|
|
# Install Rust using rustup, pinned to an exact release.
|
|
#
|
|
# 🔴 RUST_VERSION must equal `channel` in src-tauri/rust-toolchain.toml.
|
|
#
|
|
# The two are a pair. rust-toolchain.toml is what makes a developer's `cargo
|
|
# clippy` agree with CI's; this line is what makes the image already contain that
|
|
# toolchain. If they drift, rustup silently downloads the pinned version the
|
|
# first time cargo runs inside a job — a toolchain install at job time, which
|
|
# CLAUDE.md's "🔴 CI installs no system tools" rule forbids (and which costs
|
|
# ~1min plus a network dependency on every build).
|
|
#
|
|
# 🔴 Changing this line does NOT change CI on its own: the image must be
|
|
# rebuilt and pushed (`scripts/build-builder-image.sh`) before the new pin is
|
|
# authoritative. Bump rust-toolchain.toml and this line together, rebuild, push,
|
|
# then merge.
|
|
#
|
|
# Was: `sh -s -- -y` (latest stable, whatever it happened to be on rebuild day).
|
|
ENV RUST_VERSION=1.97.1
|
|
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
|
sh -s -- -y --profile minimal --default-toolchain "$RUST_VERSION" && \
|
|
. $HOME/.cargo/env && \
|
|
rustup default "$RUST_VERSION" && \
|
|
rustup target add aarch64-linux-android && \
|
|
rustup target add armv7-linux-androideabi && \
|
|
rustup target add x86_64-linux-android && \
|
|
rustup component add rustfmt clippy && \
|
|
rustc --version && \
|
|
cargo clippy --version
|
|
|
|
# Setup Android SDK
|
|
RUN mkdir -p $ANDROID_HOME && \
|
|
mkdir -p /root/.android && \
|
|
echo '### User Sources for `android` cmd line tool ###' > /root/.android/repositories.cfg && \
|
|
echo 'count=0' >> /root/.android/repositories.cfg
|
|
|
|
# Download and setup Android Command Line Tools
|
|
RUN wget -q https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O /tmp/cmdline-tools.zip && \
|
|
unzip -q /tmp/cmdline-tools.zip -d $ANDROID_HOME && \
|
|
rm /tmp/cmdline-tools.zip && \
|
|
mkdir -p $ANDROID_HOME/cmdline-tools/latest && \
|
|
mv $ANDROID_HOME/cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest/ 2>/dev/null || true
|
|
|
|
# Accept all SDK licenses up front so Gradle can install/use components non-interactively
|
|
RUN yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --sdk_root=$ANDROID_HOME --licenses > /dev/null
|
|
|
|
# Install Android SDK components (must match the compileSdk/targetSdk in the generated Gradle project)
|
|
RUN $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --sdk_root=$ANDROID_HOME \
|
|
"platform-tools" \
|
|
"platforms;android-$SDK_VERSION" \
|
|
"build-tools;$BUILD_TOOLS_VERSION" \
|
|
"ndk;$NDK_VERSION" \
|
|
--channel=0 2>&1 | grep -v "Warning" || true
|
|
|
|
# Set NDK environment variable
|
|
ENV NDK_HOME=$ANDROID_HOME/ndk/$NDK_VERSION
|
|
|
|
# Gradle distribution. `tauri android init` regenerates gen/android with a
|
|
# wrapper pointing at services.gradle.org, so every Android job would otherwise
|
|
# download ~130MB of Gradle at build time — slow, and a hard failure when the
|
|
# CDN hiccups ("Unexpected end of file from server"). Ship the distribution in
|
|
# the image instead; scripts/sync-android-sources.sh repoints the regenerated
|
|
# wrapper at this local copy. Keep GRADLE_VERSION in sync with the version
|
|
# Tauri's generated wrapper requests.
|
|
ENV GRADLE_VERSION=8.14.3 \
|
|
GRADLE_HOME=/opt/gradle/gradle-8.14.3
|
|
RUN mkdir -p /opt/gradle/dist && \
|
|
wget -q "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" \
|
|
-O "/opt/gradle/dist/gradle-${GRADLE_VERSION}-bin.zip" && \
|
|
unzip -q "/opt/gradle/dist/gradle-${GRADLE_VERSION}-bin.zip" -d /opt/gradle && \
|
|
"$GRADLE_HOME/bin/gradle" --version
|
|
ENV PATH="$GRADLE_HOME/bin:$PATH"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Desktop packaging tools — kept in a trailing layer ON PURPOSE so that adding
|
|
# or changing a packaging tool doesn't invalidate the expensive apt/rust/Android
|
|
# layers above (a tool tweak becomes a ~1-2 min rebuild, not ~15). Covers Linux
|
|
# (deb/rpm) and Windows cross (MSVC via cargo-xwin + NSIS).
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
# Linux desktop packaging: rpmbuild for the .rpm bundle (deb needs nothing extra)
|
|
rpm \
|
|
file \
|
|
# Windows cross-compile (official Tauri path: MSVC target via cargo-xwin).
|
|
# clang provides clang-cl, the MSVC-compatible C compiler cc-rs uses to build
|
|
# C deps (bundled sqlite, ring, ...); lld = linker; llvm = llvm-lib/ar etc;
|
|
# nsis = installer generator.
|
|
clang \
|
|
lld \
|
|
llvm \
|
|
nsis \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
# Ubuntu's clang package ships clang but NOT the clang-cl alias that cc-rs
|
|
# invokes for MSVC targets. clang-cl is the same binary in MSVC-compat mode,
|
|
# so provide it as a symlink.
|
|
&& ln -sf /usr/bin/clang /usr/local/bin/clang-cl
|
|
|
|
# Windows rust target + cargo-xwin (downloads the MSVC CRT/SDK at build time).
|
|
RUN . $HOME/.cargo/env && \
|
|
rustup target add x86_64-pc-windows-msvc && \
|
|
cargo install --locked cargo-xwin
|
|
|
|
WORKDIR /app
|
|
|
|
ENTRYPOINT ["/bin/bash"]
|