diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 5e72aae..b212a90 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -56,6 +56,10 @@ env: BIN: uo-link-sidecar LINUX_TARGET: x86_64-unknown-linux-gnu WINDOWS_TARGET: x86_64-pc-windows-gnu + # Ampere/Graviton instances and Pi-class boxes are a realistic ServUO home, + # and the shard dials the sidecar out on loopback — so wherever the shard + # runs, this binary has to run too (installer PLAN.md §5.2). + ARM64_TARGET: aarch64-unknown-linux-gnu # Notified after a release so the installer's compat matrix picks up this # version immediately rather than at its next nightly run (PLAN.md §7.2). INSTALLER_REPO: RunicGateway/installer @@ -137,14 +141,26 @@ jobs: echo "==> release=${RELEASE} version=${VERSION} bump=${BUMP} last_tag=${LAST_TAG:-}" # ── RUST ADAPTER: toolchain + cross-compile deps ───────────────────── - - name: Install Rust toolchain, Windows target, and MinGW linker + - name: Install Rust toolchain, cross targets, and their linkers if: ${{ steps.plan.outputs.release == 'true' }} run: | set -euo pipefail SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo" $SUDO apt-get update + # The arm64 cross toolchain is not optional for this crate: sqlx's + # sqlite feature pulls libsqlite3-sys, which compiles bundled SQLite + # from C, so a Rust-only cross build fails at the first .c file. + # + # libc6-dev-arm64-cross is named explicitly because gcc-aarch64-linux-gnu + # only *recommends* it, and this install is --no-install-recommends: the + # compiler arrives without arm64 libc headers and SQLite's build dies on + # `bits/libc-header-start.h: No such file or directory`. Verified by + # reproducing both the failure and the fix in a rust:1-slim-bookworm + # container. $SUDO apt-get install -y --no-install-recommends \ - build-essential gcc-mingw-w64-x86-64 curl ca-certificates git jq + build-essential gcc-mingw-w64-x86-64 \ + gcc-aarch64-linux-gnu libc6-dev-arm64-cross \ + curl ca-certificates git jq if ! command -v cargo >/dev/null 2>&1; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ @@ -154,6 +170,7 @@ jobs: export PATH="${HOME}/.cargo/bin:${PATH}" rustup component add rustfmt rustup target add "${WINDOWS_TARGET}" + rustup target add "${ARM64_TARGET}" - name: Set the crate version to match the release if: ${{ steps.plan.outputs.release == 'true' }} @@ -195,14 +212,30 @@ jobs: AR_x86_64_pc_windows_gnu: x86_64-w64-mingw32-ar run: cargo build --release --locked --target "${WINDOWS_TARGET}" + # Same shape as the Windows step: a linker for Rust's output and a CC/AR + # pair for the cc-crate build of bundled SQLite. + - name: cargo build --release (Linux arm64, cross via aarch64-linux-gnu) + if: ${{ steps.plan.outputs.release == 'true' }} + working-directory: sidecar + env: + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc + CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc + AR_aarch64_unknown_linux_gnu: aarch64-linux-gnu-ar + run: cargo build --release --locked --target "${ARM64_TARGET}" + # ── RUST ADAPTER: package artifacts (+ checksums) ──────────────────── - name: Package artifacts and SHA256SUMS if: ${{ steps.plan.outputs.release == 'true' }} run: | set -euo pipefail cp "${WORKDIR}/target/${LINUX_TARGET}/release/${BIN}" "dist/${BIN}-linux-x86_64" + cp "${WORKDIR}/target/${ARM64_TARGET}/release/${BIN}" "dist/${BIN}-linux-aarch64" cp "${WORKDIR}/target/${WINDOWS_TARGET}/release/${BIN}.exe" "dist/${BIN}-windows-x86_64.exe" - ( cd dist && sha256sum "${BIN}-linux-x86_64" "${BIN}-windows-x86_64.exe" > SHA256SUMS ) + # Every artifact must appear here: the installer verifies its download + # against these sums, and `sha256sum -c` passes silently over a file + # this list does not mention. + ( cd dist && sha256sum "${BIN}-linux-x86_64" "${BIN}-linux-aarch64" \ + "${BIN}-windows-x86_64.exe" > SHA256SUMS ) ls -l dist && echo "----" && cat dist/SHA256SUMS # ── RELEASE ENGINE: commit the bump, tag, push ─────────────────────── @@ -258,7 +291,7 @@ jobs: | jq -r '.id')" echo "Created release ${TAG} (id=${REL_ID})" - for f in "${BIN}-linux-x86_64" "${BIN}-windows-x86_64.exe" SHA256SUMS; do + for f in "${BIN}-linux-x86_64" "${BIN}-linux-aarch64" "${BIN}-windows-x86_64.exe" SHA256SUMS; do curl -sSf -X POST "${API}/releases/${REL_ID}/assets?name=${f}" \ -H "Authorization: token ${CI_TOKEN}" \ -F "attachment=@dist/${f}" >/dev/null