archy/verify-build.sh

292 lines
7.8 KiB
Bash
Raw Normal View History

#!/bin/bash
# Production Build Verification Script
# Tests the built .app bundle before distribution
set -e
APP_BUNDLE="${1:-build/macos/Archipelago.app}"
echo "🔍 Archipelago Production Build Verification"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
FAILED=0
WARNINGS=0
pass() {
echo -e "${GREEN}$1${NC}"
}
fail() {
echo -e "${RED}$1${NC}"
FAILED=$((FAILED + 1))
}
warn() {
echo -e "${YELLOW}⚠️ $1${NC}"
WARNINGS=$((WARNINGS + 1))
}
# Check app bundle exists
echo "📦 Checking app bundle..."
if [ ! -d "$APP_BUNDLE" ]; then
fail "App bundle not found at: $APP_BUNDLE"
exit 1
fi
pass "App bundle exists"
# Check bundle structure
echo ""
echo "🏗️ Checking bundle structure..."
if [ -d "$APP_BUNDLE/Contents/MacOS" ]; then
pass "MacOS directory exists"
else
fail "MacOS directory missing"
fi
if [ -d "$APP_BUNDLE/Contents/Resources" ]; then
pass "Resources directory exists"
else
fail "Resources directory missing"
fi
if [ -f "$APP_BUNDLE/Contents/Info.plist" ]; then
pass "Info.plist exists"
else
fail "Info.plist missing"
fi
if [ -f "$APP_BUNDLE/Contents/PkgInfo" ]; then
pass "PkgInfo exists"
else
fail "PkgInfo missing"
fi
# Check executables
echo ""
echo "⚙️ Checking executables..."
if [ -f "$APP_BUNDLE/Contents/MacOS/archipelago" ]; then
pass "Backend binary exists"
# Check if executable
if [ -x "$APP_BUNDLE/Contents/MacOS/archipelago" ]; then
pass "Backend binary is executable"
else
fail "Backend binary is not executable"
fi
# Check architecture
ARCH=$(lipo -info "$APP_BUNDLE/Contents/MacOS/archipelago" 2>&1)
echo " Architecture: $ARCH"
else
fail "Backend binary missing"
fi
if [ -f "$APP_BUNDLE/Contents/MacOS/launch.sh" ]; then
pass "Launch script exists"
if [ -x "$APP_BUNDLE/Contents/MacOS/launch.sh" ]; then
pass "Launch script is executable"
else
fail "Launch script is not executable"
fi
else
fail "Launch script missing"
fi
if [ -f "$APP_BUNDLE/Contents/MacOS/manage-docker.sh" ]; then
pass "Docker manager script exists"
else
warn "Docker manager script missing (optional)"
fi
# Check resources
echo ""
echo "📁 Checking resources..."
if [ -d "$APP_BUNDLE/Contents/Resources/frontend" ]; then
pass "Frontend directory exists"
if [ -f "$APP_BUNDLE/Contents/Resources/frontend/index.html" ]; then
pass "Frontend index.html exists"
else
fail "Frontend index.html missing"
fi
else
fail "Frontend directory missing"
fi
if [ -d "$APP_BUNDLE/Contents/Resources/docker-ui" ]; then
pass "Docker UI directory exists"
if [ -d "$APP_BUNDLE/Contents/Resources/docker-ui/bitcoin-ui" ]; then
pass "Bitcoin UI exists"
else
warn "Bitcoin UI missing"
fi
if [ -d "$APP_BUNDLE/Contents/Resources/docker-ui/lnd-ui" ]; then
pass "LND UI exists"
else
warn "LND UI missing"
fi
else
warn "Docker UI directory missing (optional)"
fi
if [ -f "$APP_BUNDLE/Contents/Resources/docker-compose.yml" ]; then
pass "Docker compose file exists"
else
warn "Docker compose file missing (optional)"
fi
if [ -f "$APP_BUNDLE/Contents/Resources/AppIcon.icns" ]; then
pass "App icon exists"
else
warn "App icon missing - will use default"
fi
# Check Info.plist content
echo ""
echo "📄 Validating Info.plist..."
BUNDLE_ID=$(defaults read "$APP_BUNDLE/Contents/Info.plist" CFBundleIdentifier 2>/dev/null)
if [ -n "$BUNDLE_ID" ]; then
pass "Bundle ID: $BUNDLE_ID"
else
fail "Bundle ID not found"
fi
VERSION=$(defaults read "$APP_BUNDLE/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null)
if [ -n "$VERSION" ]; then
pass "Version: $VERSION"
else
warn "Version not found"
fi
EXECUTABLE=$(defaults read "$APP_BUNDLE/Contents/Info.plist" CFBundleExecutable 2>/dev/null)
if [ -n "$EXECUTABLE" ]; then
pass "Executable: $EXECUTABLE"
else
fail "Executable not specified"
fi
# Check code signature
echo ""
echo "🔐 Checking code signature..."
if codesign -v "$APP_BUNDLE" 2>/dev/null; then
pass "App is code signed"
# Get signature info
SIGNATURE=$(codesign -dvv "$APP_BUNDLE" 2>&1 | grep "Authority=" | head -1)
echo " $SIGNATURE"
# Check if hardened runtime is enabled
if codesign -dvv "$APP_BUNDLE" 2>&1 | grep -q "flags=0x10000"; then
pass "Hardened runtime enabled"
else
warn "Hardened runtime not enabled (recommended for notarization)"
fi
else
warn "App is not code signed (required for distribution)"
fi
# Check notarization
echo ""
echo "📝 Checking notarization..."
if spctl --assess --type execute --verbose "$APP_BUNDLE" 2>&1 | grep -q "accepted"; then
pass "App is notarized"
else
warn "App is not notarized (required for macOS 10.15+)"
fi
# Check for common issues
echo ""
echo "🔍 Checking for common issues..."
# Check for hardcoded paths
if grep -r "/Users/" "$APP_BUNDLE/Contents/MacOS/" 2>/dev/null | grep -v "Library/Application" >/dev/null; then
warn "Found hardcoded user paths in binaries"
fi
# Check for debug symbols (should be stripped)
if nm "$APP_BUNDLE/Contents/MacOS/archipelago" 2>/dev/null | grep -q "debug"; then
warn "Debug symbols present - consider stripping for smaller size"
fi
# Check bundle size
echo ""
echo "📏 Bundle size..."
BUNDLE_SIZE=$(du -sh "$APP_BUNDLE" | cut -f1)
echo " Total size: $BUNDLE_SIZE"
if [ -d "$APP_BUNDLE/Contents/Resources/frontend" ]; then
FRONTEND_SIZE=$(du -sh "$APP_BUNDLE/Contents/Resources/frontend" | cut -f1)
echo " Frontend: $FRONTEND_SIZE"
fi
BACKEND_SIZE=$(du -sh "$APP_BUNDLE/Contents/MacOS/archipelago" | cut -f1)
echo " Backend: $BACKEND_SIZE"
# Summary
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Verification Summary"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
if [ $FAILED -eq 0 ]; then
if [ $WARNINGS -eq 0 ]; then
pass "All checks passed! 🎉"
echo ""
echo "✅ Ready for distribution"
else
echo -e "${YELLOW}⚠️ Passed with $WARNINGS warning(s)${NC}"
echo ""
echo "Build is usable but has some warnings (see above)"
fi
else
echo -e "${RED}❌ Failed: $FAILED critical issue(s)${NC}"
echo -e "${YELLOW}⚠️ Warnings: $WARNINGS${NC}"
echo ""
echo "⛔ Build has critical issues - DO NOT distribute"
exit 1
fi
# Next steps
echo ""
echo "🚀 Next Steps:"
echo ""
if codesign -v "$APP_BUNDLE" 2>/dev/null && spctl --assess --type execute "$APP_BUNDLE" 2>&1 | grep -q "accepted"; then
echo " 1. ✅ App is signed and notarized"
echo " 2. Create DMG: hdiutil create -volname \"Archipelago\" \\"
echo " -srcfolder \"$APP_BUNDLE\" \\"
echo " -ov -format UDZO Archipelago.dmg"
echo " 3. Distribute via GitHub Releases or website"
else
echo " 1. Code sign the app:"
echo " codesign --deep --force --verify --verbose \\"
echo " --sign \"Developer ID Application: Your Name\" \\"
echo " --options runtime \"$APP_BUNDLE\""
echo ""
echo " 2. Notarize the app:"
echo " ditto -c -k --keepParent \"$APP_BUNDLE\" Archipelago.zip"
echo " xcrun notarytool submit Archipelago.zip ..."
echo ""
echo " 3. Create DMG after notarization"
fi
echo ""
echo "📖 For detailed instructions, see BUILD_MACOS.md"
echo ""