diff --git a/.github/actions/setup-cmux/action.yml b/.github/actions/setup-cmux/action.yml new file mode 100644 index 000000000..7ad43ee65 --- /dev/null +++ b/.github/actions/setup-cmux/action.yml @@ -0,0 +1,13 @@ +name: 'Setup cmux build environment' +description: 'Setup Bun and install dependencies' +runs: + using: "composite" + steps: + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install --frozen-lockfile + shell: bash diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 62e6fb423..f23dec92f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,13 +14,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Install dependencies - run: bun install --frozen-lockfile + - uses: ./.github/actions/setup-cmux - name: Install ImageMagick run: brew install imagemagick @@ -28,28 +22,17 @@ jobs: - name: Build application run: bun run build - - name: Package for macOS - run: | - # Decode certificate to file to avoid issues with newlines in base64 string - if [ -n "${{ secrets.MACOS_CERTIFICATE }}" ]; then - echo "${{ secrets.MACOS_CERTIFICATE }}" | base64 -D > /tmp/certificate.p12 - export CSC_LINK="/tmp/certificate.p12" - export CSC_KEY_PASSWORD="${{ secrets.MACOS_CERTIFICATE_PWD }}" - fi - - # Notarization credentials (optional - will skip if not provided) - if [ -n "${{ secrets.AC_APIKEY_ID }}" ]; then - # Decode API key to file - echo "${{ secrets.AC_APIKEY_P8_BASE64 }}" | base64 -D > /tmp/AuthKey.p8 - export APPLE_API_KEY="/tmp/AuthKey.p8" - export APPLE_API_KEY_ID="${{ secrets.AC_APIKEY_ID }}" - export APPLE_API_ISSUER="${{ secrets.AC_APIKEY_ISSUER_ID }}" - echo "✅ Notarization credentials found (API key) - will notarize" - else - echo "⚠️ No notarization credentials - skipping notarization" - fi + - name: Setup code signing + run: ./scripts/setup-macos-signing.sh + env: + MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} + AC_APIKEY_P8_BASE64: ${{ secrets.AC_APIKEY_P8_BASE64 }} + AC_APIKEY_ID: ${{ secrets.AC_APIKEY_ID }} + AC_APIKEY_ISSUER_ID: ${{ secrets.AC_APIKEY_ISSUER_ID }} - make dist-mac + - name: Package for macOS + run: make dist-mac - name: Upload macOS DMG (x64) uses: actions/upload-artifact@v4 @@ -74,13 +57,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Install dependencies - run: bun install --frozen-lockfile + - uses: ./.github/actions/setup-cmux - name: Install ImageMagick run: sudo apt-get update && sudo apt-get install -y imagemagick diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..921870f21 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,58 @@ +name: Release + +on: + release: + types: [published] + +permissions: + contents: write # Required for electron-builder to upload release assets + +jobs: + build-macos: + name: Build and Release macOS + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-cmux + + - name: Install ImageMagick + run: brew install imagemagick + + - name: Build application + run: bun run build + + - name: Setup code signing + run: ./scripts/setup-macos-signing.sh + env: + MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} + AC_APIKEY_P8_BASE64: ${{ secrets.AC_APIKEY_P8_BASE64 }} + AC_APIKEY_ID: ${{ secrets.AC_APIKEY_ID }} + AC_APIKEY_ISSUER_ID: ${{ secrets.AC_APIKEY_ISSUER_ID }} + + - name: Package and publish for macOS + run: bun x electron-builder --mac --publish always + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-linux: + name: Build and Release Linux + runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-cmux + + - name: Install ImageMagick + run: sudo apt-get update && sudo apt-get install -y imagemagick + + - name: Build application + run: bun run build + + - name: Package and publish for Linux + run: bun x electron-builder --linux --publish always + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index a5893e2f1..0cd7365b1 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,10 @@ "build": { "appId": "com.cmux.app", "productName": "Cmux", + "publish": { + "provider": "github", + "releaseType": "release" + }, "directories": { "output": "release" }, diff --git a/scripts/setup-macos-signing.sh b/scripts/setup-macos-signing.sh new file mode 100755 index 000000000..0c23800aa --- /dev/null +++ b/scripts/setup-macos-signing.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Sets up macOS code signing and notarization from GitHub secrets +# Usage: ./scripts/setup-macos-signing.sh +# +# Required environment variables: +# MACOS_CERTIFICATE - Base64-encoded .p12 certificate +# MACOS_CERTIFICATE_PWD - Certificate password +# AC_APIKEY_P8_BASE64 - Base64-encoded Apple API key (.p8) +# AC_APIKEY_ID - Apple API Key ID +# AC_APIKEY_ISSUER_ID - Apple API Issuer ID + +set -euo pipefail + +# Setup code signing certificate +if [ -n "${MACOS_CERTIFICATE:-}" ]; then + echo "Setting up code signing certificate..." + echo "$MACOS_CERTIFICATE" | base64 -D > /tmp/certificate.p12 + echo "CSC_LINK=/tmp/certificate.p12" >> "$GITHUB_ENV" + echo "CSC_KEY_PASSWORD=$MACOS_CERTIFICATE_PWD" >> "$GITHUB_ENV" +else + echo "⚠️ No code signing certificate provided - building unsigned" +fi + +# Setup notarization credentials +if [ -n "${AC_APIKEY_ID:-}" ]; then + echo "Setting up notarization credentials..." + echo "$AC_APIKEY_P8_BASE64" | base64 -D > /tmp/AuthKey.p8 + echo "APPLE_API_KEY=/tmp/AuthKey.p8" >> "$GITHUB_ENV" + echo "APPLE_API_KEY_ID=$AC_APIKEY_ID" >> "$GITHUB_ENV" + echo "APPLE_API_ISSUER=$AC_APIKEY_ISSUER_ID" >> "$GITHUB_ENV" + echo "✅ Notarization credentials configured" +else + echo "⚠️ No notarization credentials - skipping notarization" +fi