Set custom DMG volume icon to prevent Electron default icon confusion #132
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version to build (e.g., 2.0.4)' | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write | |
| actions: read | |
| checks: write | |
| env: | |
| NODE_VERSION: '18' | |
| jobs: | |
| # Test stage - runs on Linux for speed | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci --prefer-offline | |
| - name: Run linter | |
| run: npm run lint -- --max-warnings=-1 | |
| # Build stage - macOS with code signing | |
| build-macos: | |
| runs-on: macos-latest | |
| needs: test | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Set version from tag | |
| run: | | |
| if [ -n "${{ inputs.version }}" ]; then | |
| TAG_VERSION="${{ inputs.version }}" | |
| else | |
| TAG_VERSION=${GITHUB_REF#refs/tags/v} | |
| fi | |
| echo "VERSION=$TAG_VERSION" >> $GITHUB_ENV | |
| npm version $TAG_VERSION --no-git-tag-version --allow-same-version | |
| - name: Install dependencies | |
| run: npm ci --prefer-offline | |
| - name: Verify required environment variables | |
| run: | | |
| if [ -z "${{ vars.APPLE_ID }}" ] || [ -z "${{ secrets.APPLE_PASSWORD }}" ] || [ -z "${{ secrets.APPLE_TEAM_ID }}" ] || [ -z "${{ secrets.SIGNING_IDENTITY }}" ]; then | |
| echo "❌ Error: Missing required environment variables for code signing" | |
| echo "Required: APPLE_ID (var), APPLE_PASSWORD, APPLE_TEAM_ID, SIGNING_IDENTITY (org secrets)" | |
| exit 1 | |
| fi | |
| - name: Import code signing certificate | |
| run: | | |
| echo "Importing code signing certificate..." | |
| # Create temporary keychain | |
| KEYCHAIN_PATH=$RUNNER_TEMP/ci-build.keychain-db | |
| KEYCHAIN_PASSWORD=$(openssl rand -base64 32) | |
| # Delete keychain if it exists | |
| security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true | |
| # Create new temporary keychain | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| # Set keychain settings (no timeout, no lock) | |
| security set-keychain-settings "$KEYCHAIN_PATH" | |
| # Unlock keychain | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| # Add to keychain search list | |
| security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | sed s/\"//g) | |
| # Import certificate | |
| echo "${{ secrets.SIGNING_CERTIFICATE_BASE64 }}" | base64 -d > certificate.p12 | |
| security import certificate.p12 -k "$KEYCHAIN_PATH" -P "${{ secrets.SIGNING_CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign -T /usr/bin/productbuild | |
| rm certificate.p12 | |
| # Allow codesign to access the certificate without prompting | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| # Set default keychain | |
| security default-keychain -s "$KEYCHAIN_PATH" | |
| echo "✅ Certificate imported successfully" | |
| - name: Verify environment variables | |
| run: | | |
| echo "Verifying environment variables..." | |
| if [ -z "${{ secrets.FIGMA_CLIENT_ID }}" ] || [ -z "${{ secrets.FIGMA_CLIENT_SECRET }}" ]; then | |
| echo "⚠️ Warning: FIGMA_CLIENT_ID or FIGMA_CLIENT_SECRET not set" | |
| echo "OAuth authentication will not work in the built app" | |
| else | |
| echo "✅ Figma OAuth credentials configured" | |
| fi | |
| if [ -z "${{ secrets.GOOGLE_ANALYTICS_ID }}" ] || [ -z "${{ secrets.GOOGLE_ANALYTICS_API_SECRET }}" ]; then | |
| echo "⚠️ Warning: Google Analytics credentials not set" | |
| else | |
| echo "✅ Google Analytics configured" | |
| fi | |
| - name: Build macOS universal app | |
| run: npm run make -- --platform=darwin --arch=universal | |
| env: | |
| # Code signing credentials (org level) | |
| APPLE_ID: ${{ vars.APPLE_ID }} | |
| APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| SIGNING_IDENTITY: ${{ secrets.SIGNING_IDENTITY }} | |
| # Runtime configuration (repo level) | |
| FIGMA_CLIENT_ID: ${{ secrets.FIGMA_CLIENT_ID }} | |
| FIGMA_CLIENT_SECRET: ${{ secrets.FIGMA_CLIENT_SECRET }} | |
| GOOGLE_ANALYTICS_ID: ${{ secrets.GOOGLE_ANALYTICS_ID }} | |
| GOOGLE_ANALYTICS_API_SECRET: ${{ secrets.GOOGLE_ANALYTICS_API_SECRET }} | |
| # Analytics distribution channel | |
| DISTRIBUTION_CHANNEL: ${{ secrets.DISTRIBUTION_CHANNEL }} | |
| - name: Clean up keychain | |
| if: always() | |
| run: | | |
| security delete-keychain $RUNNER_TEMP/ci-build.keychain-db 2>/dev/null || true | |
| security default-keychain -s ~/Library/Keychains/login.keychain-db || true | |
| - name: List build artifacts | |
| run: | | |
| echo "=== Build artifacts ===" | |
| find out/make -type f | |
| - name: Upload DMG artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: macos-universal-dmg | |
| path: out/make/*.dmg | |
| if-no-files-found: error | |
| - name: Upload ZIP artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: macos-universal-zip | |
| path: out/make/zip/darwin/universal/*.zip | |
| if-no-files-found: error | |
| # Build stage - Windows | |
| build-windows: | |
| runs-on: windows-latest | |
| needs: test | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: Set version from tag | |
| shell: bash | |
| run: | | |
| if [ -n "${{ inputs.version }}" ]; then | |
| TAG_VERSION="${{ inputs.version }}" | |
| else | |
| TAG_VERSION=${GITHUB_REF#refs/tags/v} | |
| fi | |
| echo "VERSION=$TAG_VERSION" >> $GITHUB_ENV | |
| npm version $TAG_VERSION --no-git-tag-version --allow-same-version | |
| - name: Install dependencies | |
| run: npm ci --prefer-offline | |
| - name: Verify environment variables | |
| shell: bash | |
| run: | | |
| echo "Verifying environment variables..." | |
| if [ -z "${{ secrets.FIGMA_CLIENT_ID }}" ] || [ -z "${{ secrets.FIGMA_CLIENT_SECRET }}" ]; then | |
| echo "⚠️ Warning: FIGMA_CLIENT_ID or FIGMA_CLIENT_SECRET not set" | |
| echo "OAuth authentication will not work in the built app" | |
| else | |
| echo "✅ Figma OAuth credentials configured" | |
| fi | |
| if [ -z "${{ secrets.GOOGLE_ANALYTICS_ID }}" ] || [ -z "${{ secrets.GOOGLE_ANALYTICS_API_SECRET }}" ]; then | |
| echo "⚠️ Warning: Google Analytics credentials not set" | |
| else | |
| echo "✅ Google Analytics configured" | |
| fi | |
| - name: Build Windows app | |
| run: npm run make -- --platform=win32 | |
| env: | |
| FIGMA_CLIENT_ID: ${{ secrets.FIGMA_CLIENT_ID }} | |
| FIGMA_CLIENT_SECRET: ${{ secrets.FIGMA_CLIENT_SECRET }} | |
| GOOGLE_ANALYTICS_ID: ${{ secrets.GOOGLE_ANALYTICS_ID }} | |
| GOOGLE_ANALYTICS_API_SECRET: ${{ secrets.GOOGLE_ANALYTICS_API_SECRET }} | |
| # Analytics distribution channel | |
| DISTRIBUTION_CHANNEL: ${{ secrets.DISTRIBUTION_CHANNEL }} | |
| - name: List build artifacts | |
| shell: bash | |
| run: | | |
| echo "=== Build artifacts ===" | |
| find out/make -type f | |
| - name: Upload Windows artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-build | |
| path: | | |
| out/make/squirrel.windows/**/*.exe | |
| out/make/squirrel.windows/**/*.nupkg | |
| if-no-files-found: warn | |
| # Create GitHub Release | |
| create-release: | |
| runs-on: ubuntu-latest | |
| needs: [build-macos, build-windows] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: List downloaded artifacts | |
| run: | | |
| echo "=== Downloaded artifacts ===" | |
| find artifacts -type f | |
| - name: Extract version from tag | |
| run: | | |
| if [ -n "${{ inputs.version }}" ]; then | |
| TAG_VERSION="${{ inputs.version }}" | |
| TAG_NAME="v$TAG_VERSION" | |
| else | |
| TAG_VERSION=${GITHUB_REF#refs/tags/v} | |
| TAG_NAME=${GITHUB_REF#refs/tags/} | |
| fi | |
| echo "VERSION=$TAG_VERSION" >> $GITHUB_ENV | |
| echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: true | |
| make_latest: true | |
| name: TalkToFigma Desktop ${{ env.TAG_NAME }} | |
| body: | | |
| ## TalkToFigma Desktop ${{ env.TAG_NAME }} | |
| ### 📦 Downloads | |
| - **macOS DMG (Universal)**: Works on both Intel and Apple Silicon Macs | |
| - **macOS ZIP (Universal)**: Alternative distribution format | |
| - **Windows Squirrel**: Traditional EXE installer | |
| ### 🔒 Code Signing | |
| - macOS builds are **code signed** with Grab Developer ID | |
| - macOS builds are **notarized** by Apple | |
| - Bundle ID: `com.grabtaxi.klever` | |
| ### 📋 Requirements | |
| - macOS 10.15 (Catalina) or later | |
| - Windows 10 or later | |
| - Node.js 18+ (for MCP server) | |
| ### 🚀 What's New | |
| See commit history and release notes below for details. | |
| files: | | |
| artifacts/macos-universal-dmg/*.dmg | |
| artifacts/macos-universal-zip/**/*.zip | |
| artifacts/windows-build/**/*.exe | |
| artifacts/windows-build/**/*.nupkg |