* feat: add conversations, desktop (Tauri), and offline sync Major new features: - conversations module: Slack-like channels, threads, reactions, pins - Tauri desktop app with local SQLite for offline-first operation - Hybrid logical clock sync engine with conflict resolution - DB provider abstraction (D1/Tauri/memory) with React context Conversations: - Text/voice/announcement channels with categories - Message threads, reactions, attachments, pinning - Real-time presence and typing indicators - Full-text search across messages Desktop (Tauri): - Local SQLite database with sync to cloud D1 - Offline mutation queue with automatic replay - Window management and keyboard shortcuts - Desktop shell with offline banner Sync infrastructure: - Vector clock implementation for causality tracking - Last-write-wins with semantic conflict resolution - Delta sync via checkpoints for bandwidth efficiency - Comprehensive test coverage Also adds e2e test setup with Playwright and CI workflows for desktop releases. * fix(tests): sync engine test schema and checkpoint logic - Add missing process_after column and sync_tombstone table to test schemas - Fix checkpoint update to save cursor even when records array is empty - Revert claude-code-review.yml workflow changes to match main --------- Co-authored-by: Nicholai <nicholaivogelfilms@gmail.com>
201 lines
6.5 KiB
YAML
201 lines
6.5 KiB
YAML
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 }}
|