name: Desktop Release on: push: tags: - "v*" env: CARGO_TERM_COLOR: always jobs: build: name: Build ${{ matrix.platform.os-name }} (${{ matrix.target }}) runs-on: ${{ matrix.platform.os }} strategy: fail-fast: false matrix: include: # Linux x64 - platform: os: ubuntu-latest os-name: linux target: x86_64-unknown-linux-gnu bundles: deb,rpm,appimage # Linux ARM64 - platform: os: ubuntu-latest os-name: linux target: aarch64-unknown-linux-gnu bundles: deb,rpm,appimage # macOS (universal binary) - platform: os: macos-latest os-name: macos target: universal-apple-darwin bundles: dmg # Windows - platform: os: windows-latest os-name: windows target: x86_64-pc-windows-msvc bundles: nsis steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v2 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - name: Cache Cargo registry uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo- - name: Cache Bun dependencies uses: actions/cache@v4 with: path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} restore-keys: | ${{ runner.os }}-bun- - name: Cache Rust target uses: actions/cache@v4 with: path: | src-tauri/target key: ${{ runner.os }}-${{ matrix.target }}-rust-target-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-${{ matrix.target }}-rust-target- - name: Install Linux dependencies if: matrix.platform.os == 'ubuntu-latest' run: | sudo apt-get update sudo apt-get install -y \ libwebkit2gtk-4.1-dev \ libgtk-3-dev \ libayatana-appindicator3-dev \ librsvg2-dev \ libsoup-3.0-dev \ libjavascriptcoregtk-4.1-dev \ patchelf # Cross-compilation support for ARM64 if [ "${{ matrix.target }}" = "aarch64-unknown-linux-gnu" ]; then sudo apt-get install -y \ gcc-aarch64-linux-gnu \ g++-aarch64-linux-gnu fi - name: Setup macOS keychain (for signing) if: matrix.platform.os == 'macos-latest' env: APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} run: | if [ -n "$APPLE_CERTIFICATE" ]; then # Create temporary keychain KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db KEYCHAIN_PASSWORD=$(openssl rand -base64 32) security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" # Import certificate CERTIFICATE_PATH=$RUNNER_TEMP/certificate.p12 echo -n "$APPLE_CERTIFICATE" | base64 --decode -o "$CERTIFICATE_PATH" security import "$CERTIFICATE_PATH" \ -P "$APPLE_CERTIFICATE_PASSWORD" \ -A -t cert -f pkcs12 \ -k "$KEYCHAIN_PATH" security list-keychain -d user -s "$KEYCHAIN_PATH" fi - name: Install frontend dependencies run: bun install --frozen-lockfile - name: Build frontend run: bun run build - name: Build Tauri app uses: tauri-apps/tauri-action@v0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # macOS signing APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} # Windows signing WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} # Cross-compilation for Linux ARM64 CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc CXX_aarch64_unknown_linux_gnu: aarch64-linux-gnu-g++ with: tagName: ${{ github.ref_name }} releaseName: "Compass Desktop ${{ github.ref_name }}" releaseBody: "See CHANGELOG.md for details." releaseDraft: true prerelease: false args: | --target ${{ matrix.target }} --bundles ${{ matrix.bundles }} release: name: Create Release needs: build runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') steps: - name: Checkout repository uses: actions/checkout@v4 - name: Generate Release Notes id: release-notes run: | # Extract version from tag (controlled by GitHub, not user input) VERSION="${GITHUB_REF#refs/tags/}" # Check if CHANGELOG.md exists and extract notes for this version if [ -f "CHANGELOG.md" ]; then # Extract section for current version NOTES=$(sed -n "/^## \[$VERSION\]/,/^## \[/p" CHANGELOG.md | sed '1d;$d') if [ -z "$NOTES" ]; then NOTES="Release $VERSION" fi else NOTES="Release $VERSION" fi # Save to file for multiline output echo "$NOTES" > /tmp/release-notes.md - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: body_path: /tmp/release-notes.md draft: true generate_release_notes: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}