Skip to content

Build Standalone Application #17

Build Standalone Application

Build Standalone Application #17

Workflow file for this run

name: Build Standalone Application
on:
# Manual trigger
workflow_dispatch:
# Key: Give GITHUB_TOKEN write permissions (contents: write), otherwise cannot create releases
permissions:
contents: write
jobs:
build_and_release:
runs-on: macos-latest
steps:
# 1. Check out repository code
- name: Check out repository
uses: actions/checkout@v2
# 2. Set up Python 3.9
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
# 3. Install dependencies
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install pyinstaller
# Install Pillow for icon conversion if needed
pip install Pillow
# 3.5. Create app icon if not exists
- name: Create app icon
run: |
# Create a simple icon using Python if no icon file exists
if [ ! -f "icon.icns" ]; then
python3 << 'EOF'
import os
try:
from PIL import Image, ImageDraw, ImageFont
# Create a 1024x1024 icon with a search magnifying glass
size = 1024
img = Image.new('RGBA', (size, size), (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
# Draw a modern search icon
center = size // 2
circle_radius = size // 3
handle_width = size // 20
# Main circle (magnifying glass lens)
circle_bbox = [
center - circle_radius,
center - circle_radius - size // 10,
center + circle_radius,
center + circle_radius - size // 10
]
draw.ellipse(circle_bbox, outline=(70, 130, 220, 255), width=size//40)
# Handle of magnifying glass
handle_start_x = center + circle_radius * 0.7
handle_start_y = center + circle_radius * 0.7 - size // 10
handle_end_x = center + circle_radius * 1.3
handle_end_y = center + circle_radius * 1.3 - size // 10
draw.line([
(handle_start_x, handle_start_y),
(handle_end_x, handle_end_y)
], fill=(70, 130, 220, 255), width=handle_width)
# Add a subtle gradient background circle
bg_circle = [50, 50, size-50, size-50]
draw.ellipse(bg_circle, fill=(245, 245, 250, 100))
# Save as PNG first
img.save('icon.png')
print("Created icon.png")
# Convert to different sizes for icns
sizes = [16, 32, 64, 128, 256, 512, 1024]
icon_images = []
for s in sizes:
resized = img.resize((s, s), Image.Resampling.LANCZOS)
icon_images.append(resized)
# Save the largest as the main icon
img.save('icon.icns')
print("Created icon.icns")
except ImportError:
print("Pillow not available, will use default icon")
except Exception as e:
print(f"Icon creation failed: {e}, will use default icon")
EOF
fi
# 4. Build standalone applications for both architectures
- name: Build standalone application
run: |
# Check if icon exists and add icon parameter
ICON_PARAM=""
if [ -f "icon.icns" ]; then
ICON_PARAM="--icon=icon.icns"
echo "Using custom icon: icon.icns"
else
echo "No custom icon found, using default"
fi
# Create x86_64 version - use --onedir for faster startup
pyinstaller --target-architecture x86_64 --onedir --windowed --noconsole $ICON_PARAM everything.py
mkdir -p dist_x86_64
mv dist/everything dist_x86_64/
# Clean build files
rm -rf build dist
# Create arm64 version - use --onedir for faster startup
pyinstaller --target-architecture arm64 --onedir --windowed --noconsole $ICON_PARAM everything.py
mkdir -p dist_arm64
mv dist/everything dist_arm64/
# 5. Create macOS app bundles and installers
- name: Create macOS app bundles and installers
run: |
# Create app bundle structure for x86_64
mkdir -p "Everything by mdfind x86_64.app/Contents/MacOS"
mkdir -p "Everything by mdfind x86_64.app/Contents/Resources"
mkdir -p "Everything by mdfind x86_64.app/Contents/Frameworks"
# Copy entire application directory (onedir output includes all dependencies)
cp -R dist_x86_64/everything/* "Everything by mdfind x86_64.app/Contents/MacOS/"
# Copy icon to Resources if it exists
if [ -f "icon.icns" ]; then
cp icon.icns "Everything by mdfind x86_64.app/Contents/Resources/"
fi
# Create Info.plist for x86_64
cat > "Everything by mdfind x86_64.app/Contents/Info.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>CFBundleExecutable</key>
<string>everything</string>
<key>CFBundleIdentifier</key>
<string>com.appledragon.everythingbymdfind</string>
<key>CFBundleName</key>
<string>Everything by mdfind</string>
<key>CFBundleDisplayName</key>
<string>Everything by mdfind</string>
<key>CFBundleVersion</key>
<string>1.3.3</string>
<key>CFBundleShortVersionString</key>
<string>1.3.3</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>icon</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>NSAppleEventsUsageDescription</key>
<string>This app needs Apple Events access to interact with Spotlight for file searching.</string>
<key>NSDesktopFolderUsageDescription</key>
<string>This app needs access to your Desktop folder to search for files.</string>
<key>NSDocumentsFolderUsageDescription</key>
<string>This app needs access to your Documents folder to search for files.</string>
<key>NSDownloadsFolderUsageDescription</key>
<string>This app needs access to your Downloads folder to search for files.</string>
</dict>
</plist>
EOF
# Create app bundle structure for arm64
mkdir -p "Everything by mdfind arm64.app/Contents/MacOS"
mkdir -p "Everything by mdfind arm64.app/Contents/Resources"
mkdir -p "Everything by mdfind arm64.app/Contents/Frameworks"
# Copy entire application directory (onedir output includes all dependencies)
cp -R dist_arm64/everything/* "Everything by mdfind arm64.app/Contents/MacOS/"
# Copy icon to Resources if it exists
if [ -f "icon.icns" ]; then
cp icon.icns "Everything by mdfind arm64.app/Contents/Resources/"
fi
# Create Info.plist for arm64
cat > "Everything by mdfind arm64.app/Contents/Info.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>CFBundleExecutable</key>
<string>everything</string>
<key>CFBundleIdentifier</key>
<string>com.appledragon.everythingbymdfind</string>
<key>CFBundleName</key>
<string>Everything by mdfind</string>
<key>CFBundleDisplayName</key>
<string>Everything by mdfind</string>
<key>CFBundleVersion</key>
<string>1.3.3</string>
<key>CFBundleShortVersionString</key>
<string>1.3.3</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>icon</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>NSAppleEventsUsageDescription</key>
<string>This app needs Apple Events access to interact with Spotlight for file searching.</string>
<key>NSDesktopFolderUsageDescription</key>
<string>This app needs access to your Desktop folder to search for files.</string>
<key>NSDocumentsFolderUsageDescription</key>
<string>This app needs access to your Documents folder to search for files.</string>
<key>NSDownloadsFolderUsageDescription</key>
<string>This app needs access to your Downloads folder to search for files.</string>
</dict>
</plist>
EOF
# Create installer packages
pkgbuild --root "Everything by mdfind x86_64.app" \
--identifier "com.appledragon.everythingbymdfind.x86_64" \
--version "1.3.3" \
--install-location "/Applications/Everything by mdfind x86_64.app" \
"everything-x86_64.pkg"
pkgbuild --root "Everything by mdfind arm64.app" \
--identifier "com.appledragon.everythingbymdfind.arm64" \
--version "1.3.3" \
--install-location "/Applications/Everything by mdfind arm64.app" \
"everything-arm64.pkg"
# Also create zip files for direct download
zip -r "everything-x86_64-app.zip" "Everything by mdfind x86_64.app"
zip -r "everything-arm64-app.zip" "Everything by mdfind arm64.app"
# 6. Create GitHub Release
- name: Create GitHub release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: 'v1.3.3'
release_name: 'Everything by mdfind v1.3.3'
body: |
## Everything by mdfind v1.3.3
### New Features
- Added file compression functionality with ZIP support
- Enhanced dialog with "Open in Finder" option after compression
- **PERFORMANCE IMPROVEMENT**: Fixed slow startup issue by using directory-based packaging instead of single-file
### Installation Options
**Option 1: macOS Installer Package (.pkg)** - RECOMMENDED
- Download the .pkg file for your architecture
- Double-click to install like any standard Mac application
- The app will be installed to /Applications folder
- **Fast startup** - no more extraction delays!
**Option 2: App Bundle (.zip)**
- Download the .zip file for your architecture
- Extract and drag to Applications folder manually
- **Fast startup** - optimized for performance
### Architecture Support
- **Intel Macs (x86_64)**: Download files with "x86_64" in the name
- **Apple Silicon Macs (arm64)**: Download files with "arm64" in the name
### Performance Notes
- This version uses directory-based packaging instead of single-file
- **Startup time improved significantly** (from ~3-5 seconds to instant)
- Slightly larger download size but much better user experience
### System Requirements
- macOS 10.15 (Catalina) or later
- Python runtime is included (no separate installation needed)
draft: false
prerelease: false
# 7. Upload release assets
- name: Upload x86_64 installer package
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: everything-x86_64.pkg
asset_name: everything-x86_64.pkg
asset_content_type: application/octet-stream
- name: Upload arm64 installer package
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: everything-arm64.pkg
asset_name: everything-arm64.pkg
asset_content_type: application/octet-stream
- name: Upload x86_64 app bundle
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: everything-x86_64-app.zip
asset_name: everything-x86_64-app.zip
asset_content_type: application/zip
- name: Upload arm64 app bundle
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: everything-arm64-app.zip
asset_name: everything-arm64-app.zip
asset_content_type: application/zip