Merge pull request 'feat(ci): add persistent pre-baked Docker builder images' (#21) from feat/persistent-ci-builders into master
Reviewed-on: #21
This commit is contained in:
commit
bff11dc847
24
.docker/Dockerfile.linux-amd64
Normal file
24
.docker/Dockerfile.linux-amd64
Normal file
@ -0,0 +1,24 @@
|
||||
# Pre-baked builder for Linux amd64 Tauri releases.
|
||||
# All system dependencies are installed once here; CI jobs skip apt-get entirely.
|
||||
# Rebuild when: Rust toolchain version changes, webkit2gtk/gtk major version changes,
|
||||
# or Node.js major version changes. Tag format: rust<VER>-node<VER>
|
||||
FROM rust:1.88-slim
|
||||
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y -qq --no-install-recommends \
|
||||
libwebkit2gtk-4.1-dev \
|
||||
libssl-dev \
|
||||
libgtk-3-dev \
|
||||
libayatana-appindicator3-dev \
|
||||
librsvg2-dev \
|
||||
patchelf \
|
||||
pkg-config \
|
||||
curl \
|
||||
perl \
|
||||
jq \
|
||||
git \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN rustup target add x86_64-unknown-linux-gnu
|
||||
45
.docker/Dockerfile.linux-arm64
Normal file
45
.docker/Dockerfile.linux-arm64
Normal file
@ -0,0 +1,45 @@
|
||||
# Pre-baked cross-compiler for Linux arm64 Tauri releases (runs on Linux amd64).
|
||||
# Bakes in: amd64 cross-toolchain, arm64 multiarch dev libs, Node.js, and Rust.
|
||||
# This image takes ~15 min to build but is only rebuilt when deps change.
|
||||
# Rebuild when: Rust toolchain version, webkit2gtk/gtk major version, or Node.js changes.
|
||||
# Tag format: rust<VER>-node<VER>
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Step 1: amd64 host tools and cross-compiler
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y -qq --no-install-recommends \
|
||||
curl git gcc g++ make patchelf pkg-config perl jq \
|
||||
gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Step 2: Enable arm64 multiarch. Ubuntu uses ports.ubuntu.com for arm64 to avoid
|
||||
# binary-all index conflicts with the amd64 archive.ubuntu.com mirror.
|
||||
RUN dpkg --add-architecture arm64 \
|
||||
&& sed -i 's|^deb http://archive.ubuntu.com|deb [arch=amd64] http://archive.ubuntu.com|g' /etc/apt/sources.list \
|
||||
&& sed -i 's|^deb http://security.ubuntu.com|deb [arch=amd64] http://security.ubuntu.com|g' /etc/apt/sources.list \
|
||||
&& printf '%s\n' \
|
||||
'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted universe multiverse' \
|
||||
'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted universe multiverse' \
|
||||
'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted universe multiverse' \
|
||||
> /etc/apt/sources.list.d/arm64-ports.list \
|
||||
&& apt-get update -qq \
|
||||
&& apt-get install -y -qq --no-install-recommends \
|
||||
libwebkit2gtk-4.1-dev:arm64 \
|
||||
libssl-dev:arm64 \
|
||||
libgtk-3-dev:arm64 \
|
||||
librsvg2-dev:arm64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Step 3: Node.js 22
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Step 4: Rust 1.88 with arm64 cross-compilation target
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
|
||||
--default-toolchain 1.88.0 --profile minimal --no-modify-path \
|
||||
&& /root/.cargo/bin/rustup target add aarch64-unknown-linux-gnu
|
||||
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
20
.docker/Dockerfile.windows-cross
Normal file
20
.docker/Dockerfile.windows-cross
Normal file
@ -0,0 +1,20 @@
|
||||
# Pre-baked cross-compiler for Windows amd64 Tauri releases (runs on Linux amd64).
|
||||
# All MinGW and Node.js dependencies are installed once here; CI jobs skip apt-get entirely.
|
||||
# Rebuild when: Rust toolchain version changes or Node.js major version changes.
|
||||
# Tag format: rust<VER>-node<VER>
|
||||
FROM rust:1.88-slim
|
||||
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y -qq --no-install-recommends \
|
||||
mingw-w64 \
|
||||
curl \
|
||||
nsis \
|
||||
perl \
|
||||
make \
|
||||
jq \
|
||||
git \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN rustup target add x86_64-pc-windows-gnu
|
||||
107
.gitea/workflows/build-images.yml
Normal file
107
.gitea/workflows/build-images.yml
Normal file
@ -0,0 +1,107 @@
|
||||
name: Build CI Docker Images
|
||||
|
||||
# Rebuilds the pre-baked builder images and pushes them to the local Gitea
|
||||
# container registry (172.0.0.29:3000).
|
||||
#
|
||||
# WHEN TO RUN:
|
||||
# - Automatically: whenever a Dockerfile under .docker/ changes on master.
|
||||
# - Manually: via workflow_dispatch (e.g. first-time setup, forced rebuild).
|
||||
#
|
||||
# ONE-TIME SERVER PREREQUISITE (run once on 172.0.0.29 before first use):
|
||||
# echo '{"insecure-registries":["172.0.0.29:3000"]}' \
|
||||
# | sudo tee /etc/docker/daemon.json
|
||||
# sudo systemctl restart docker
|
||||
#
|
||||
# Images produced:
|
||||
# 172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22
|
||||
# 172.0.0.29:3000/sarman/trcaa-windows-cross:rust1.88-node22
|
||||
# 172.0.0.29:3000/sarman/trcaa-linux-arm64:rust1.88-node22
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '.docker/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: build-ci-images
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
REGISTRY: 172.0.0.29:3000
|
||||
REGISTRY_USER: sarman
|
||||
|
||||
jobs:
|
||||
linux-amd64:
|
||||
runs-on: linux-amd64
|
||||
container:
|
||||
image: docker:24-cli
|
||||
options: -v /var/run/docker.sock:/var/run/docker.sock
|
||||
steps:
|
||||
- name: Checkout
|
||||
run: |
|
||||
apk add --no-cache git
|
||||
git init
|
||||
git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git
|
||||
git fetch --depth=1 origin "$GITHUB_SHA"
|
||||
git checkout FETCH_HEAD
|
||||
- name: Build and push linux-amd64 builder
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
echo "$RELEASE_TOKEN" | docker login $REGISTRY -u $REGISTRY_USER --password-stdin
|
||||
docker build \
|
||||
-t $REGISTRY/$REGISTRY_USER/trcaa-linux-amd64:rust1.88-node22 \
|
||||
-f .docker/Dockerfile.linux-amd64 .
|
||||
docker push $REGISTRY/$REGISTRY_USER/trcaa-linux-amd64:rust1.88-node22
|
||||
echo "✓ Pushed $REGISTRY/$REGISTRY_USER/trcaa-linux-amd64:rust1.88-node22"
|
||||
|
||||
windows-cross:
|
||||
runs-on: linux-amd64
|
||||
container:
|
||||
image: docker:24-cli
|
||||
options: -v /var/run/docker.sock:/var/run/docker.sock
|
||||
steps:
|
||||
- name: Checkout
|
||||
run: |
|
||||
apk add --no-cache git
|
||||
git init
|
||||
git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git
|
||||
git fetch --depth=1 origin "$GITHUB_SHA"
|
||||
git checkout FETCH_HEAD
|
||||
- name: Build and push windows-cross builder
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
echo "$RELEASE_TOKEN" | docker login $REGISTRY -u $REGISTRY_USER --password-stdin
|
||||
docker build \
|
||||
-t $REGISTRY/$REGISTRY_USER/trcaa-windows-cross:rust1.88-node22 \
|
||||
-f .docker/Dockerfile.windows-cross .
|
||||
docker push $REGISTRY/$REGISTRY_USER/trcaa-windows-cross:rust1.88-node22
|
||||
echo "✓ Pushed $REGISTRY/$REGISTRY_USER/trcaa-windows-cross:rust1.88-node22"
|
||||
|
||||
linux-arm64:
|
||||
runs-on: linux-amd64
|
||||
container:
|
||||
image: docker:24-cli
|
||||
options: -v /var/run/docker.sock:/var/run/docker.sock
|
||||
steps:
|
||||
- name: Checkout
|
||||
run: |
|
||||
apk add --no-cache git
|
||||
git init
|
||||
git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git
|
||||
git fetch --depth=1 origin "$GITHUB_SHA"
|
||||
git checkout FETCH_HEAD
|
||||
- name: Build and push linux-arm64 builder
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
echo "$RELEASE_TOKEN" | docker login $REGISTRY -u $REGISTRY_USER --password-stdin
|
||||
docker build \
|
||||
-t $REGISTRY/$REGISTRY_USER/trcaa-linux-arm64:rust1.88-node22 \
|
||||
-f .docker/Dockerfile.linux-arm64 .
|
||||
docker push $REGISTRY/$REGISTRY_USER/trcaa-linux-arm64:rust1.88-node22
|
||||
echo "✓ Pushed $REGISTRY/$REGISTRY_USER/trcaa-linux-arm64:rust1.88-node22"
|
||||
142
tests/unit/ciDockerBuilders.test.ts
Normal file
142
tests/unit/ciDockerBuilders.test.ts
Normal file
@ -0,0 +1,142 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const root = process.cwd();
|
||||
|
||||
const readFile = (rel: string) => readFileSync(path.resolve(root, rel), "utf-8");
|
||||
|
||||
// ─── Dockerfiles ─────────────────────────────────────────────────────────────
|
||||
|
||||
describe("Dockerfile.linux-amd64", () => {
|
||||
const df = readFile(".docker/Dockerfile.linux-amd64");
|
||||
|
||||
it("is based on the pinned Rust 1.88 slim image", () => {
|
||||
expect(df).toContain("FROM rust:1.88-slim");
|
||||
});
|
||||
|
||||
it("installs webkit2gtk 4.1 dev package", () => {
|
||||
expect(df).toContain("libwebkit2gtk-4.1-dev");
|
||||
});
|
||||
|
||||
it("installs Node.js 22 via NodeSource", () => {
|
||||
expect(df).toContain("nodesource.com/setup_22.x");
|
||||
expect(df).toContain("nodejs");
|
||||
});
|
||||
|
||||
it("pre-adds the x86_64 Linux Rust target", () => {
|
||||
expect(df).toContain("rustup target add x86_64-unknown-linux-gnu");
|
||||
});
|
||||
|
||||
it("cleans apt lists to keep image lean", () => {
|
||||
expect(df).toContain("rm -rf /var/lib/apt/lists/*");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Dockerfile.windows-cross", () => {
|
||||
const df = readFile(".docker/Dockerfile.windows-cross");
|
||||
|
||||
it("is based on the pinned Rust 1.88 slim image", () => {
|
||||
expect(df).toContain("FROM rust:1.88-slim");
|
||||
});
|
||||
|
||||
it("installs mingw-w64 cross-compiler", () => {
|
||||
expect(df).toContain("mingw-w64");
|
||||
});
|
||||
|
||||
it("installs nsis for Windows installer bundling", () => {
|
||||
expect(df).toContain("nsis");
|
||||
});
|
||||
|
||||
it("installs Node.js 22 via NodeSource", () => {
|
||||
expect(df).toContain("nodesource.com/setup_22.x");
|
||||
});
|
||||
|
||||
it("pre-adds the Windows GNU Rust target", () => {
|
||||
expect(df).toContain("rustup target add x86_64-pc-windows-gnu");
|
||||
});
|
||||
|
||||
it("cleans apt lists to keep image lean", () => {
|
||||
expect(df).toContain("rm -rf /var/lib/apt/lists/*");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Dockerfile.linux-arm64", () => {
|
||||
const df = readFile(".docker/Dockerfile.linux-arm64");
|
||||
|
||||
it("is based on Ubuntu 22.04 (Jammy)", () => {
|
||||
expect(df).toContain("FROM ubuntu:22.04");
|
||||
});
|
||||
|
||||
it("installs aarch64 cross-compiler", () => {
|
||||
expect(df).toContain("gcc-aarch64-linux-gnu");
|
||||
expect(df).toContain("g++-aarch64-linux-gnu");
|
||||
});
|
||||
|
||||
it("sets up arm64 multiarch via ports.ubuntu.com", () => {
|
||||
expect(df).toContain("dpkg --add-architecture arm64");
|
||||
expect(df).toContain("ports.ubuntu.com/ubuntu-ports");
|
||||
expect(df).toContain("jammy");
|
||||
});
|
||||
|
||||
it("installs arm64 webkit2gtk dev package", () => {
|
||||
expect(df).toContain("libwebkit2gtk-4.1-dev:arm64");
|
||||
});
|
||||
|
||||
it("installs Rust 1.88 with arm64 cross-compilation target", () => {
|
||||
expect(df).toContain("--default-toolchain 1.88.0");
|
||||
expect(df).toContain("rustup target add aarch64-unknown-linux-gnu");
|
||||
});
|
||||
|
||||
it("adds cargo to PATH via ENV", () => {
|
||||
expect(df).toContain('ENV PATH="/root/.cargo/bin:${PATH}"');
|
||||
});
|
||||
|
||||
it("installs Node.js 22 via NodeSource", () => {
|
||||
expect(df).toContain("nodesource.com/setup_22.x");
|
||||
});
|
||||
});
|
||||
|
||||
// ─── build-images.yml workflow ───────────────────────────────────────────────
|
||||
|
||||
describe("build-images.yml workflow", () => {
|
||||
const wf = readFile(".gitea/workflows/build-images.yml");
|
||||
|
||||
it("triggers on changes to .docker/ files on master", () => {
|
||||
expect(wf).toContain("- master");
|
||||
expect(wf).toContain("- '.docker/**'");
|
||||
});
|
||||
|
||||
it("supports manual workflow_dispatch trigger", () => {
|
||||
expect(wf).toContain("workflow_dispatch:");
|
||||
});
|
||||
|
||||
it("mounts the host Docker socket for image builds", () => {
|
||||
expect(wf).toContain("-v /var/run/docker.sock:/var/run/docker.sock");
|
||||
});
|
||||
|
||||
it("authenticates to the local Gitea registry before pushing", () => {
|
||||
expect(wf).toContain("docker login");
|
||||
expect(wf).toContain("--password-stdin");
|
||||
expect(wf).toContain("172.0.0.29:3000");
|
||||
});
|
||||
|
||||
it("builds and pushes all three platform images", () => {
|
||||
expect(wf).toContain("trcaa-linux-amd64:rust1.88-node22");
|
||||
expect(wf).toContain("trcaa-windows-cross:rust1.88-node22");
|
||||
expect(wf).toContain("trcaa-linux-arm64:rust1.88-node22");
|
||||
});
|
||||
|
||||
it("uses docker:24-cli image for build jobs", () => {
|
||||
expect(wf).toContain("docker:24-cli");
|
||||
});
|
||||
|
||||
it("runs all three build jobs on linux-amd64 runner", () => {
|
||||
const matches = wf.match(/runs-on: linux-amd64/g) ?? [];
|
||||
expect(matches.length).toBeGreaterThanOrEqual(3);
|
||||
});
|
||||
|
||||
it("uses RELEASE_TOKEN secret for registry auth", () => {
|
||||
expect(wf).toContain("secrets.RELEASE_TOKEN");
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user