#!/usr/bin/env bash # # windows-publish.sh — cross-build the Windows installer and add it to a downloads folder. # # Usage: # ./scripts/windows-publish.sh ~/win-mtgc # # Or through npm: `npm run windows:publish -- ~/win-mtgc`. # # Options: # --allow-dirty publish uncommitted changes; the file name gets a -dirty suffix # # Environment: # MTGC_WINDOWS_DIR downloads directory, if not given as an argument # # Builds on Linux for x86_64-pc-windows-msvc through cargo-xwin, which fetches # the MSVC CRT and Windows SDK into ~/.cache/cargo-xwin the first time. Only # the NSIS installer can be made off Windows (MSI needs WiX). The directory is # public — serve it as is. Needs `sudo dnf install mingw-nsis-base llvm lld # clang`, `cargo install --locked cargo-xwin`, `rustup target add # x86_64-pc-windows-msvc`, and the desktop setup from ./scripts/devel-setup.sh. # set -euo pipefail usage() { sed -n '3,22p' "$0" | sed 's/^# \{0,1\}//' exit "${1:-0}" } info() { printf '\033[1;34m==>\033[0m %s\n' "$*"; } warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$*"; } err() { printf '\033[1;31m[err]\033[0m %s\n' "$*" >&2; } PACKAGE="mtgc" TARGET="x86_64-pc-windows-msvc" LATEST="$PACKAGE-latest-x64-setup.exe" KEEP=3 # versions kept in the folder, so a bad release can be rolled back allow_dirty=false dir="${MTGC_WINDOWS_DIR:-}" while [ $# -gt 0 ]; do case "$1" in --allow-dirty) allow_dirty=true ;; -h | --help) usage ;; -*) usage 1 ;; *) dir="$1" ;; esac shift done [ -n "$dir" ] || usage 1 mkdir -p "$dir" dir="$(cd "$dir" && pwd)" repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$repo_root" # --- 1. Tools --------------------------------------------------------------- for tool in makensis llvm-rc lld-link clang; do if ! command -v "$tool" >/dev/null 2>&1; then err "$tool not found. Install them: sudo dnf install mingw-nsis-base llvm lld clang" exit 1 fi done if ! command -v cargo-xwin >/dev/null 2>&1; then err "cargo-xwin not found. Install it: cargo install --locked cargo-xwin" exit 1 fi if command -v rustup >/dev/null 2>&1 && ! rustup target list --installed | grep -qxF "$TARGET"; then err "the $TARGET Rust target is missing. Add it: rustup target add $TARGET" exit 1 fi # --- 2. Version ------------------------------------------------------------- # # The installer's own version stays numeric (NSIS insists); a dirty build is # only marked in the file name. source scripts/lib/release-version.sh file_version="$release_version" if $release_dirty; then if ! $allow_dirty; then err "the working tree has uncommitted changes; commit them or pass --allow-dirty" exit 1 fi file_version="$release_version-dirty" fi # --- 3. Only ever move forward ---------------------------------------------- newest=0 for exe in "$dir/${PACKAGE}"_*_x64-setup.exe; do [ -e "$exe" ] || continue patch="${exe##*/${PACKAGE}_}" patch="${patch%_x64-setup.exe}" patch="${patch%-dirty}" patch="${patch##*.}" [ "$patch" -gt "$newest" ] && newest="$patch" done if [ "$release_count" -le "$newest" ]; then err "version $release_version is not newer than the folder's x.y.$newest; commit something first" exit 1 fi # --- 4. Build --------------------------------------------------------------- info "building $file_version for $TARGET" outputs="target/$TARGET/release/bundle/nsis" rm -rf "$outputs" cargo tauri build --runner cargo-xwin --target "$TARGET" --bundles nsis --ci \ --config "{\"version\":\"$release_version\"}" built="$(find "$outputs" -name '*-setup.exe' | head -1)" if [ -z "$built" ]; then err "the build produced no installer under $outputs" exit 1 fi # --- 5. Publish ------------------------------------------------------------- name="${PACKAGE}_${file_version}_x64-setup.exe" cp "$built" "$dir/$name" # A copy, not a symlink, so the stable link survives rsync and any static host. cp "$built" "$dir/.$LATEST.tmp" mv -f "$dir/.$LATEST.tmp" "$dir/$LATEST" # Drop all but the newest few versions. mapfile -t old < <(find "$dir" -maxdepth 1 -name "${PACKAGE}_*_x64-setup.exe" | sort -V | head -n -"$KEEP") if [ "${#old[@]}" -gt 0 ]; then rm -f "${old[@]}" fi (cd "$dir" && sha256sum "$LATEST" "${PACKAGE}"_*_x64-setup.exe >SHA256SUMS) # --- 6. How to use it ------------------------------------------------------- info "published $file_version" cat <