# The image every step in .woodpecker runs in. It builds the desktop app, the # Windows installer and the Android APK, and holds the tools that publish them. # # Build it in Woodpecker: open a pipeline, click "Deploy", and set the deploy # target to `builder`. Or locally: # # podman build -t mtgc-builder ci/builder # # Debian 12 on purpose: a Linux binary needs at least the glibc it was built # against, so the oldest libraries we can build on reach the most machines. # Versions match a working dev machine; bump them here, not in the scripts. FROM debian:bookworm ENV RUST_VERSION=1.97.1 \ TAURI_CLI_VERSION=2.11.4 \ CARGO_XWIN_VERSION=0.23.1 \ NODE_VERSION=22.14.0 \ REPREPRO_VERSION=5.4.4 \ REPREPRO_SHA256=5b028f79183659d441d1b340deb88341a7f29335ae7370eff4b3c094fbe90bc4 \ FDROIDSERVER_VERSION=2.4.5 \ CMDLINE_TOOLS_BUILD=13114758 \ NDK_VERSION=28.2.13676358 \ ANDROID_PLATFORM=android-36 \ ANDROID_BUILD_TOOLS=36.0.0 ENV RUSTUP_HOME=/opt/rustup \ CARGO_HOME=/opt/cargo \ ANDROID_HOME=/opt/android-sdk \ PATH=/opt/cargo/bin:/opt/node/bin:/opt/android-sdk/cmdline-tools/latest/bin:/usr/lib/llvm-14/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # System packages. The first group builds the app, then Windows, then the # package repos and Android. libgpgme and below only build reprepro. RUN apt-get update \ && apt-get install -y --no-install-recommends \ build-essential ca-certificates curl file git pkg-config unzip xz-utils \ libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libssl-dev \ clang lld llvm nsis \ createrepo-c dpkg-dev gnupg rpm \ openjdk-17-jdk-headless python3-venv \ automake libarchive-dev libbz2-dev libdb-dev libgpgme-dev liblzma-dev libzstd-dev zlib1g-dev \ && rm -rf /var/lib/apt/lists/* # reprepro: bookworm's 5.3 can't read a repo that keeps several versions of a # package, which deb-publish.sh's `Limit:` makes, so use the dev machine's. RUN curl -fsSL -o /tmp/reprepro.tar.gz \ "https://salsa.debian.org/debian/reprepro/-/archive/reprepro-$REPREPRO_VERSION/reprepro-reprepro-$REPREPRO_VERSION.tar.gz" \ && echo "$REPREPRO_SHA256 /tmp/reprepro.tar.gz" | sha256sum -c - \ && mkdir /tmp/reprepro \ && tar xzf /tmp/reprepro.tar.gz -C /tmp/reprepro --strip-components=1 \ && cd /tmp/reprepro \ && autoreconf -fi \ && ./configure --with-libbz2 --with-liblzma --with-libarchive \ && make -j"$(nproc)" install \ && rm -rf /tmp/reprepro /tmp/reprepro.tar.gz # Rust RUN curl -fsSL -o /tmp/rustup-init https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init \ && chmod +x /tmp/rustup-init \ && /tmp/rustup-init -y --no-modify-path --profile minimal --default-toolchain "$RUST_VERSION" \ --target x86_64-pc-windows-msvc \ --target aarch64-linux-android \ --target armv7-linux-androideabi \ --target i686-linux-android \ --target x86_64-linux-android \ && rm /tmp/rustup-init \ && cargo install --locked tauri-cli --version "$TAURI_CLI_VERSION" \ && cargo install --locked cargo-xwin --version "$CARGO_XWIN_VERSION" \ && rm -rf /opt/cargo/registry /opt/cargo/git # Node RUN mkdir /opt/node \ && curl -fsSL "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ | tar xJ -C /opt/node --strip-components=1 # Android SDK and NDK RUN mkdir -p /opt/android-sdk/cmdline-tools \ && curl -fsSL -o /tmp/cmdline-tools.zip \ "https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_TOOLS_BUILD}_latest.zip" \ && unzip -q /tmp/cmdline-tools.zip -d /tmp/cmdline-tools \ && mv /tmp/cmdline-tools/cmdline-tools /opt/android-sdk/cmdline-tools/latest \ && rm -rf /tmp/cmdline-tools /tmp/cmdline-tools.zip \ && (yes || true) | sdkmanager --licenses >/dev/null \ && sdkmanager --install \ "platforms;$ANDROID_PLATFORM" \ "build-tools;$ANDROID_BUILD_TOOLS" \ "platform-tools" \ "ndk;$NDK_VERSION" >/dev/null # fdroidserver RUN python3 -m venv /opt/fdroidserver \ && /opt/fdroidserver/bin/pip install --no-cache-dir "fdroidserver==$FDROIDSERVER_VERSION" \ && ln -s /opt/fdroidserver/bin/fdroid /usr/local/bin/fdroid # Steps run as uid 1000, the owner of the release directories on the NAS. It # gets an account because keytool and Gradle ask who they're running as, and # the SDK because Gradle may add a build-tools package it wants. RUN useradd --uid 1000 --create-home builder \ && chown -R 1000:1000 /opt/android-sdk