Skip to content

Commit 7e8a70b

Browse files
ci(linux): containerize cargo check and release build with cargo-chef
Replace bare-metal apt-get + toolchain setup with multi-stage Docker build using cargo-chef for dependency caching. Blacksmith's Docker layer caching (sticky disks) persists all layers across CI runs. Dockerfile stages: - deps: system packages, Rust nightly, Node.js, cargo-chef, tauri-cli - planner: cargo-chef prepare (recipe.json from manifests) - cook: cargo-chef cook for dev + release profiles - check: cargo check --workspace (test workflow target) - build: cargo tauri build + bundle (release workflow target) - artifacts: extract .deb and binary test.yml Linux build uses --target check via useblacksmith actions. release.yml Linux build uses --target artifacts with local output. macOS/Windows paths unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f6c1a14 commit 7e8a70b

3 files changed

Lines changed: 85 additions & 53 deletions

File tree

.github/workflows/release.yml

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,24 +128,26 @@ jobs:
128128
steps:
129129
- uses: actions/checkout@v6
130130

131-
- name: Setup Tauri build environment
132-
uses: ./.github/actions/setup-tauri-build
131+
- name: Setup Docker builder
132+
uses: useblacksmith/setup-docker-builder@v1
133133

134-
- name: Build binary
135-
env:
136-
GITHUB_TOKEN: ${{ github.token }}
137-
LASTFM_API_KEY: ${{ secrets.LASTFM_API_KEY }}
138-
LASTFM_API_SECRET: ${{ secrets.LASTFM_API_SECRET }}
139-
run: task ci:build TARGET=x86_64-unknown-linux-gnu
140-
141-
- name: Bundle
142-
run: task ci:bundle TARGET=x86_64-unknown-linux-gnu BUNDLES=deb
134+
- name: Build and bundle via Docker
135+
uses: useblacksmith/build-push-action@v2
136+
with:
137+
context: .
138+
file: docker/Dockerfile.linux-amd64
139+
target: artifacts
140+
push: false
141+
outputs: type=local,dest=dist
142+
build-args: |
143+
LASTFM_API_KEY=${{ secrets.LASTFM_API_KEY }}
144+
LASTFM_API_SECRET=${{ secrets.LASTFM_API_SECRET }}
143145
144146
- name: Upload artifacts
145147
uses: actions/upload-artifact@v7
146148
with:
147149
name: linux-amd64
148-
path: target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb
150+
path: dist/*.deb
149151
retention-days: 7
150152

151153
- name: Upload release assets
@@ -154,7 +156,7 @@ jobs:
154156
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
155157
run: |
156158
gh release upload "${{ github.event.release.tag_name }}" \
157-
target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb
159+
dist/*.deb
158160
159161
build-windows:
160162
name: Build Windows (x64)

.github/workflows/test.yml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,24 @@ jobs:
139139
140140
- uses: actions/checkout@v6
141141

142-
- name: Setup Tauri build environment
143-
uses: ./.github/actions/setup-tauri-build
142+
# Linux: containerized cargo check with Blacksmith Docker layer caching
143+
- name: Setup Docker builder (Linux)
144+
if: runner.os == 'Linux'
145+
uses: useblacksmith/setup-docker-builder@v1
144146

145147
- name: Cargo check (Linux)
146148
if: runner.os == 'Linux'
147-
shell: bash
148-
env:
149-
GITHUB_TOKEN: ${{ github.token }}
150-
run: task ci:check TARGET=${{ matrix.target }}
149+
uses: useblacksmith/build-push-action@v2
150+
with:
151+
context: .
152+
file: docker/Dockerfile.linux-amd64
153+
target: check
154+
push: false
155+
156+
# macOS/Windows: bare-metal setup + cargo check
157+
- name: Setup Tauri build environment
158+
if: runner.os != 'Linux'
159+
uses: ./.github/actions/setup-tauri-build
151160

152161
- name: Cargo check (macOS)
153162
if: runner.os == 'macOS'

docker/Dockerfile.linux-amd64

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
11
# syntax=docker/dockerfile:1.17.1
22
# check=skip=all
33

4-
FROM debian:trixie-slim AS builder
4+
FROM debian:trixie-slim AS deps
5+
6+
RUN true <<'DOCKERFILE'
7+
Multi-stage Dockerfile for Linux CI builds.
8+
9+
Stages:
10+
deps - system packages, Rust nightly, Node.js, cargo-chef, tauri-cli
11+
planner - cargo-chef prepare (generates recipe.json from lock/manifests)
12+
cook - cargo-chef cook (compiles all dependencies, cached by Blacksmith)
13+
check - cargo check --workspace (test workflow target)
14+
build - cargo tauri build --no-bundle + cargo tauri bundle (release target)
15+
artifacts - extract .deb and binary
16+
17+
Usage:
18+
test.yml: docker build --target check .
19+
release.yml: docker build --target artifacts --output type=local,dest=dist .
20+
DOCKERFILE
521

622
ENV DEBIAN_FRONTEND=noninteractive
723

@@ -36,7 +52,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
3652
librsvg2-dev \
3753
&& rm -rf /var/lib/apt/lists/*
3854

39-
# -- Rust (nightly) --
4055
ENV RUSTUP_HOME=/usr/local/rustup \
4156
CARGO_HOME=/usr/local/cargo \
4257
PATH="/usr/local/cargo/bin:${PATH}"
@@ -45,65 +60,71 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
4560
| sh -s -- -y --default-toolchain nightly --profile minimal \
4661
&& rustup target add x86_64-unknown-linux-gnu
4762

48-
# -- Node.js --
63+
RUN cargo install cargo-chef --locked \
64+
&& cargo install cargo-binstall --locked \
65+
&& cargo binstall tauri-cli --locked --no-confirm
66+
4967
ARG NODE_MAJOR=24
5068
RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - \
5169
&& apt-get install -y --no-install-recommends nodejs \
5270
&& rm -rf /var/lib/apt/lists/*
5371

54-
# -- Deno --
55-
RUN curl -fsSL -L https://github.com/denoland/deno/releases/latest/download/deno-x86_64-unknown-linux-gnu.zip \
56-
-o /tmp/deno.zip \
57-
&& unzip -o /tmp/deno.zip -d /usr/local/bin \
58-
&& chmod +x /usr/local/bin/deno \
59-
&& rm /tmp/deno.zip
60-
61-
# -- Last.fm API keys (embedded at compile time via build.rs) --
62-
ARG LASTFM_API_KEY
63-
ARG LASTFM_API_SECRET
64-
ENV LASTFM_API_KEY=${LASTFM_API_KEY}
65-
ENV LASTFM_API_SECRET=${LASTFM_API_SECRET}
66-
67-
# -- Build environment --
6872
ENV RUSTUP_TOOLCHAIN=nightly \
6973
RUSTFLAGS="-Zthreads=16"
7074

7175
WORKDIR /build
7276

73-
# -- Layer: dependency files (cached unless deps change) --
77+
FROM deps AS planner
78+
7479
COPY Cargo.toml Cargo.lock ./
75-
COPY crates/mt-tauri/Cargo.toml crates/mt-tauri/
80+
COPY crates/ crates/
81+
82+
RUN cargo chef prepare --recipe-path recipe.json
83+
84+
FROM deps AS cook
85+
86+
COPY --from=planner /build/recipe.json recipe.json
7687
COPY crates/mt-tauri/.cargo crates/mt-tauri/.cargo/
7788

78-
# Stub source files for cargo fetch
79-
RUN mkdir -p crates/mt-tauri/src && echo "fn main() {}" > crates/mt-tauri/src/main.rs \
80-
&& echo "" > crates/mt-tauri/src/lib.rs
89+
RUN cargo chef cook --recipe-path recipe.json \
90+
--target x86_64-unknown-linux-gnu
8191

82-
RUN cargo fetch --target x86_64-unknown-linux-gnu
92+
RUN cargo chef cook --release --recipe-path recipe.json \
93+
--target x86_64-unknown-linux-gnu
8394

84-
# Frontend deps
85-
COPY deno.jsonc deno.lock ./
8695
COPY app/frontend/package.json app/frontend/package-lock.json app/frontend/
96+
RUN cd app/frontend && npm ci
97+
98+
FROM cook AS check
99+
100+
COPY Cargo.toml Cargo.lock ./
101+
COPY crates/ crates/
87102

88-
RUN deno install --node-modules-dir=auto
103+
RUN cargo check --workspace --target x86_64-unknown-linux-gnu
89104

90-
# -- Layer: full source --
91-
RUN rm -rf crates/mt-tauri/src
105+
FROM cook AS build
92106

107+
ARG LASTFM_API_KEY
108+
ARG LASTFM_API_SECRET
109+
ENV LASTFM_API_KEY=${LASTFM_API_KEY} \
110+
LASTFM_API_SECRET=${LASTFM_API_SECRET}
111+
112+
COPY Cargo.toml Cargo.lock ./
93113
COPY crates/ crates/
94114
COPY app/ app/
95-
COPY scripts/ scripts/
96115
COPY static/ static/
97116

98-
# -- Build frontend --
99117
RUN cd app/frontend && npm run build
100118

101-
# -- Build Tauri app --
102-
RUN deno run -A npm:@tauri-apps/cli build \
119+
RUN cargo tauri build --no-bundle \
120+
--target x86_64-unknown-linux-gnu \
121+
--config '{"build":{"beforeBuildCommand":""}}'
122+
123+
RUN cargo tauri bundle \
103124
--target x86_64-unknown-linux-gnu \
104125
--bundles deb
105126

106127
FROM scratch AS artifacts
107128

108-
COPY --from=builder /build/target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb /
109-
COPY --from=builder /build/target/x86_64-unknown-linux-gnu/release/mt-tauri /mt-tauri
129+
COPY --from=build /build/target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb /
130+
COPY --from=build /build/target/x86_64-unknown-linux-gnu/release/mt-tauri /mt-tauri

0 commit comments

Comments
 (0)