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:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,5 +9,6 @@ node_modules
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
dist/
|
||||
.cursor/
|
||||
.vscode/
|
||||
|
||||
10
README.md
10
README.md
@@ -33,6 +33,16 @@ npm run tauri dev
|
||||
npm run tauri build
|
||||
```
|
||||
|
||||
## Release Build
|
||||
|
||||
```bash
|
||||
npm run release
|
||||
```
|
||||
|
||||
This runs the full Tauri production build, ad-hoc code signs the `.app` bundle, and copies the output to `dist/release/`.
|
||||
|
||||
The resulting `GUI Video Clipper.app` can be launched directly or dragged to `/Applications`.
|
||||
|
||||
## Architecture
|
||||
|
||||
GUI Video Clipper is built with [Tauri v2](https://v2.tauri.app/) (Rust backend) and [Svelte 5](https://svelte.dev/) (TypeScript frontend).
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"preview": "vite preview",
|
||||
"test": "vitest run",
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json",
|
||||
"tauri": "tauri"
|
||||
"tauri": "tauri",
|
||||
"release": "bash scripts/build-release.sh"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
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\""
|
||||
@@ -34,7 +34,7 @@
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"targets": ["app", "dmg"],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
|
||||
Reference in New Issue
Block a user