Build every artifact in a pinned image, not on my laptop
Two builder images, because the jobs genuinely need two distributions: Ubuntu for the tests, the Linux bundle and the Android APK, and Arch for the .pkg.tar.zst, since makepkg is Arch-specific. Both are built from this repo (NFR-12) and pinned by tag in the workflows, so a Dockerfile change only reaches CI once it has been pushed. libdbus-1-dev is not incidental in the Ubuntu image: btleplug's Linux backend is bluez-async over the dbus crate, so without it the workspace does not build at all. The per-commit Android job is a cargo check, not an APK. The full signed build is ~15 minutes and runs only on tags; a one-minute check catches what actually breaks — the JNI shim, droidplug, and any desktop-only API that has crept into a shared crate. Two invariants a compiler cannot see are checked there too, because both fail silently: the app builds, installs, launches, and finds no trainer. The JNI symbol in android.rs is matched by the runtime by name, so renaming the Kotlin package compiles fine and simply never initialises btleplug; and gen/ must stay untracked or the sync script quietly becomes optional. The Android versionCode carries a 1000 floor. `tauri android init` writes 1000 for 0.1.0 today, so anyone holding a locally built APK already has that number installed, and a bare major/minor/patch code would be 100 — a downgrade, which Android refuses outright. The fmt check is advisory for now. The tree predates this workflow and `cargo fmt --all` currently rewrites ~2000 lines across 28 files; making it a gate here would mean landing a repo-wide reformat as a side effect of adding CI. Run fmt in its own commit, then drop the continue-on-error. The two clippy warnings that stood between the tree and a real `-D warnings` gate are fixed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# BikeControl builder image.
|
||||
#
|
||||
# One image that can do every job CI asks of it:
|
||||
# - `cargo test` / `clippy` on the host target, which means the *Linux BLE*
|
||||
# stack must be present: btleplug talks to BlueZ over D-Bus, so libdbus is a
|
||||
# hard build dependency, not an optional extra.
|
||||
# - the Tauri desktop bundle (deb / AppImage), which needs the webkit2gtk set.
|
||||
# - the Android APK: SDK, NDK, JDK, and the three Android Rust targets.
|
||||
#
|
||||
# Build and push:
|
||||
# docker build -f Dockerfile.builder -t gitea.tourolle.paris/dtourolle/bikecontrol-builder:latest .
|
||||
# docker push gitea.tourolle.paris/dtourolle/bikecontrol-builder:latest
|
||||
# or run scripts/build-builder-image.sh.
|
||||
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
ANDROID_HOME=/opt/android-sdk \
|
||||
ANDROID_SDK_ROOT=/opt/android-sdk \
|
||||
NDK_VERSION=27.0.11902837 \
|
||||
SDK_VERSION=36 \
|
||||
BUILD_TOOLS_VERSION=35.0.0 \
|
||||
RUST_BACKTRACE=1 \
|
||||
CARGO_HOME=/root/.cargo \
|
||||
PATH="/root/.cargo/bin:$PATH"
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
ca-certificates \
|
||||
unzip \
|
||||
jq \
|
||||
file \
|
||||
pkg-config \
|
||||
openjdk-17-jdk-headless \
|
||||
libssl-dev \
|
||||
libclang-dev \
|
||||
llvm-dev \
|
||||
# BLE on the host target: btleplug's Linux backend is bluez-async over the
|
||||
# `dbus` crate, which links against libdbus-1. Without this the workspace
|
||||
# does not build at all — `crates/ble` is not optional.
|
||||
libdbus-1-dev \
|
||||
# Tauri v2 desktop (needed for `cargo test`/`clippy` on the host target and
|
||||
# for the deb/AppImage bundle).
|
||||
libglib2.0-dev \
|
||||
libgtk-3-dev \
|
||||
libwebkit2gtk-4.1-dev \
|
||||
libjavascriptcoregtk-4.1-dev \
|
||||
libsoup-3.0-dev \
|
||||
librsvg2-dev \
|
||||
libayatana-appindicator3-dev \
|
||||
# AppImage bundling reaches for these at bundle time.
|
||||
fuse3 \
|
||||
desktop-file-utils \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Node 20 for the Vite/Svelte frontend. The UI is plain npm (ui/package-lock.json
|
||||
# is the lockfile CI installs from), so no bun here.
|
||||
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/*
|
||||
|
||||
# Rust, with every target the release job builds for.
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal && \
|
||||
. "$CARGO_HOME/env" && \
|
||||
rustup component add rustfmt clippy && \
|
||||
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
|
||||
|
||||
# The Tauri CLI as a cargo subcommand. The frontend package.json deliberately
|
||||
# does not carry @tauri-apps/cli — the shell is a cargo workspace member, so the
|
||||
# CLI belongs to the toolchain, not to the UI's dependency tree.
|
||||
RUN . "$CARGO_HOME/env" && cargo install tauri-cli --locked --version "^2"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Android SDK / NDK.
|
||||
RUN mkdir -p "$ANDROID_HOME" /root/.android && \
|
||||
printf '### User Sources for `android` cmd line tool ###\ncount=0\n' > /root/.android/repositories.cfg && \
|
||||
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/cmdline-tools/"* "$ANDROID_HOME/cmdline-tools/latest/" && \
|
||||
rmdir "$ANDROID_HOME/cmdline-tools/cmdline-tools"
|
||||
|
||||
# Licences up front so Gradle never blocks on a prompt in CI.
|
||||
RUN yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --sdk_root="$ANDROID_HOME" --licenses > /dev/null
|
||||
|
||||
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
|
||||
|
||||
ENV NDK_HOME=$ANDROID_HOME/ndk/$NDK_VERSION \
|
||||
ANDROID_NDK_HOME=$ANDROID_HOME/ndk/$NDK_VERSION \
|
||||
ANDROID_NDK_ROOT=$ANDROID_HOME/ndk/$NDK_VERSION \
|
||||
PATH="/opt/android-sdk/platform-tools:/opt/android-sdk/cmdline-tools/latest/bin:$PATH"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENTRYPOINT ["/bin/bash"]
|
||||
Reference in New Issue
Block a user