diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 0f0d18e1..c1165183 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -22,6 +22,11 @@ jobs: with: node-version: "22.x" check-latest: true + + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: "1.89.0" - name: Setup rust run: | diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 23f57786..79c0c5b1 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -23,6 +23,11 @@ jobs: node-version: "22.x" check-latest: true + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: "1.89.0" + - name: Setup rust run: | cargo install sqlx-cli diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 0ccfc04e..f9fee79b 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -67,7 +67,7 @@ jobs: uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0 with: context: sync-server - platforms: linux/amd64,linux/arm64,linux/arm/v7 + platforms: linux/amd64,linux/arm64 push: ${{ github.ref_type == 'tag' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/publish-plugin.yml b/.github/workflows/publish-plugin.yml index 18c934bb..2aee93c5 100644 --- a/.github/workflows/publish-plugin.yml +++ b/.github/workflows/publish-plugin.yml @@ -25,6 +25,19 @@ jobs: cd frontend npm ci npm run build + + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: "1.89.0" + + - name: Install cross-compilation tools + run: | + sudo apt update + sudo apt install -y gcc-aarch64-linux-gnu musl-tools gcc-mingw-w64-x86-64 + + - name: Build Linux and Windows binaries + run: ./scripts/build-sync-server-binaries.sh - name: Create release env: @@ -37,4 +50,4 @@ jobs: gh release create "$tag" \ --title="$tag" \ --draft \ - main.js manifest.json styles.css + main.js manifest.json styles.css artifacts/sync-server-* diff --git a/scripts/build-sync-server-binaries.sh b/scripts/build-sync-server-binaries.sh new file mode 100755 index 00000000..1a605999 --- /dev/null +++ b/scripts/build-sync-server-binaries.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +set -e + +cd "$(dirname "$0")/../sync-server" + +# Setup database +sqlx database create --database-url sqlite://db.sqlite3 2>/dev/null || true +sqlx migrate run --source src/app_state/database/migrations --database-url sqlite://db.sqlite3 + +targets=${@:-"x86_64-unknown-linux-gnu x86_64-unknown-linux-musl aarch64-unknown-linux-gnu x86_64-pc-windows-gnu"} + +mkdir -p ../artifacts +rm -f ../artifacts/sync-server-* + + +for target in $targets; do + echo "Building $target..." + + # Set linkers for cross-compilation + case "$target" in + aarch64-unknown-linux-gnu) + export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc ;; + x86_64-unknown-linux-musl) + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc ;; + x86_64-pc-windows-gnu) + export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc ;; + esac + + rustup target add "$target" 2>/dev/null || true + + cargo build --release --target "$target" + ext="" + [[ "$target" == *windows* ]] && ext=".exe" + + name="sync-server-${target//-/_}$ext" + name="${name//x86_64_unknown_linux_gnu/linux-x86_64}" + name="${name//x86_64_unknown_linux_musl/linux-x86_64-musl}" + name="${name//aarch64_unknown_linux_gnu/linux-aarch64}" + name="${name//x86_64_pc_windows_gnu/windows-x86_64}" + + cp "target/$target/release/sync_server$ext" "../artifacts/$name" + echo "✓ Built $name" +done + +ls -la ../artifacts/sync-server-* diff --git a/sync-server/Dockerfile b/sync-server/Dockerfile index df6ba74f..abd9aa6e 100644 --- a/sync-server/Dockerfile +++ b/sync-server/Dockerfile @@ -1,18 +1,33 @@ -FROM rust:1.89-alpine AS builder +FROM rust:1.89-slim-trixie AS builder +ARG TARGETPLATFORM WORKDIR /usr/src/backend -# Install build dependencies for Alpine -RUN apk add --no-cache musl-dev pkgconf openssl-dev perl make +# Set RUST_TARGET based on platform and create sourceable script +RUN case "$TARGETPLATFORM" in \ + "linux/amd64") echo 'export RUST_TARGET="x86_64-unknown-linux-musl"' > /tmp/rust_env ;; \ + "linux/arm64") echo 'export RUST_TARGET="aarch64-unknown-linux-musl"' > /tmp/rust_env ;; \ + "linux/arm/v7") echo 'export RUST_TARGET="armv7-unknown-linux-musleabihf"' > /tmp/rust_env ;; \ + *) echo "Unsupported platform: $TARGETPLATFORM" && exit 1 ;; \ + esac -# Install sqlx-cli -RUN cargo install sqlx-cli --features=openssl-vendored +# Install musl tools, cross-compilation toolchains, and OpenSSL dev packages +RUN . /tmp/rust_env && \ + apt update && \ + apt install -y musl-tools libssl-dev pkg-config \ + gcc-aarch64-linux-gnu \ + gcc-arm-linux-gnueabi &&\ + rustup target add $RUST_TARGET && \ + cargo install sqlx-cli -# Setup database and build +# Build application COPY . . -RUN sqlx database create --database-url sqlite://db.sqlite3 && \ + +RUN . /tmp/rust_env && \ + export CFLAGS="-Wno-stringop-overread" && \ + sqlx database create --database-url sqlite://db.sqlite3 && \ sqlx migrate run --source src/app_state/database/migrations --database-url sqlite://db.sqlite3 && \ - cargo build --release + cargo build --release --target $RUST_TARGET # Runtime image FROM alpine:3.22.0 @@ -21,7 +36,7 @@ LABEL org.opencontainers.image.authors="andras@schmelczer.dev" RUN apk add --no-cache curl ca-certificates -COPY --from=builder /usr/src/backend/target/release/sync_server /app/sync_server +COPY --from=builder /usr/src/backend/target/*/release/sync_server /app/sync_server VOLUME /data EXPOSE 3000/tcp @@ -30,4 +45,4 @@ WORKDIR /data HEALTHCHECK --interval=30s --timeout=5s \ CMD curl -f http://localhost:3000/vaults/fake/ping || exit 1 -ENTRYPOINT ["/app/sync_server"] \ No newline at end of file +ENTRYPOINT ["/app/sync_server"] diff --git a/sync-server/rust-toolchain.toml b/sync-server/rust-toolchain.toml index ed32db00..635d09fb 100644 --- a/sync-server/rust-toolchain.toml +++ b/sync-server/rust-toolchain.toml @@ -1,4 +1,9 @@ [toolchain] channel = "1.89.0" -targets = [ "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl" ] +targets = [ + "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", + "aarch64-unknown-linux-gnu", + "x86_64-pc-windows-gnu", +] profile = "default"