mirror of
https://seed.radicle.dev/rad:z4D5UCArafTzTQpDZNQRuqswh3ury.git
synced 2026-10-24 22:10:34 +08:00
Builds macOS DMG, Linux amd64 deb and AppImage from a single macOS Apple Silicon machine using Podman containers. See RELEASE.md and scripts/release for details. Replaces Woodpecker CI with GitHub Actions workflows for lint, unit tests, e2e tests, and Arch package validation.
174 lines
5.5 KiB
Bash
Executable File
174 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Build release artifacts for all platforms.
|
|
#
|
|
# Usage: scripts/release [OPTIONS]
|
|
#
|
|
# Options:
|
|
# --only-dmg Build macOS aarch64 DMG only
|
|
# --only-deb Build Linux amd64 deb only
|
|
# --only-appimage Build Linux amd64 AppImage only
|
|
# --rebuild-image Force rebuild of podman container images
|
|
# --clean Wipe target-release/, node_modules/ and Linux build volumes
|
|
# --help Show this help
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
# ---- Flags ----
|
|
|
|
BUILD_DMG=true
|
|
BUILD_DEB=true
|
|
BUILD_APPIMAGE=true
|
|
REBUILD_IMAGE=false
|
|
CLEAN=false
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--only-dmg) BUILD_DMG=true; BUILD_DEB=false; BUILD_APPIMAGE=false ;;
|
|
--only-deb) BUILD_DMG=false; BUILD_DEB=true; BUILD_APPIMAGE=false ;;
|
|
--only-appimage) BUILD_DMG=false; BUILD_DEB=false; BUILD_APPIMAGE=true ;;
|
|
--rebuild-image) REBUILD_IMAGE=true ;;
|
|
--clean) CLEAN=true; BUILD_DMG=false; BUILD_DEB=false; BUILD_APPIMAGE=false ;;
|
|
--help|-h)
|
|
head -20 "$0" | grep '^#' | sed 's/^# \?//'
|
|
exit 0
|
|
;;
|
|
*) echo "Unknown option: $arg" >&2; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
# ---- Helpers ----
|
|
|
|
step() { echo; echo "==> $*"; }
|
|
|
|
# Builds a container image if it does not already exist (or --rebuild-image).
|
|
# $1: image name, $2: dockerfile path (relative to PROJECT_DIR), $3: platform
|
|
ensure_image() {
|
|
local name="$1"
|
|
local dockerfile="$2"
|
|
local platform="$3"
|
|
if [[ "$REBUILD_IMAGE" == true ]] || ! podman image exists "$name" 2>/dev/null; then
|
|
echo " Building container image: $name"
|
|
podman build \
|
|
--platform "$platform" \
|
|
-t "$name" \
|
|
-f "$PROJECT_DIR/$dockerfile" \
|
|
"$PROJECT_DIR"
|
|
fi
|
|
}
|
|
|
|
# ---- Version and output directory ----
|
|
|
|
VERSION="$(jq -r '.version' "$PROJECT_DIR/crates/radicle-tauri/tauri.conf.json")"
|
|
RELEASE_SHA="$(git -C "$PROJECT_DIR" rev-parse HEAD)"
|
|
SHORT_SHA="$(git -C "$PROJECT_DIR" rev-parse --short=8 HEAD)"
|
|
RELEASE_DIR="$PROJECT_DIR/releases/v$VERSION"
|
|
|
|
step "Building release v$VERSION (${SHORT_SHA})"
|
|
echo " Output: $RELEASE_DIR"
|
|
mkdir -p "$RELEASE_DIR"
|
|
|
|
# ---- Clean ----
|
|
|
|
if [[ "$CLEAN" == true ]]; then
|
|
step "Cleaning build artifacts"
|
|
rm -rf "$PROJECT_DIR/target-release"
|
|
rm -rf "$PROJECT_DIR/node_modules"
|
|
podman volume rm radicle-desktop-linux-target radicle-desktop-linux-nm radicle-desktop-linux-cargo 2>/dev/null || true
|
|
podman image rm radicle-desktop-release-builder 2>/dev/null || true
|
|
echo " Cleaned"
|
|
fi
|
|
|
|
# ---- macOS aarch64 DMG ----
|
|
|
|
if [[ "$BUILD_DMG" == true ]]; then
|
|
step "Building macOS aarch64 DMG"
|
|
cd "$PROJECT_DIR"
|
|
npm install
|
|
CARGO_TARGET_DIR="$PROJECT_DIR/target-release" \
|
|
npm exec -- tauri build --bundles dmg
|
|
cp "target-release/release/bundle/dmg/Radicle_${VERSION}_aarch64.dmg" \
|
|
"$RELEASE_DIR/radicle-desktop-aarch64.dmg"
|
|
echo " radicle-desktop-aarch64.dmg"
|
|
fi
|
|
|
|
# ---- Linux amd64 deb ----
|
|
#
|
|
# Runs in the native ARM64 Ubuntu container, which cross-compiles Rust to
|
|
# x86_64. Build artifacts are cached in named podman volumes so subsequent
|
|
# runs only recompile what changed.
|
|
#
|
|
# When to clear volumes:
|
|
# After a Rust toolchain bump or dependency change that confuses incremental
|
|
# compilation: podman volume rm radicle-desktop-linux-target radicle-desktop-linux-cargo
|
|
# After a major npm dependency change: podman volume rm radicle-desktop-linux-nm
|
|
|
|
if [[ "$BUILD_DEB" == true ]]; then
|
|
step "Building Linux amd64 deb"
|
|
ensure_image "radicle-desktop-release-builder" "Dockerfile.release" "linux/arm64"
|
|
|
|
podman run --rm \
|
|
-v "$PROJECT_DIR:/workspace:z" \
|
|
-v radicle-desktop-linux-target:/workspace/target:z \
|
|
-v radicle-desktop-linux-nm:/workspace/node_modules:z \
|
|
-v radicle-desktop-linux-cargo:/root/.cargo/registry:z \
|
|
-v "$RELEASE_DIR:/output:z" \
|
|
-w /workspace \
|
|
-e CI=true \
|
|
radicle-desktop-release-builder \
|
|
bash -c "
|
|
set -euo pipefail
|
|
npm ci
|
|
npm exec -- tauri build --target x86_64-unknown-linux-gnu --bundles deb
|
|
cp target/x86_64-unknown-linux-gnu/release/bundle/deb/*.deb /output/
|
|
"
|
|
|
|
echo " radicle-desktop_${VERSION}_amd64.deb"
|
|
fi
|
|
|
|
# ---- Linux amd64 AppImage ----
|
|
#
|
|
# See scripts/appimage-build for the full setup. Key points:
|
|
# - --privileged to mount binfmt_misc for x86_64 emulation via QEMU
|
|
# - APPIMAGE_EXTRACT_AND_RUN=1 so linuxdeploy-x86_64.AppImage runs without FUSE
|
|
# - PKG_CONFIG_PATH for the GTK plugin to find amd64 packages
|
|
# - PATH includes libgtk-3-0t64 dir where gtk-query-immodules-3.0 lives
|
|
# The script is mounted from the workspace (heredocs pipe to host, not container)
|
|
|
|
if [[ "$BUILD_APPIMAGE" == true ]]; then
|
|
step "Building Linux amd64 AppImage"
|
|
ensure_image "radicle-desktop-release-builder" "Dockerfile.release" "linux/arm64"
|
|
|
|
podman run --rm \
|
|
--privileged \
|
|
-v "$PROJECT_DIR:/workspace:z" \
|
|
-v radicle-desktop-linux-target:/workspace/target:z \
|
|
-v radicle-desktop-linux-nm:/workspace/node_modules:z \
|
|
-v radicle-desktop-linux-cargo:/root/.cargo/registry:z \
|
|
-v "$RELEASE_DIR:/output:z" \
|
|
-w /workspace \
|
|
-e CI=true \
|
|
radicle-desktop-release-builder \
|
|
bash /workspace/scripts/appimage-build
|
|
|
|
echo " radicle-desktop_${VERSION}_amd64.AppImage"
|
|
fi
|
|
|
|
if [[ "$CLEAN" == false ]]; then
|
|
# ---- latest.json ----
|
|
|
|
step "Generating latest.json"
|
|
printf '{"sha": "%s", "version": "%s"}' "$RELEASE_SHA" "$VERSION" \
|
|
> "$RELEASE_DIR/latest.json"
|
|
echo " latest.json"
|
|
|
|
# ---- Summary ----
|
|
|
|
echo
|
|
echo "Done. Artifacts in $RELEASE_DIR:"
|
|
ls -lh "$RELEASE_DIR"
|
|
fi
|