Files
nexus/release.sh
T
2026-04-28 09:36:25 +01:00

216 lines
6.4 KiB
Bash

#!/usr/bin/env bash
# release.sh — Build and package release artefacts for Nexus Terminal.
# Produces per-platform zips plus a manifest.json and version.txt.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
log() { echo -e "${GREEN}[nexus]${NC} $1"; }
warn() { echo -e "${YELLOW}[nexus]${NC} $1"; }
err() { echo -e "${RED}[nexus]${NC} $1" >&2; }
check_deps() {
command -v go >/dev/null 2>&1 || { err "Go is not installed"; exit 1; }
command -v node >/dev/null 2>&1 || { err "Node.js is not installed"; exit 1; }
command -v npm >/dev/null 2>&1 || { err "npm is not installed"; exit 1; }
command -v zip >/dev/null 2>&1 || { err "zip is not installed"; exit 1; }
command -v shasum >/dev/null 2>&1 || { err "shasum is not installed"; exit 1; }
if ! command -v wails >/dev/null 2>&1; then
if [ -f "$HOME/go/bin/wails" ]; then
export PATH="$PATH:$HOME/go/bin"
else
err "Wails is not installed. Run: go install github.com/wailsapp/wails/v2/cmd/wails@latest"
exit 1
fi
fi
}
install_deps() {
log "Installing Go dependencies..."
go mod download
log "Installing frontend dependencies..."
cd frontend && npm install && cd ..
}
build_version() {
local tag
local commit
tag="$(git describe --tags --abbrev=0 2>/dev/null || echo "dev")"
commit="$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")"
echo "${tag}-${commit}"
}
build_ldflags() {
local version="$1"
local flags="-s -w -X github.com/andydixon/nexus/internal/api.appVersion=${version}"
if [ -n "${NEXUS_UPDATE_URL:-}" ]; then
flags="${flags} -X github.com/andydixon/nexus/internal/api.appUpdateURL=${NEXUS_UPDATE_URL}"
fi
echo "${flags}"
}
pick_cc() {
local target_os="$1"
local target_arch="$2"
if [ "$target_os" = "windows" ]; then
if [ "$target_arch" = "amd64" ]; then
echo "x86_64-w64-mingw32-gcc"
else
echo "aarch64-w64-mingw32-gcc"
fi
return
fi
if [ "$target_os" = "linux" ]; then
if [ "$target_arch" = "amd64" ]; then
echo "x86_64-linux-gnu-gcc"
else
echo "aarch64-linux-gnu-gcc"
fi
return
fi
echo ""
}
build_target() {
local target_os="$1"
local target_arch="$2"
local version="$3"
local out_dir="$4"
local platform="${target_os}/${target_arch}"
local cc
cc="$(pick_cc "$target_os" "$target_arch")"
if [ -n "$cc" ] && ! command -v "$cc" >/dev/null 2>&1; then
warn "Skipping ${platform} (missing C compiler: ${cc})"
return 0
fi
local output_base="NexusTerminal-${target_os}-${target_arch}"
local output_path
if [ "$target_os" = "darwin" ]; then
output_path="${out_dir}/${output_base}.app"
elif [ "$target_os" = "windows" ]; then
output_path="${out_dir}/${output_base}.exe"
else
output_path="${out_dir}/${output_base}"
fi
log "Building ${platform}..."
local ldflags
ldflags="$(build_ldflags "$version")"
if [ -n "$cc" ]; then
CC="$cc" CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" -o "$output_path"
else
CGO_ENABLED=1 wails build -platform "$platform" -ldflags "$ldflags" -o "$output_path"
fi
local zip_name="${out_dir}/${output_base}.zip"
if [ "$target_os" = "darwin" ]; then
(cd "$out_dir" && zip -r "${output_base}.zip" "${output_base}.app" >/dev/null)
elif [ "$target_os" = "windows" ]; then
(cd "$out_dir" && zip -j "${output_base}.zip" "${output_base}.exe" >/dev/null)
else
(cd "$out_dir" && zip -j "${output_base}.zip" "${output_base}" >/dev/null)
fi
echo "$target_os|$target_arch|$output_base.zip" >> "${out_dir}/.release-files"
}
write_manifest() {
local version="$1"
local out_dir="$2"
local manifest_path="$3"
local version_path="$4"
local base_url="${NEXUS_RELEASE_BASE_URL:-}"
local published_at
published_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
echo "$version" > "$version_path"
{
echo "{"
echo " \"latestVersion\": \"${version}\","
echo " \"publishedAt\": \"${published_at}\","
if [ -n "$base_url" ]; then
echo " \"releaseURL\": \"${base_url}/\","
else
echo " \"releaseURL\": \"\","
fi
echo " \"files\": ["
local first=1
while IFS='|' read -r os arch filename; do
[ -z "$os" ] && continue
local file_path="${out_dir}/${filename}"
local sha
sha="$(shasum -a 256 "$file_path" | awk '{print $1}')"
local size
size="$(wc -c < "$file_path" | tr -d ' ')"
local url=""
if [ -n "$base_url" ]; then
url="${base_url}/${filename}"
fi
if [ $first -eq 0 ]; then
echo ","
fi
first=0
printf " {\"platform\":\"%s\",\"arch\":\"%s\",\"filename\":\"%s\",\"url\":\"%s\",\"sha256\":\"%s\",\"size\":%s}" "$os" "$arch" "$filename" "$url" "$sha" "$size"
done < "${out_dir}/.release-files"
echo
echo " ]"
echo "}"
} > "$manifest_path"
rm -f "${out_dir}/.release-files"
}
main() {
check_deps
install_deps
local version
version="$(build_version)"
if [ -z "${NEXUS_UPDATE_URL:-}" ]; then
warn "NEXUS_UPDATE_URL is not set; updates will default to GitHub in this build"
fi
local release_root="build/releases"
local out_dir="${release_root}/${version}"
mkdir -p "$out_dir"
log "Building release ${version}..."
: > "${out_dir}/.release-files"
build_target "darwin" "amd64" "$version" "$out_dir"
build_target "darwin" "arm64" "$version" "$out_dir"
build_target "linux" "amd64" "$version" "$out_dir"
build_target "linux" "arm64" "$version" "$out_dir"
build_target "windows" "amd64" "$version" "$out_dir"
build_target "windows" "arm64" "$version" "$out_dir"
local manifest_path="${release_root}/manifest.json"
local version_path="${release_root}/version.txt"
write_manifest "$version" "$out_dir" "$manifest_path" "$version_path"
log "Release artefacts written to ${out_dir}"
log "Manifest: ${manifest_path}"
log "Version: ${version_path}"
}
main "$@"