Files
funman300 36cbf6df58
Build and Deploy / build-and-push (push) Successful in 9m33s
fix(ci): copy CHANGELOG.md into the wasm docker stage — deploys broken since v0.47.0
whats_new_plugin embeds the changelog at compile time
(include_str!("../../CHANGELOG.md"), shipped 2026-07-13), but the
Dockerfile's wasm-builder stage copies an explicit file list that
never included CHANGELOG.md — every docker-build since (10 runs,
v0.48.x and v0.49.0 content) failed in build_wasm.sh while web-e2e
(full checkout) stayed green, so the web has been serving the
July 14 image.

Also add CHANGELOG.md to the workflow's trigger paths so changelog
cuts redeploy the web and the What's-new card stays fresh.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 18:53:13 -07:00

147 lines
6.4 KiB
Docker

# --- WASM build stage ---
# Builds solitaire_server/web/pkg/ (replay viewer + Bevy canvas app) from
# source. The artifacts are not committed to the repo (issue #156); this
# stage is their single source of truth for deployment.
FROM rust:1.95-slim AS wasm-builder
WORKDIR /build
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN rustup target add wasm32-unknown-unknown
# Pinned wasm toolchain — keep versions in sync with
# .gitea/workflows/web-e2e.yml and build_wasm.sh prerequisites.
RUN curl -sSL https://github.com/rustwasm/wasm-bindgen/releases/download/0.2.120/wasm-bindgen-0.2.120-x86_64-unknown-linux-musl.tar.gz \
| tar xz -C /opt \
&& ln -s /opt/wasm-bindgen-0.2.120-x86_64-unknown-linux-musl/wasm-bindgen /usr/local/bin/wasm-bindgen \
&& curl -sSL https://github.com/rustwasm/wasm-pack/releases/download/v0.14.0/wasm-pack-v0.14.0-x86_64-unknown-linux-musl.tar.gz \
| tar xz -C /opt \
&& ln -s /opt/wasm-pack-v0.14.0-x86_64-unknown-linux-musl/wasm-pack /usr/local/bin/wasm-pack \
&& curl -sSL https://github.com/WebAssembly/binaryen/releases/download/version_130/binaryen-version_130-x86_64-linux.tar.gz \
| tar xz -C /opt \
&& ln -s /opt/binaryen-version_130/bin/wasm-opt /usr/local/bin/wasm-opt
# Manifests first so the dependency-fetch layer caches across source changes
# (same pattern as the server build stage below).
COPY .cargo/config.toml ./.cargo/config.toml
COPY Cargo.toml Cargo.lock ./
COPY solitaire_core/Cargo.toml ./solitaire_core/Cargo.toml
COPY solitaire_sync/Cargo.toml ./solitaire_sync/Cargo.toml
COPY solitaire_data/Cargo.toml ./solitaire_data/Cargo.toml
COPY solitaire_engine/Cargo.toml ./solitaire_engine/Cargo.toml
COPY solitaire_server/Cargo.toml ./solitaire_server/Cargo.toml
COPY solitaire_app/Cargo.toml ./solitaire_app/Cargo.toml
COPY solitaire_assetgen/Cargo.toml ./solitaire_assetgen/Cargo.toml
COPY solitaire_wasm/Cargo.toml ./solitaire_wasm/Cargo.toml
COPY solitaire_web/Cargo.toml ./solitaire_web/Cargo.toml
RUN for crate in solitaire_core solitaire_sync solitaire_data solitaire_engine \
solitaire_server solitaire_app solitaire_assetgen solitaire_wasm solitaire_web; do \
mkdir -p $crate/src && echo "pub fn _stub() {}" > $crate/src/lib.rs; \
done && \
echo "fn main() {}" > solitaire_server/src/main.rs && \
echo "fn main() {}" > solitaire_app/src/main.rs && \
echo "fn main() {}" > solitaire_assetgen/src/main.rs
RUN cargo fetch --locked
# Real source for the wasm-feeding crates. Whole crate directories (not just
# src/) because solitaire_engine embeds theme/audio/font assets at compile
# time from its own assets/ and the workspace assets/.
COPY build_wasm.sh ./
# whats_new_plugin embeds the changelog at compile time
# (include_str!("../../CHANGELOG.md")) — omit it and the engine build
# fails inside this stage while full-checkout builds stay green.
COPY CHANGELOG.md ./
COPY solitaire_core ./solitaire_core
COPY solitaire_sync ./solitaire_sync
COPY solitaire_data ./solitaire_data
COPY solitaire_engine ./solitaire_engine
COPY solitaire_wasm ./solitaire_wasm
COPY solitaire_web ./solitaire_web
COPY assets ./assets
RUN ./build_wasm.sh
# --- Build stage ---
FROM rust:1.95-slim AS builder
WORKDIR /build
# Install musl tools for a fully static binary and sqlx-cli for compile-time
# query checking (SQLX_OFFLINE=true skips the live-DB check at build time).
RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
# Copy only the files needed to build the server crate.
# Layer order: workspace manifests first so dependency fetches are cached.
COPY .cargo/config.toml ./.cargo/config.toml
COPY Cargo.toml Cargo.lock ./
COPY solitaire_core/Cargo.toml ./solitaire_core/Cargo.toml
COPY solitaire_sync/Cargo.toml ./solitaire_sync/Cargo.toml
COPY solitaire_data/Cargo.toml ./solitaire_data/Cargo.toml
COPY solitaire_engine/Cargo.toml ./solitaire_engine/Cargo.toml
COPY solitaire_server/Cargo.toml ./solitaire_server/Cargo.toml
COPY solitaire_app/Cargo.toml ./solitaire_app/Cargo.toml
COPY solitaire_assetgen/Cargo.toml ./solitaire_assetgen/Cargo.toml
COPY solitaire_wasm/Cargo.toml ./solitaire_wasm/Cargo.toml
COPY solitaire_web/Cargo.toml ./solitaire_web/Cargo.toml
# Stub every workspace crate so `cargo fetch --locked` resolves the full
# dependency graph without requiring source files beyond Cargo.toml.
RUN for crate in solitaire_core solitaire_sync solitaire_data solitaire_engine \
solitaire_server solitaire_app solitaire_assetgen solitaire_wasm solitaire_web; do \
mkdir -p $crate/src && echo "pub fn _stub() {}" > $crate/src/lib.rs; \
done && \
echo "fn main() {}" > solitaire_server/src/main.rs && \
echo "fn main() {}" > solitaire_app/src/main.rs && \
echo "fn main() {}" > solitaire_assetgen/src/main.rs
# Registry config comes from .cargo/config.toml copied above.
RUN cargo fetch --locked
# Now copy real source and build in release mode.
COPY solitaire_core/src ./solitaire_core/src
COPY solitaire_sync/src ./solitaire_sync/src
COPY solitaire_server/src ./solitaire_server/src
COPY solitaire_server/web ./solitaire_server/web
COPY solitaire_server/migrations ./solitaire_server/migrations
# sqlx offline query cache — required when SQLX_OFFLINE=true so the
# compile-time macros don't need a live database.
COPY .sqlx ./.sqlx
ENV SQLX_OFFLINE=true
RUN cargo build --release --locked -p solitaire_server --bin solitaire_server
# --- Runtime stage ---
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
libsqlite3-0 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /build/target/release/solitaire_server ./server
# Migrations are embedded via sqlx::migrate!("./migrations") at compile time.
# Static web assets are served via ServeDir at runtime from these paths:
# /app/solitaire_server/web → /web route
# /app/assets → /assets route
# Card themes (dark + classic) are embedded in the binary; no theme files needed here.
COPY solitaire_server/web ./solitaire_server/web
# The wasm bundles are never in the repo — they come from the wasm-builder stage.
COPY --from=wasm-builder /build/solitaire_server/web/pkg ./solitaire_server/web/pkg
COPY assets ./assets
ENV SERVER_PORT=8080
EXPOSE 8080
ENTRYPOINT ["./server"]