- Revamped README.md to enhance clarity and detail on features, installation, and system requirements for Archipelago. - Added macOS-specific configuration in `config.rs` to detect when running from a macOS app bundle, adjusting data directory paths accordingly. - Introduced a new production build script in `package.json` for optimized deployment of the Neode UI.
291 lines
10 KiB
Bash
Executable File
291 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
# Archipelago Production macOS Build Script
|
|
# Creates a production-ready .app bundle and .dmg installer
|
|
|
|
set -e
|
|
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
APP_NAME="Archipelago"
|
|
APP_VERSION="${ARCHIPELAGO_VERSION:-0.1.0}"
|
|
BUILD_DIR="$PROJECT_ROOT/build/macos"
|
|
APP_BUNDLE="$BUILD_DIR/$APP_NAME.app"
|
|
DMG_NAME="Archipelago-${APP_VERSION}-macOS.dmg"
|
|
|
|
echo "🏗️ Archipelago macOS Production Build"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo " Version: $APP_VERSION"
|
|
echo " Target: macOS App Bundle + DMG Installer"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
# Clean previous build
|
|
echo "🧹 Cleaning previous build..."
|
|
rm -rf "$BUILD_DIR"
|
|
mkdir -p "$BUILD_DIR"
|
|
|
|
# Step 1: Build Rust Backend (Release Mode)
|
|
echo ""
|
|
echo "⚙️ Step 1/6: Building Rust backend (release mode)..."
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
cd "$PROJECT_ROOT/core"
|
|
cargo build --release --workspace
|
|
|
|
if [ ! -f "target/release/archipelago" ]; then
|
|
echo "❌ Backend build failed - archipelago binary not found"
|
|
exit 1
|
|
fi
|
|
|
|
# Get binary size
|
|
BACKEND_SIZE=$(du -h target/release/archipelago | cut -f1)
|
|
echo "✅ Backend built successfully ($BACKEND_SIZE)"
|
|
|
|
# Step 2: Build Vue.js Frontend (Production Mode)
|
|
echo ""
|
|
echo "🎨 Step 2/6: Building Vue.js frontend (production mode)..."
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
cd "$PROJECT_ROOT/neode-ui"
|
|
|
|
# Check if node_modules exists
|
|
if [ ! -d "node_modules" ]; then
|
|
echo "📦 Installing frontend dependencies..."
|
|
npm install
|
|
fi
|
|
|
|
# Build production frontend
|
|
npm run build
|
|
|
|
if [ ! -d "dist" ]; then
|
|
echo "❌ Frontend build failed - dist directory not found"
|
|
exit 1
|
|
fi
|
|
|
|
# Get build size
|
|
FRONTEND_SIZE=$(du -sh dist | cut -f1)
|
|
echo "✅ Frontend built successfully ($FRONTEND_SIZE)"
|
|
|
|
# Step 3: Create macOS App Bundle Structure
|
|
echo ""
|
|
echo "📦 Step 3/6: Creating macOS app bundle..."
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
# Create standard macOS .app directory structure
|
|
mkdir -p "$APP_BUNDLE/Contents/MacOS"
|
|
mkdir -p "$APP_BUNDLE/Contents/Resources"
|
|
mkdir -p "$APP_BUNDLE/Contents/Frameworks"
|
|
|
|
# Copy backend binary
|
|
echo " • Copying backend binary..."
|
|
cp "$PROJECT_ROOT/core/target/release/archipelago" "$APP_BUNDLE/Contents/MacOS/"
|
|
chmod +x "$APP_BUNDLE/Contents/MacOS/archipelago"
|
|
|
|
# Copy frontend build
|
|
echo " • Copying frontend assets..."
|
|
cp -R "$PROJECT_ROOT/neode-ui/dist" "$APP_BUNDLE/Contents/Resources/frontend"
|
|
|
|
# Copy Docker UI assets
|
|
echo " • Copying Docker UI assets..."
|
|
mkdir -p "$APP_BUNDLE/Contents/Resources/docker-ui"
|
|
cp -R "$PROJECT_ROOT/docker/bitcoin-ui" "$APP_BUNDLE/Contents/Resources/docker-ui/"
|
|
cp -R "$PROJECT_ROOT/docker/lnd-ui" "$APP_BUNDLE/Contents/Resources/docker-ui/"
|
|
|
|
# Copy configuration templates
|
|
echo " • Copying configuration..."
|
|
cp "$PROJECT_ROOT/core/.env.example" "$APP_BUNDLE/Contents/Resources/env.template"
|
|
cp "$PROJECT_ROOT/core/.env.production" "$APP_BUNDLE/Contents/Resources/env.production"
|
|
|
|
# Copy docker-compose.yml for production
|
|
echo " • Copying Docker configuration..."
|
|
cp "$PROJECT_ROOT/docker-compose.yml" "$APP_BUNDLE/Contents/Resources/"
|
|
cp "$PROJECT_ROOT/manage-docker.sh" "$APP_BUNDLE/Contents/MacOS/"
|
|
chmod +x "$APP_BUNDLE/Contents/MacOS/manage-docker.sh"
|
|
|
|
# Create launch script
|
|
echo " • Creating launcher script..."
|
|
cat > "$APP_BUNDLE/Contents/MacOS/launch.sh" << 'LAUNCH_EOF'
|
|
#!/bin/bash
|
|
# Archipelago macOS Launcher
|
|
|
|
# Get the directory containing this script
|
|
BUNDLE_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
RESOURCES_DIR="$BUNDLE_DIR/Resources"
|
|
MACOS_DIR="$BUNDLE_DIR/MacOS"
|
|
|
|
# Set up data directory in user's home
|
|
DATA_DIR="$HOME/Library/Application Support/Archipelago"
|
|
mkdir -p "$DATA_DIR/data"
|
|
mkdir -p "$DATA_DIR/logs"
|
|
|
|
# Export environment variables
|
|
export ARCHIPELAGO_DATA_DIR="$DATA_DIR/data"
|
|
export ARCHIPELAGO_FRONTEND_DIR="$RESOURCES_DIR/frontend"
|
|
export ARCHIPELAGO_DOCKER_UI_DIR="$RESOURCES_DIR/docker-ui"
|
|
export ARCHIPELAGO_LOG_DIR="$DATA_DIR/logs"
|
|
export RUST_LOG="${RUST_LOG:-info}"
|
|
|
|
# Launch backend
|
|
cd "$DATA_DIR"
|
|
exec "$MACOS_DIR/archipelago" > "$DATA_DIR/logs/archipelago.log" 2>&1
|
|
LAUNCH_EOF
|
|
|
|
chmod +x "$APP_BUNDLE/Contents/MacOS/launch.sh"
|
|
|
|
# Step 4: Create Info.plist
|
|
echo ""
|
|
echo "📄 Step 4/6: Creating app metadata..."
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
cat > "$APP_BUNDLE/Contents/Info.plist" << PLIST_EOF
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>CFBundleName</key>
|
|
<string>Archipelago</string>
|
|
<key>CFBundleDisplayName</key>
|
|
<string>Archipelago</string>
|
|
<key>CFBundleIdentifier</key>
|
|
<string>com.archipelago.app</string>
|
|
<key>CFBundleVersion</key>
|
|
<string>$APP_VERSION</string>
|
|
<key>CFBundleShortVersionString</key>
|
|
<string>$APP_VERSION</string>
|
|
<key>CFBundlePackageType</key>
|
|
<string>APPL</string>
|
|
<key>CFBundleSignature</key>
|
|
<string>ARCH</string>
|
|
<key>CFBundleExecutable</key>
|
|
<string>launch.sh</string>
|
|
<key>CFBundleIconFile</key>
|
|
<string>AppIcon</string>
|
|
<key>NSHighResolutionCapable</key>
|
|
<true/>
|
|
<key>LSMinimumSystemVersion</key>
|
|
<string>10.15</string>
|
|
<key>LSApplicationCategoryType</key>
|
|
<string>public.app-category.utilities</string>
|
|
<key>NSHumanReadableCopyright</key>
|
|
<string>Copyright © 2026 Archipelago. All rights reserved.</string>
|
|
<key>LSBackgroundOnly</key>
|
|
<false/>
|
|
<key>NSRequiresAquaSystemAppearance</key>
|
|
<false/>
|
|
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
|
<true/>
|
|
</dict>
|
|
</plist>
|
|
PLIST_EOF
|
|
|
|
echo "✅ Info.plist created"
|
|
|
|
# Create PkgInfo
|
|
echo -n "APPLARCH" > "$APP_BUNDLE/Contents/PkgInfo"
|
|
|
|
# Step 5: Create App Icon (placeholder - user should provide real icon)
|
|
echo ""
|
|
echo "🎨 Step 5/6: Creating app icon..."
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
# Check if sips command is available (macOS built-in)
|
|
if command -v sips >/dev/null 2>&1; then
|
|
# Try to find a logo to convert
|
|
LOGO_SOURCE=""
|
|
if [ -f "$PROJECT_ROOT/neode-ui/public/assets/img/logo.png" ]; then
|
|
LOGO_SOURCE="$PROJECT_ROOT/neode-ui/public/assets/img/logo.png"
|
|
elif [ -f "$PROJECT_ROOT/neode-ui/public/assets/img/app-icons/bitcoin-core.png" ]; then
|
|
LOGO_SOURCE="$PROJECT_ROOT/neode-ui/public/assets/img/app-icons/bitcoin-core.png"
|
|
fi
|
|
|
|
if [ -n "$LOGO_SOURCE" ]; then
|
|
# Create iconset
|
|
ICONSET_DIR="$BUILD_DIR/AppIcon.iconset"
|
|
mkdir -p "$ICONSET_DIR"
|
|
|
|
# Generate icon sizes
|
|
for size in 16 32 128 256 512; do
|
|
sips -z $size $size "$LOGO_SOURCE" --out "$ICONSET_DIR/icon_${size}x${size}.png" >/dev/null 2>&1
|
|
sips -z $((size*2)) $((size*2)) "$LOGO_SOURCE" --out "$ICONSET_DIR/icon_${size}x${size}@2x.png" >/dev/null 2>&1
|
|
done
|
|
|
|
# Convert to icns
|
|
iconutil -c icns "$ICONSET_DIR" -o "$APP_BUNDLE/Contents/Resources/AppIcon.icns" 2>/dev/null || {
|
|
echo "⚠️ Icon conversion failed - app will use default icon"
|
|
}
|
|
|
|
rm -rf "$ICONSET_DIR"
|
|
echo "✅ App icon created from $LOGO_SOURCE"
|
|
else
|
|
echo "⚠️ No logo found - app will use default icon"
|
|
echo " Add logo.png to neode-ui/public/assets/img/ and rebuild"
|
|
fi
|
|
else
|
|
echo "⚠️ sips not available - skipping icon creation"
|
|
fi
|
|
|
|
# Step 6: Create DMG Installer
|
|
echo ""
|
|
echo "💿 Step 6/6: Creating DMG installer..."
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
|
|
DMG_TEMP_DIR="$BUILD_DIR/dmg"
|
|
mkdir -p "$DMG_TEMP_DIR"
|
|
|
|
# Copy app to DMG staging
|
|
cp -R "$APP_BUNDLE" "$DMG_TEMP_DIR/"
|
|
|
|
# Create Applications symlink
|
|
ln -s /Applications "$DMG_TEMP_DIR/Applications"
|
|
|
|
# Create DMG
|
|
hdiutil create -volname "Archipelago $APP_VERSION" \
|
|
-srcfolder "$DMG_TEMP_DIR" \
|
|
-ov -format UDZO \
|
|
"$BUILD_DIR/$DMG_NAME" 2>/dev/null || {
|
|
echo "⚠️ DMG creation failed - using app bundle only"
|
|
}
|
|
|
|
# Cleanup
|
|
rm -rf "$DMG_TEMP_DIR"
|
|
|
|
# Summary
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "✅ Production build complete!"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
echo "📦 Build artifacts:"
|
|
echo " • App Bundle: $APP_BUNDLE"
|
|
if [ -f "$BUILD_DIR/$DMG_NAME" ]; then
|
|
DMG_SIZE=$(du -h "$BUILD_DIR/$DMG_NAME" | cut -f1)
|
|
echo " • DMG Installer: $BUILD_DIR/$DMG_NAME ($DMG_SIZE)"
|
|
fi
|
|
echo ""
|
|
echo "📋 Build summary:"
|
|
echo " • Backend: $BACKEND_SIZE (Rust)"
|
|
echo " • Frontend: $FRONTEND_SIZE (Vue.js)"
|
|
BUNDLE_SIZE=$(du -sh "$APP_BUNDLE" | cut -f1)
|
|
echo " • Total Bundle: $BUNDLE_SIZE"
|
|
echo ""
|
|
echo "🚀 Next steps:"
|
|
echo " 1. Test the app:"
|
|
echo " open \"$APP_BUNDLE\""
|
|
echo ""
|
|
echo " 2. Install system-wide:"
|
|
echo " cp -R \"$APP_BUNDLE\" /Applications/"
|
|
echo ""
|
|
echo " 3. Distribute via DMG:"
|
|
if [ -f "$BUILD_DIR/$DMG_NAME" ]; then
|
|
echo " • Share: $BUILD_DIR/$DMG_NAME"
|
|
else
|
|
echo " • (DMG creation skipped - use app bundle directly)"
|
|
fi
|
|
echo ""
|
|
echo " 4. Code signing (optional but recommended):"
|
|
echo " codesign --deep --force --verify --verbose \\
|
|
--sign \"Developer ID Application: Your Name\" \\
|
|
\"$APP_BUNDLE\""
|
|
echo ""
|
|
echo "💡 For notarization (macOS 10.14.5+):"
|
|
echo " • Requires Apple Developer account"
|
|
echo " • Use: xcrun notarytool submit $DMG_NAME ..."
|
|
echo ""
|