Skip to content

Build TablePro

Build TablePro #38

Workflow file for this run

name: Build OpenTable
on:
push:
tags: ["v*"]
paths-ignore:
- "**.md"
- "docs/**"
- ".vscode/**"
env:
XCODE_PROJECT: OpenTable.xcodeproj
XCODE_SCHEME: OpenTable
BUILD_CONFIGURATION: Release
XCODE_VERSION: "26.2" # Updated to support macOS 26 Tahoe liquid design
jobs:
lint:
name: SwiftLint
runs-on: macos-26 # Updated to macOS 26 (Tahoe) runner
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Cache SwiftLint
uses: actions/cache@v4
with:
path: ~/Library/Caches/Homebrew/swiftlint*
key: swiftlint-${{ runner.os }}-${{ hashFiles('.swiftlint.yml') }}
restore-keys: |
swiftlint-${{ runner.os }}-
- name: Install SwiftLint
run: brew install swiftlint
- name: Run SwiftLint
run: swiftlint lint --strict
prepare-libs:
name: Prepare Universal Libraries
runs-on: macos-26 # Updated to macOS 26 (Tahoe) runner
needs: lint
timeout-minutes: 25
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Cache Homebrew downloads
uses: actions/cache@v4
continue-on-error: true
with:
path: ~/Library/Caches/Homebrew
key: brew-downloads-${{ runner.os }}-${{ hashFiles('**/build-release.sh') }}
restore-keys: |
brew-downloads-${{ runner.os }}-
- name: Install ARM64 Homebrew dependencies
run: |
echo "Installing ARM64 dependencies..."
# Check and install only if needed
if ! brew list mariadb-connector-c &>/dev/null; then
echo "📦 Installing mariadb-connector-c..."
brew install mariadb-connector-c
else
echo "✅ mariadb-connector-c already installed"
fi
if ! brew list libpq &>/dev/null; then
echo "📦 Installing libpq..."
brew install libpq
else
echo "✅ libpq already installed"
fi
# Link packages with --force (needed for keg-only formulas)
brew link --force mariadb-connector-c
brew link --force libpq
# Verify installations
if ! brew list mariadb-connector-c >/dev/null 2>&1; then
echo "❌ ERROR: mariadb-connector-c installation failed or incomplete"
exit 1
fi
if ! brew list libpq >/dev/null 2>&1; then
echo "❌ ERROR: libpq installation failed or incomplete"
exit 1
fi
# Get the actual prefix for mariadb-connector-c (handles keg-only formulas)
MARIADB_PREFIX=$(brew --prefix mariadb-connector-c)
echo "MariaDB Connector/C prefix: $MARIADB_PREFIX"
# Find the library file (may be in lib/ or lib/mariadb/)
MARIADB_LIB=""
for path in "$MARIADB_PREFIX/lib/mariadb/libmariadb.a" "$MARIADB_PREFIX/lib/libmariadb.a"; do
if [ -f "$path" ]; then
MARIADB_LIB="$path"
break
fi
done
if [ -z "$MARIADB_LIB" ]; then
echo "❌ ERROR: mariadb-connector-c installed but library file not found"
echo "Searched in:"
echo " - $MARIADB_PREFIX/lib/mariadb/libmariadb.a"
echo " - $MARIADB_PREFIX/lib/libmariadb.a"
echo ""
echo "Contents of $MARIADB_PREFIX/lib/:"
ls -la "$MARIADB_PREFIX/lib/" || echo "Directory not found"
exit 1
fi
echo "✅ Found ARM64 MariaDB library at: $MARIADB_LIB"
echo "ARM64_MARIADB_LIB=$MARIADB_LIB" >> $GITHUB_ENV
echo "✅ All ARM64 dependencies installed successfully"
- name: Install x86_64 Homebrew
run: |
# Install Rosetta 2 if needed
if ! arch -x86_64 /usr/bin/true 2>/dev/null; then
echo "Installing Rosetta 2..."
if ! softwareupdate --install-rosetta --agree-to-license; then
echo "❌ ERROR: Failed to install Rosetta 2"
echo "This is required to run x86_64 binaries on Apple Silicon"
exit 1
fi
# Verify Rosetta 2 is now working
if ! arch -x86_64 /usr/bin/true 2>/dev/null; then
echo "❌ ERROR: Rosetta 2 installed but not functional"
exit 1
fi
echo "✅ Rosetta 2 installed successfully"
else
echo "✅ Rosetta 2 already installed"
fi
# Check if x86_64 Homebrew is already installed
if [ ! -f /usr/local/bin/brew ]; then
echo "Installing x86_64 Homebrew..."
# Using official Homebrew installer (trusted source)
if ! arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
echo "❌ ERROR: Homebrew installation script failed"
exit 1
fi
# Verify installation
if [ ! -f /usr/local/bin/brew ]; then
echo "❌ ERROR: Homebrew installed but /usr/local/bin/brew not found"
exit 1
fi
# Verify it's executable
if ! /usr/local/bin/brew --version; then
echo "❌ ERROR: Homebrew binary is not functional"
exit 1
fi
echo "✅ x86_64 Homebrew installed successfully"
else
echo "x86_64 Homebrew already installed"
# Still verify it works
if ! /usr/local/bin/brew --version; then
echo "❌ ERROR: x86_64 Homebrew exists but is not functional"
exit 1
fi
fi
- name: Install x86_64 Homebrew dependencies
run: |
echo "Installing x86_64 dependencies..."
# Check and install only if needed
if ! arch -x86_64 /usr/local/bin/brew list mariadb-connector-c &>/dev/null; then
echo "📦 Installing mariadb-connector-c (x86_64)..."
arch -x86_64 /usr/local/bin/brew install mariadb-connector-c
else
echo "✅ mariadb-connector-c (x86_64) already installed"
fi
if ! arch -x86_64 /usr/local/bin/brew list libpq &>/dev/null; then
echo "📦 Installing libpq (x86_64)..."
arch -x86_64 /usr/local/bin/brew install libpq
else
echo "✅ libpq (x86_64) already installed"
fi
# Link packages with --force (needed for keg-only formulas)
arch -x86_64 /usr/local/bin/brew link --force mariadb-connector-c
arch -x86_64 /usr/local/bin/brew link --force libpq
# Verify installations
if ! arch -x86_64 /usr/local/bin/brew list mariadb-connector-c >/dev/null 2>&1; then
echo "❌ ERROR: mariadb-connector-c installation failed or incomplete"
exit 1
fi
if ! arch -x86_64 /usr/local/bin/brew list libpq >/dev/null 2>&1; then
echo "❌ ERROR: libpq installation failed or incomplete"
exit 1
fi
# Get the actual prefix for mariadb-connector-c (handles keg-only formulas)
X86_MARIADB_PREFIX=$(arch -x86_64 /usr/local/bin/brew --prefix mariadb-connector-c)
echo "x86_64 MariaDB Connector/C prefix: $X86_MARIADB_PREFIX"
# Find the library file (may be in lib/ or lib/mariadb/)
X86_MARIADB_LIB=""
for path in "$X86_MARIADB_PREFIX/lib/mariadb/libmariadb.a" "$X86_MARIADB_PREFIX/lib/libmariadb.a"; do
if [ -f "$path" ]; then
X86_MARIADB_LIB="$path"
break
fi
done
if [ -z "$X86_MARIADB_LIB" ]; then
echo "❌ ERROR: mariadb-connector-c installed but library file not found"
echo "Searched in:"
echo " - $X86_MARIADB_PREFIX/lib/mariadb/libmariadb.a"
echo " - $X86_MARIADB_PREFIX/lib/libmariadb.a"
echo ""
echo "Contents of $X86_MARIADB_PREFIX/lib/:"
ls -la "$X86_MARIADB_PREFIX/lib/" || echo "Directory not found"
exit 1
fi
echo "✅ Found x86_64 MariaDB library at: $X86_MARIADB_LIB"
echo "X86_MARIADB_LIB=$X86_MARIADB_LIB" >> $GITHUB_ENV
echo "✅ All x86_64 dependencies installed successfully"
- name: Create universal libmariadb library
run: |
echo "Creating universal libmariadb.a..."
# Use library paths from environment (set by previous steps)
ARM64_LIB="${ARM64_MARIADB_LIB}"
X86_LIB="${X86_MARIADB_LIB}"
echo "ARM64 library path: $ARM64_LIB"
echo "x86_64 library path: $X86_LIB"
# Verify input files exist
if [ -z "$ARM64_LIB" ] || [ ! -f "$ARM64_LIB" ]; then
echo "❌ ERROR: ARM64 library not found at: $ARM64_LIB"
echo "ARM64 Homebrew installation may have failed"
exit 1
fi
if [ -z "$X86_LIB" ] || [ ! -f "$X86_LIB" ]; then
echo "❌ ERROR: x86_64 library not found at: $X86_LIB"
echo "x86_64 Homebrew installation may have failed"
exit 1
fi
# Verify inputs are correct architectures
echo "Verifying input architectures:"
lipo -info "$ARM64_LIB"
lipo -info "$X86_LIB"
# Ensure output directory exists
mkdir -p Libs
# Create universal binary
if ! lipo -create "$ARM64_LIB" "$X86_LIB" -output Libs/libmariadb_universal.a; then
echo "❌ ERROR: Failed to create universal library"
echo "This could mean:"
echo " - Libraries are incompatible"
echo " - Libraries are already universal"
echo " - Output directory is not writable"
exit 1
fi
# Verify output
if [ ! -f "Libs/libmariadb_universal.a" ]; then
echo "❌ ERROR: Universal library was not created"
exit 1
fi
echo "✅ Universal library created successfully:"
lipo -info Libs/libmariadb_universal.a
ls -lh Libs/libmariadb_universal.a
# Verify it's actually universal (contains both architectures)
if ! lipo -info Libs/libmariadb_universal.a | grep -q "arm64"; then
echo "❌ ERROR: Universal library missing arm64 architecture"
exit 1
fi
if ! lipo -info Libs/libmariadb_universal.a | grep -q "x86_64"; then
echo "❌ ERROR: Universal library missing x86_64 architecture"
exit 1
fi
echo "✅ Verified: Library contains both arm64 and x86_64"
- name: Upload library artifacts
uses: actions/upload-artifact@v4
with:
name: libs-universal
path: Libs/
retention-days: 1
build-arm64:
name: Build ARM64
runs-on: macos-26 # Updated to macOS 26 (Tahoe) runner
needs: prepare-libs
timeout-minutes: 20
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download library artifacts
uses: actions/download-artifact@v4
with:
name: libs-universal
path: Libs/
- name: Verify downloaded artifacts
run: |
echo "Verifying downloaded library artifacts..."
if [ ! -f "Libs/libmariadb_universal.a" ]; then
echo "❌ ERROR: Required library artifact not found: Libs/libmariadb_universal.a"
echo "This means:"
echo " - The prepare-libs job failed to create the library"
echo " - The artifact upload failed"
echo " - The artifact download was corrupted"
echo ""
echo "Contents of Libs directory:"
ls -la Libs/ || echo "Libs directory is empty or doesn't exist"
exit 1
fi
echo "✅ Universal library found"
lipo -info Libs/libmariadb_universal.a
ls -lh Libs/libmariadb_universal.a
- name: Cache Homebrew downloads
uses: actions/cache@v4
continue-on-error: true
with:
path: ~/Library/Caches/Homebrew
key: brew-arm64-downloads-${{ runner.os }}-${{ hashFiles('**/build-release.sh') }}
restore-keys: |
brew-arm64-downloads-${{ runner.os }}-
- name: Install ARM64 dependencies
run: |
echo "Installing ARM64 dependencies..."
# Check and install only if needed
if ! brew list mariadb-connector-c &>/dev/null; then
echo "📦 Installing mariadb-connector-c..."
brew install mariadb-connector-c
else
echo "✅ mariadb-connector-c already installed"
fi
if ! brew list libpq &>/dev/null; then
echo "📦 Installing libpq..."
brew install libpq
else
echo "✅ libpq already installed"
fi
# Link packages with --force (needed for keg-only formulas)
brew link --force mariadb-connector-c
brew link --force libpq
# Verify installations
if ! brew list mariadb-connector-c >/dev/null 2>&1; then
echo "❌ ERROR: mariadb-connector-c installation failed"
exit 1
fi
if ! brew list libpq >/dev/null 2>&1; then
echo "❌ ERROR: libpq installation failed"
exit 1
fi
echo "✅ ARM64 dependencies installed"
- name: Select Xcode version
run: |
sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app/Contents/Developer
echo "Selected Xcode version:"
xcodebuild -version
- name: Build ARM64
run: |
chmod +x build-release.sh
./build-release.sh arm64
- name: Verify build
run: |
echo "Verifying build output..."
BINARY_PATH="build/Release/OpenTable-arm64.app/Contents/MacOS/OpenTable"
# Check binary exists
if [ ! -f "$BINARY_PATH" ]; then
echo "❌ ERROR: Built binary not found at: $BINARY_PATH"
echo "Build may have failed silently"
exit 1
fi
# Check it's not empty
if [ ! -s "$BINARY_PATH" ]; then
echo "❌ ERROR: Binary file is empty"
exit 1
fi
# Check architecture
ARCH_INFO=$(lipo -info "$BINARY_PATH")
echo "Architecture: $ARCH_INFO"
if ! echo "$ARCH_INFO" | grep -q "arm64"; then
echo "❌ ERROR: Binary does not contain arm64 architecture"
echo "Expected: arm64 only"
echo "Got: $ARCH_INFO"
exit 1
fi
if echo "$ARCH_INFO" | grep -q "x86_64"; then
echo "❌ ERROR: Binary contains x86_64 but should be arm64 only"
exit 1
fi
# Check it's executable
if [ ! -x "$BINARY_PATH" ]; then
echo "❌ ERROR: Binary is not executable"
exit 1
fi
# Display info
echo "✅ Build verified successfully"
echo "Binary size: $(ls -lh "$BINARY_PATH" | awk '{print $5}')"
echo "App bundle size: $(du -sh build/Release/OpenTable-arm64.app | awk '{print $1}')"
- name: Create DMG installer
run: |
echo "Creating DMG installer..."
# Install create-dmg tool for proper icon handling in CI
echo "📦 Installing create-dmg tool..."
brew install create-dmg
# Make DMG creation script executable
chmod +x create-dmg.sh
# Create DMG with version from git tag or use default
# The script handles app renaming internally
VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.1.13")
echo "📌 Using version: $VERSION"
./create-dmg.sh "$VERSION" "arm64" "build/Release/OpenTable-arm64.app"
# Verify DMG was created - check for the specific file or any arm64 DMG
DMG_FILE="build/Release/OpenTable-${VERSION}-arm64.dmg"
if [ -f "$DMG_FILE" ]; then
echo "✅ DMG installer created successfully: $DMG_FILE"
else
echo "⚠️ Expected DMG not found at: $DMG_FILE"
echo "📂 Checking for any DMG files in build/Release/:"
ls -la build/Release/*.dmg 2>/dev/null || echo " No DMG files found"
# Check if any arm64 DMG was created (version might differ)
if ls build/Release/*-arm64.dmg 1>/dev/null 2>&1; then
echo "✅ Found arm64 DMG file(s):"
ls -lh build/Release/*-arm64.dmg
else
echo "❌ ERROR: No arm64 DMG file was created"
exit 1
fi
fi
ls -lh build/Release/*.dmg
- name: Create ZIP archive (fallback)
run: |
echo "Creating ZIP archive..."
cd build/Release
if ! zip -r OpenTable-arm64.zip OpenTable-arm64.app; then
echo "❌ ERROR: Failed to create ZIP archive"
exit 1
fi
echo "✅ ZIP archive created"
ls -lh OpenTable-arm64.zip
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: OpenTable-arm64-${{ github.sha }}
path: |
build/Release/*.dmg
build/Release/OpenTable-arm64.zip
retention-days: ${{ startsWith(github.ref, 'refs/tags/v') && 90 || 7 }}
build-x86_64:
name: Build x86_64
runs-on: macos-26 # Updated to macOS 26 (Tahoe) runner
needs: prepare-libs
timeout-minutes: 20
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download library artifacts
uses: actions/download-artifact@v4
with:
name: libs-universal
path: Libs/
- name: Verify downloaded artifacts
run: |
echo "Verifying downloaded library artifacts..."
if [ ! -f "Libs/libmariadb_universal.a" ]; then
echo "❌ ERROR: Required library artifact not found: Libs/libmariadb_universal.a"
echo ""
echo "Contents of Libs directory:"
ls -la Libs/ || echo "Libs directory is empty or doesn't exist"
exit 1
fi
echo "✅ Universal library found"
lipo -info Libs/libmariadb_universal.a
- name: Cache Homebrew downloads
uses: actions/cache@v4
continue-on-error: true
with:
path: ~/Library/Caches/Homebrew
key: brew-x86_64-downloads-${{ runner.os }}-${{ hashFiles('**/build-release.sh') }}
restore-keys: |
brew-x86_64-downloads-${{ runner.os }}-
- name: Install Rosetta 2
run: |
if ! arch -x86_64 /usr/bin/true 2>/dev/null; then
echo "Installing Rosetta 2..."
if ! softwareupdate --install-rosetta --agree-to-license; then
echo "❌ ERROR: Failed to install Rosetta 2"
exit 1
fi
# Verify Rosetta 2 works
if ! arch -x86_64 /usr/bin/true 2>/dev/null; then
echo "❌ ERROR: Rosetta 2 installed but not functional"
exit 1
fi
echo "✅ Rosetta 2 installed"
else
echo "✅ Rosetta 2 already installed"
fi
- name: Install x86_64 Homebrew
run: |
if [ ! -f /usr/local/bin/brew ]; then
echo "Installing x86_64 Homebrew..."
if ! arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
echo "❌ ERROR: Homebrew installation failed"
exit 1
fi
if [ ! -f /usr/local/bin/brew ]; then
echo "❌ ERROR: Homebrew not found after installation"
exit 1
fi
if ! /usr/local/bin/brew --version; then
echo "❌ ERROR: Homebrew not functional"
exit 1
fi
echo "✅ x86_64 Homebrew installed"
else
echo "x86_64 Homebrew already installed"
if ! /usr/local/bin/brew --version; then
echo "❌ ERROR: Homebrew not functional"
exit 1
fi
fi
- name: Install x86_64 dependencies
run: |
echo "Installing x86_64 dependencies..."
# Check and install only if needed
if ! arch -x86_64 /usr/local/bin/brew list mariadb-connector-c &>/dev/null; then
echo "📦 Installing mariadb-connector-c (x86_64)..."
arch -x86_64 /usr/local/bin/brew install mariadb-connector-c
else
echo "✅ mariadb-connector-c (x86_64) already installed"
fi
if ! arch -x86_64 /usr/local/bin/brew list libpq &>/dev/null; then
echo "📦 Installing libpq (x86_64)..."
arch -x86_64 /usr/local/bin/brew install libpq
else
echo "✅ libpq (x86_64) already installed"
fi
# Link packages with --force (needed for keg-only formulas)
arch -x86_64 /usr/local/bin/brew link --force mariadb-connector-c
arch -x86_64 /usr/local/bin/brew link --force libpq
# Verify installations
if ! arch -x86_64 /usr/local/bin/brew list mariadb-connector-c >/dev/null 2>&1; then
echo "❌ ERROR: mariadb-connector-c installation failed"
exit 1
fi
if ! arch -x86_64 /usr/local/bin/brew list libpq >/dev/null 2>&1; then
echo "❌ ERROR: libpq installation failed"
exit 1
fi
echo "✅ x86_64 dependencies installed"
- name: Select Xcode version
run: |
sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app/Contents/Developer
echo "Selected Xcode version:"
xcodebuild -version
- name: Build x86_64
run: |
chmod +x build-release.sh
./build-release.sh x86_64
- name: Verify build
run: |
echo "Verifying build output..."
BINARY_PATH="build/Release/OpenTable-x86_64.app/Contents/MacOS/OpenTable"
# Check binary exists
if [ ! -f "$BINARY_PATH" ]; then
echo "❌ ERROR: Built binary not found at: $BINARY_PATH"
exit 1
fi
# Check it's not empty
if [ ! -s "$BINARY_PATH" ]; then
echo "❌ ERROR: Binary file is empty"
exit 1
fi
# Check architecture
ARCH_INFO=$(lipo -info "$BINARY_PATH")
echo "Architecture: $ARCH_INFO"
if ! echo "$ARCH_INFO" | grep -q "x86_64"; then
echo "❌ ERROR: Binary does not contain x86_64 architecture"
echo "Expected: x86_64 only"
echo "Got: $ARCH_INFO"
exit 1
fi
if echo "$ARCH_INFO" | grep -q "arm64"; then
echo "❌ ERROR: Binary contains arm64 but should be x86_64 only"
exit 1
fi
# Check it's executable
if [ ! -x "$BINARY_PATH" ]; then
echo "❌ ERROR: Binary is not executable"
exit 1
fi
# Display info
echo "✅ Build verified successfully"
echo "Binary size: $(ls -lh "$BINARY_PATH" | awk '{print $5}')"
echo "App bundle size: $(du -sh build/Release/OpenTable-x86_64.app | awk '{print $1}')"
- name: Create DMG installer
run: |
echo "Creating DMG installer..."
# Install create-dmg tool for proper icon handling in CI
echo "📦 Installing create-dmg tool..."
brew install create-dmg
# Make DMG creation script executable
chmod +x create-dmg.sh
# Create DMG with version from git tag or use default
# The script handles app renaming internally
VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.1.13")
echo "📌 Using version: $VERSION"
./create-dmg.sh "$VERSION" "x86_64" "build/Release/OpenTable-x86_64.app"
# Verify DMG was created - check for the specific file or any x86_64 DMG
DMG_FILE="build/Release/OpenTable-${VERSION}-x86_64.dmg"
if [ -f "$DMG_FILE" ]; then
echo "✅ DMG installer created successfully: $DMG_FILE"
else
echo "⚠️ Expected DMG not found at: $DMG_FILE"
echo "📂 Checking for any DMG files in build/Release/:"
ls -la build/Release/*.dmg 2>/dev/null || echo " No DMG files found"
# Check if any x86_64 DMG was created (version might differ)
if ls build/Release/*-x86_64.dmg 1>/dev/null 2>&1; then
echo "✅ Found x86_64 DMG file(s):"
ls -lh build/Release/*-x86_64.dmg
else
echo "❌ ERROR: No x86_64 DMG file was created"
exit 1
fi
fi
ls -lh build/Release/*.dmg
- name: Create ZIP archive (fallback)
run: |
echo "Creating ZIP archive..."
cd build/Release
if ! zip -r OpenTable-x86_64.zip OpenTable-x86_64.app; then
echo "❌ ERROR: Failed to create ZIP archive"
exit 1
fi
echo "✅ ZIP archive created"
ls -lh OpenTable-x86_64.zip
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: OpenTable-x86_64-${{ github.sha }}
path: |
build/Release/*.dmg
build/Release/OpenTable-x86_64.zip
retention-days: ${{ startsWith(github.ref, 'refs/tags/v') && 90 || 7 }}
release:
name: Create GitHub Release
runs-on: macos-26 # Updated to macOS 26 (Tahoe) runner
needs: [build-arm64, build-x86_64]
if: startsWith(github.ref, 'refs/tags/v')
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download ARM64 artifact
uses: actions/download-artifact@v4
with:
name: OpenTable-arm64-${{ github.sha }}
path: artifacts/
- name: Download x86_64 artifact
uses: actions/download-artifact@v4
with:
name: OpenTable-x86_64-${{ github.sha }}
path: artifacts/
- name: Verify and organize artifacts for release
run: |
VERSION=${GITHUB_REF#refs/tags/v}
if [ -z "$VERSION" ]; then
echo "❌ ERROR: Failed to extract version from ref: $GITHUB_REF"
exit 1
fi
echo "Preparing artifacts for version: $VERSION"
echo "Contents of artifacts directory:"
ls -la artifacts/
# Note: DMG files should already have correct names from build
# ZIP files need to be renamed
# Rename ZIP files if they exist
if [ -f "artifacts/OpenTable-arm64.zip" ]; then
mv artifacts/OpenTable-arm64.zip "artifacts/OpenTable-${VERSION}-arm64.zip"
fi
if [ -f "artifacts/OpenTable-x86_64.zip" ]; then
mv artifacts/OpenTable-x86_64.zip "artifacts/OpenTable-${VERSION}-x86_64.zip"
fi
echo "✅ Artifacts organized successfully"
echo "Final artifacts:"
ls -lh artifacts/
- name: Generate release notes
id: release_notes
run: |
VERSION=${GITHUB_REF#refs/tags/}
# Try to get previous tag
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -z "$PREVIOUS_TAG" ]; then
echo "No previous tag found, showing recent commits"
COMMIT_RANGE="HEAD~10..HEAD"
else
echo "Generating changes since $PREVIOUS_TAG"
COMMIT_RANGE="$PREVIOUS_TAG..HEAD"
fi
# Extract raw commits
RAW_COMMITS=$(git log --pretty=format:"%s" "$COMMIT_RANGE" 2>/dev/null || echo "")
# Filter noise commits
FILTERED_COMMITS=$(echo "$RAW_COMMITS" | awk '
tolower($0) ~ /^wip$/ { next }
tolower($0) ~ /^wip:/ { next }
/^Merge pull request/ { next }
/^Merge branch/ { next }
/^Bump [0-9]/ { next }
tolower($0) ~ /^bump version/ { next }
tolower($0) ~ /^bump [0-9]/ { next }
/^\[.*[Bb]ot\]/ { next }
/^$/ { next }
{ print }
')
# Categorize commits by conventional commit type
FEAT_COMMITS=$(echo "$FILTERED_COMMITS" | grep -i "^feat:" | sed 's/^feat: *//' || true)
FIX_COMMITS=$(echo "$FILTERED_COMMITS" | grep -i "^fix:" | sed 's/^fix: *//' || true)
PERF_COMMITS=$(echo "$FILTERED_COMMITS" | grep -i "^perf:" | sed 's/^perf: *//' || true)
DOCS_COMMITS=$(echo "$FILTERED_COMMITS" | grep -i "^docs:" | sed 's/^docs: *//' || true)
REFACTOR_COMMITS=$(echo "$FILTERED_COMMITS" | grep -i "^refactor:" | sed 's/^refactor: *//' || true)
CHORE_COMMITS=$(echo "$FILTERED_COMMITS" | grep -iE "^(chore|style|test):" | sed 's/^[^:]*: *//' || true)
OTHER_COMMITS=$(echo "$FILTERED_COMMITS" | grep -ivE "^(feat|fix|perf|docs|refactor|chore|style|test):" || true)
# Build categorized output
CHANGES=""
if [ -n "$FEAT_COMMITS" ]; then
CHANGES="${CHANGES}### New Features"$'\n\n'
CHANGES="${CHANGES}$(echo "$FEAT_COMMITS" | sed 's/^/- /')"$'\n\n'
fi
if [ -n "$FIX_COMMITS" ]; then
CHANGES="${CHANGES}### Bug Fixes"$'\n\n'
CHANGES="${CHANGES}$(echo "$FIX_COMMITS" | sed 's/^/- /')"$'\n\n'
fi
if [ -n "$PERF_COMMITS" ]; then
CHANGES="${CHANGES}### Performance Improvements"$'\n\n'
CHANGES="${CHANGES}$(echo "$PERF_COMMITS" | sed 's/^/- /')"$'\n\n'
fi
if [ -n "$DOCS_COMMITS" ]; then
CHANGES="${CHANGES}### Documentation"$'\n\n'
CHANGES="${CHANGES}$(echo "$DOCS_COMMITS" | sed 's/^/- /')"$'\n\n'
fi
if [ -n "$REFACTOR_COMMITS" ]; then
CHANGES="${CHANGES}### Refactoring"$'\n\n'
CHANGES="${CHANGES}$(echo "$REFACTOR_COMMITS" | sed 's/^/- /')"$'\n\n'
fi
if [ -n "$CHORE_COMMITS" ]; then
CHANGES="${CHANGES}### Maintenance"$'\n\n'
CHANGES="${CHANGES}$(echo "$CHORE_COMMITS" | sed 's/^/- /')"$'\n\n'
fi
if [ -n "$OTHER_COMMITS" ]; then
CHANGES="${CHANGES}### Other Changes"$'\n\n'
CHANGES="${CHANGES}$(echo "$OTHER_COMMITS" | sed 's/^/- /')"$'\n\n'
fi
# Fallback if all commits were filtered out
if [ -z "$CHANGES" ]; then
CHANGES="### Changes"$'\n\n'"- Minor improvements and bug fixes"$'\n\n'
fi
cat > release_notes.md <<EOF
$CHANGES
EOF
echo "✅ Release notes generated"
cat release_notes.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
artifacts/*.dmg
artifacts/*.zip
body_path: release_notes.md
draft: false
prerelease: ${{ contains(github.ref, '-beta') || contains(github.ref, '-alpha') || contains(github.ref, '-rc') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}