feat: add release build script
- scripts/build-release.sh: builds, signs, and copies .app to dist/release/ - Bundle targets narrowed to app + dmg - npm run release convenience script - README documents the release build workflow Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
82
scripts/build-release.sh
Executable file
82
scripts/build-release.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
VERSION_FILE="$PROJECT_ROOT/VERSION"
|
||||
|
||||
# ── Read and validate version ──────────────────────────────────────
|
||||
if [ ! -f "$VERSION_FILE" ]; then
|
||||
echo "ERROR: VERSION file not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$(cat "$VERSION_FILE" | sed 's/^[vV]//' | tr -d '[:space:]')
|
||||
|
||||
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
echo "ERROR: '$VERSION' is not valid semver (expected X.Y.Z)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Building GUI Video Clipper v$VERSION ==="
|
||||
echo ""
|
||||
|
||||
# ── Install frontend dependencies ──────────────────────────────────
|
||||
echo "→ Installing dependencies…"
|
||||
cd "$PROJECT_ROOT"
|
||||
npm install --silent
|
||||
|
||||
# ── Run tauri build ────────────────────────────────────────────────
|
||||
echo "→ Building release (this may take a few minutes)…"
|
||||
BUILD_LOG=$(mktemp)
|
||||
npx tauri build 2>&1 | tee "$BUILD_LOG" | tail -10
|
||||
|
||||
# ── Locate built artifacts ─────────────────────────────────────────
|
||||
# Parse .app path from tauri build output (handles custom CARGO_TARGET_DIR)
|
||||
APP_SRC=$(grep '\.app$' "$BUILD_LOG" | head -1 | sed 's/^[[:space:]]*//')
|
||||
DMG_SRC=$(grep '\.dmg$' "$BUILD_LOG" | head -1 | sed 's/^[[:space:]]*//')
|
||||
rm -f "$BUILD_LOG"
|
||||
|
||||
# Fall back to standard location if parsing failed
|
||||
if [ -z "$APP_SRC" ] || [ ! -d "$APP_SRC" ]; then
|
||||
BUNDLE_DIR="$PROJECT_ROOT/src-tauri/target/release/bundle"
|
||||
APP_SRC="$BUNDLE_DIR/macos/GUI Video Clipper.app"
|
||||
fi
|
||||
|
||||
if [ ! -d "$APP_SRC" ]; then
|
||||
echo "ERROR: .app bundle not found" >&2
|
||||
echo "Check the build output above for errors." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Ad-hoc code sign ──────────────────────────────────────────────
|
||||
echo "→ Ad-hoc signing .app…"
|
||||
codesign --force --deep -s - "$APP_SRC"
|
||||
|
||||
# ── Copy to dist/release/ ─────────────────────────────────────────
|
||||
DIST_DIR="$PROJECT_ROOT/dist/release"
|
||||
mkdir -p "$DIST_DIR"
|
||||
|
||||
echo "→ Copying to dist/release/…"
|
||||
rm -rf "$DIST_DIR/GUI Video Clipper.app"
|
||||
cp -R "$APP_SRC" "$DIST_DIR/"
|
||||
|
||||
# Copy DMG if it was built
|
||||
DMG_FILE="$DMG_SRC"
|
||||
if [ -n "$DMG_FILE" ] && [ -f "$DMG_FILE" ]; then
|
||||
cp "$DMG_FILE" "$DIST_DIR/"
|
||||
echo " ✓ DMG: $(basename "$DMG_FILE")"
|
||||
fi
|
||||
|
||||
# ── Summary ────────────────────────────────────────────────────────
|
||||
APP_SIZE=$(du -sh "$DIST_DIR/GUI Video Clipper.app" | cut -f1)
|
||||
echo ""
|
||||
echo "=== Build Complete ==="
|
||||
echo " Version: v$VERSION"
|
||||
echo " App: dist/release/GUI Video Clipper.app ($APP_SIZE)"
|
||||
if [ -n "$DMG_FILE" ] && [ -f "$DIST_DIR/$(basename "$DMG_FILE")" ]; then
|
||||
DMG_SIZE=$(du -sh "$DIST_DIR/$(basename "$DMG_FILE")" | cut -f1)
|
||||
echo " DMG: dist/release/$(basename "$DMG_FILE") ($DMG_SIZE)"
|
||||
fi
|
||||
echo ""
|
||||
echo "To run: open \"dist/release/GUI Video Clipper.app\""
|
||||
Reference in New Issue
Block a user