release changes
This commit is contained in:
@@ -45,17 +45,28 @@ Build the app binary for the current host:
|
||||
./build.sh
|
||||
```
|
||||
|
||||
Build a packaged release for the current host platform:
|
||||
Build packaged releases for every supported 64-bit desktop target:
|
||||
|
||||
```bash
|
||||
./release.sh
|
||||
```
|
||||
|
||||
By default, `./release.sh` now builds only the current host OS/architecture. On this Ubuntu 24.04 `amd64` host that means `linux/amd64`.
|
||||
By default, `./release.sh` builds all six OS/architecture combinations:
|
||||
|
||||
## Optional cross-target builds
|
||||
- macOS (`darwin`): `amd64` and `arm64`
|
||||
- Linux: `amd64` and `arm64`
|
||||
- Windows: `amd64` and `arm64`
|
||||
|
||||
The release scripts disable CGO and use a pure-Go SQLite driver, so Linux and Windows cross-targets no longer need C cross-compilers for the application backend. Request explicit targets with:
|
||||
Go calls the x86-64 architecture `amd64` and the AArch64 architecture `arm64`.
|
||||
|
||||
On macOS, Linux builds run in architecture-matched Podman or Docker containers
|
||||
because Wails does not cross-compile Linux applications directly from macOS.
|
||||
The reusable builder images keep their `node_modules` separate from the host
|
||||
checkout.
|
||||
|
||||
## Optional targeted builds
|
||||
|
||||
The release scripts disable CGO and use a pure-Go SQLite driver, so Linux and Windows cross-targets do not need C cross-compilers for the application backend. To build a smaller set, override the default targets:
|
||||
|
||||
```bash
|
||||
NEXUS_RELEASE_TARGETS=linux/amd64,windows/amd64 ./release.sh
|
||||
@@ -63,6 +74,7 @@ NEXUS_RELEASE_TARGETS=linux/amd64,windows/amd64 ./release.sh
|
||||
|
||||
## Platform caveats
|
||||
|
||||
- macOS targets cannot be cross-built from Linux with Wails. Build those on macOS.
|
||||
- To produce all six targets in one run, use macOS with Podman or Docker running.
|
||||
- macOS targets cannot be cross-built from Linux or Windows with Wails.
|
||||
- Cross-target support still depends on Wails and frontend packaging support for the requested platform.
|
||||
- Tested on Ubuntu 24.04 `amd64`: `linux/amd64` and `windows/amd64` build successfully.
|
||||
|
||||
+144
-21
@@ -1,6 +1,7 @@
|
||||
#!/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.
|
||||
# Produces per-platform zips, manifests, and version files for every supported
|
||||
# 64-bit desktop OS/architecture combination.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
@@ -15,6 +16,24 @@ NC='\033[0m'
|
||||
DEFAULT_UPDATE_URL="https://dixon.cx/downloads/nexus/manifest-{platform}-{arch}.json"
|
||||
DEFAULT_RELEASE_BASE_URL="https://dixon.cx/downloads/nexus"
|
||||
WAILS_VERSION="$(nexus_wails_version go.mod)"
|
||||
GO_TOOLCHAIN_VERSION="$(
|
||||
awk '
|
||||
$1 == "go" { go_version = $2 }
|
||||
$1 == "toolchain" {
|
||||
sub(/^go/, "", $2)
|
||||
toolchain_version = $2
|
||||
}
|
||||
END {
|
||||
if (toolchain_version != "") {
|
||||
print toolchain_version
|
||||
} else {
|
||||
print go_version
|
||||
}
|
||||
}
|
||||
' go.mod
|
||||
)"
|
||||
DEFAULT_LINUX_BUILD_IMAGE="docker.io/library/golang:${GO_TOOLCHAIN_VERSION:-1.26}-bookworm"
|
||||
DEFAULT_NODE_VERSION="20.19.4"
|
||||
|
||||
log() { echo -e "${GREEN}[nexus]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[nexus]${NC} $1"; }
|
||||
@@ -24,14 +43,7 @@ host_os() {
|
||||
case "$(uname -s)" in
|
||||
Darwin) echo "darwin" ;;
|
||||
Linux) echo "linux" ;;
|
||||
*) echo "unknown" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
host_arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64|amd64) echo "amd64" ;;
|
||||
arm64|aarch64) echo "arm64" ;;
|
||||
MINGW*|MSYS*|CYGWIN*) echo "windows" ;;
|
||||
*) echo "unknown" ;;
|
||||
esac
|
||||
}
|
||||
@@ -41,17 +53,13 @@ build_tags() {
|
||||
}
|
||||
|
||||
default_targets() {
|
||||
local os
|
||||
local arch
|
||||
os="$(host_os)"
|
||||
arch="$(host_arch)"
|
||||
|
||||
if [ "$os" = "unknown" ] || [ "$arch" = "unknown" ]; then
|
||||
err "Unsupported host platform: $(uname -s)/$(uname -m)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "${os}/${arch}"
|
||||
printf '%s\n' \
|
||||
"darwin/amd64" \
|
||||
"darwin/arm64" \
|
||||
"linux/amd64" \
|
||||
"linux/arm64" \
|
||||
"windows/amd64" \
|
||||
"windows/arm64"
|
||||
}
|
||||
|
||||
release_targets() {
|
||||
@@ -108,6 +116,18 @@ build_ldflags() {
|
||||
nexus_build_ldflags "$1"
|
||||
}
|
||||
|
||||
container_engine() {
|
||||
local candidate
|
||||
for candidate in podman docker; do
|
||||
if command -v "$candidate" >/dev/null 2>&1 \
|
||||
&& "$candidate" info >/dev/null 2>&1; then
|
||||
echo "$candidate"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
ensure_upx() {
|
||||
if ! nexus_bool_enabled "${NEXUS_COMPRESS:-0}"; then
|
||||
return
|
||||
@@ -132,6 +152,87 @@ ensure_upx() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
build_linux_target_in_container() {
|
||||
local target="$1"
|
||||
local version="$2"
|
||||
local out_dir="$3"
|
||||
local target_os="${target%%/*}"
|
||||
local target_arch="${target##*/}"
|
||||
|
||||
local engine
|
||||
if ! engine="$(container_engine)"; then
|
||||
warn "Linux targets require a running Podman or Docker engine on $(host_os)."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local node_arch
|
||||
case "$target_arch" in
|
||||
amd64) node_arch="x64" ;;
|
||||
arm64) node_arch="arm64" ;;
|
||||
*)
|
||||
warn "No Node.js Linux archive mapping for ${target_arch}."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
mkdir -p "$SCRIPT_DIR/build"
|
||||
local container_release_dir
|
||||
container_release_dir="$(mktemp -d "$SCRIPT_DIR/build/.release-linux.XXXXXX")"
|
||||
local container_release_root="build/$(basename "$container_release_dir")"
|
||||
local image="${NEXUS_LINUX_BUILD_IMAGE:-$DEFAULT_LINUX_BUILD_IMAGE}"
|
||||
local node_version="${NEXUS_NODE_VERSION:-$DEFAULT_NODE_VERSION}"
|
||||
local builder_image="nexus-linux-release:${GO_TOOLCHAIN_VERSION:-1.26}-${node_version}-${target_arch}"
|
||||
|
||||
log "Preparing the ${engine} Linux/${target_arch} release builder..."
|
||||
if ! "$engine" build \
|
||||
--platform "linux/${target_arch}" \
|
||||
--build-arg "GO_IMAGE=${image}" \
|
||||
--build-arg "NODE_ARCH=${node_arch}" \
|
||||
--build-arg "NODE_VERSION=${node_version}" \
|
||||
--build-arg "WAILS_VERSION=${WAILS_VERSION}" \
|
||||
-t "$builder_image" \
|
||||
-f "$SCRIPT_DIR/scripts/linux-release.Dockerfile" \
|
||||
"$SCRIPT_DIR/scripts"; then
|
||||
warn "Could not prepare the Linux/${target_arch} release builder."
|
||||
rm -rf -- "$container_release_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Building ${target} in the ${engine} container..."
|
||||
if ! "$engine" run --rm \
|
||||
--platform "linux/${target_arch}" \
|
||||
-v "${SCRIPT_DIR}:/src" \
|
||||
--tmpfs /src/frontend/node_modules \
|
||||
-w /src \
|
||||
-e "NEXUS_RELEASE_TARGETS=${target}" \
|
||||
-e "NEXUS_RELEASE_ROOT=${container_release_root}" \
|
||||
-e "NEXUS_UPDATE_URL=${NEXUS_UPDATE_URL}" \
|
||||
-e "NEXUS_RELEASE_BASE_URL=${NEXUS_RELEASE_BASE_URL}" \
|
||||
-e "GIT_CONFIG_COUNT=1" \
|
||||
-e "GIT_CONFIG_KEY_0=safe.directory" \
|
||||
-e "GIT_CONFIG_VALUE_0=/src" \
|
||||
"$builder_image" \
|
||||
./release.sh; then
|
||||
warn "Container build failed for ${target}."
|
||||
rm -rf -- "$container_release_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local output_base="NexusTerminal-${target_os}-${target_arch}"
|
||||
local container_out="${container_release_dir}/${version}"
|
||||
if [ ! -f "${container_out}/${output_base}" ] \
|
||||
|| [ ! -f "${container_out}/${output_base}.zip" ]; then
|
||||
warn "Container did not produce the expected artefacts for ${target}."
|
||||
rm -rf -- "$container_release_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cp "${container_out}/${output_base}" "${out_dir}/${output_base}"
|
||||
cp "${container_out}/${output_base}.zip" "${out_dir}/${output_base}.zip"
|
||||
echo "${target_os}|${target_arch}|${output_base}.zip" >> "${out_dir}/.release-files"
|
||||
rm -rf -- "$container_release_dir"
|
||||
}
|
||||
|
||||
build_target() {
|
||||
local target_os="$1"
|
||||
local target_arch="$2"
|
||||
@@ -288,7 +389,7 @@ main() {
|
||||
NEXUS_RELEASE_BASE_URL="${DEFAULT_RELEASE_BASE_URL}"
|
||||
fi
|
||||
|
||||
local release_root="build/releases"
|
||||
local release_root="${NEXUS_RELEASE_ROOT:-build/releases}"
|
||||
local out_dir="${release_root}/${version}"
|
||||
mkdir -p "$out_dir"
|
||||
|
||||
@@ -306,7 +407,26 @@ main() {
|
||||
fi
|
||||
|
||||
local errors=0
|
||||
local host
|
||||
host="$(host_os)"
|
||||
local target
|
||||
local container_linux_targets=()
|
||||
if [ "$host" != "linux" ]; then
|
||||
for target in "${targets[@]}"; do
|
||||
if [[ "$target" == linux/* ]]; then
|
||||
container_linux_targets+=("$target")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "${#container_linux_targets[@]}" -gt 0 ]; then
|
||||
for target in "${container_linux_targets[@]}"; do
|
||||
if ! build_linux_target_in_container "$target" "$version" "$out_dir"; then
|
||||
errors=1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
for target in "${targets[@]}"; do
|
||||
local target_os="${target%%/*}"
|
||||
local target_arch="${target##*/}"
|
||||
@@ -315,6 +435,9 @@ main() {
|
||||
errors=1
|
||||
continue
|
||||
fi
|
||||
if [ "$target_os" = "linux" ] && [ "$host" != "linux" ]; then
|
||||
continue
|
||||
fi
|
||||
if ! build_target "$target_os" "$target_arch" "$version" "$out_dir"; then
|
||||
errors=1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user