name: Build and Release on: push jobs: build_main: name: Build app (${{ matrix.dotnet_runtime }}) strategy: fail-fast: true matrix: include: - platform: 'macos-latest' # for ARM-based macOS (M1 and above) rust_target: 'aarch64-apple-darwin' dotnet_runtime: 'osx-arm64' dotnet_name_postfix: '-aarch64-apple-darwin' tauri_bundle: 'dmg' - platform: 'macos-latest' # for Intel-based macOS rust_target: 'x86_64-apple-darwin' dotnet_runtime: 'osx-x64' dotnet_name_postfix: '-x86_64-apple-darwin' tauri_bundle: 'dmg' - platform: 'ubuntu-22.04' # for x86-based linux rust_target: 'x86_64-unknown-linux-gnu' dotnet_runtime: 'linux-x64' dotnet_name_postfix: '-x86_64-unknown-linux-gnu' tauri_bundle: 'appimage deb' - platform: 'windows-latest' # for x86-based windows rust_target: 'x86_64-pc-windows-msvc' dotnet_runtime: 'win-x64' dotnet_name_postfix: '-x86_64-pc-windows-msvc.exe' tauri_bundle: 'msi nsis' - platform: 'windows-latest' # for ARM-based windows rust_target: 'aarch64-pc-windows-msvc' dotnet_runtime: 'win-arm64' dotnet_name_postfix: '-aarch64-pc-windows-msvc.exe' tauri_bundle: 'nsis' runs-on: ${{ matrix.platform }} steps: - name: Checkout repository uses: actions/checkout@v4 with: lfs: true # Enable Git LFS - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8' dotnet-quality: 'ga' cache: true cache-dependency-path: 'app/MindWork AI Studio/packages.lock.json' - name: Build .NET project run: | cd "app/MindWork AI Studio" dotnet publish --configuration release --runtime ${{ matrix.dotnet_runtime }} --disable-build-servers --force --output ../../publish/dotnet - name: Move & rename .NET artifact (Unix) if: matrix.platform != 'windows-latest' run: | mkdir -p "app/MindWork AI Studio/bin/dist" cd publish/dotnet mv mindworkAIStudio "../../app/MindWork AI Studio/bin/dist/mindworkAIStudio${{ matrix.dotnet_name_postfix }}" - name: Move & rename .NET artifact (Windows) if: matrix.platform == 'windows-latest' run: | New-Item -ItemType Directory -Path "app\MindWork AI Studio\bin\dist" -Force cd publish/dotnet mv mindworkAIStudio.exe "../../app/MindWork AI Studio/bin/dist/mindworkAIStudio${{ matrix.dotnet_name_postfix }}" - name: Create parts for the Rust cache key (Unix) if: matrix.platform != 'windows-latest' run: | cd runtime echo "RUST_VERSION=$(rustc --version | sed 's/rustc \([0-9.]*\).*/\1/')" >> $GITHUB_ENV echo "CARGO_LOCK_HASH=${{ hashFiles('**/Cargo.lock') }}" >> $GITHUB_ENV - name: Create parts for the Rust cache key (Windows) if: matrix.platform == 'windows-latest' run: | cd runtime echo "RUST_VERSION=$(rustc --version | ForEach-Object { $_ -replace 'rustc (\d+\.\d+\.\d+).*', '$1' })" >> $env:GITHUB_ENV echo "CARGO_LOCK_HASH=${{ hashFiles('**/Cargo.lock') }}" >> $env:GITHUB_ENV - name: Cache Rust uses: actions/cache@v4 with: path: | ~/.cargo/bin ~/.cargo/git/db/ ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.rustup/toolchains runtime/target/deps runtime/target/build # When the entire key matches, Rust might just create the bundles using the current .NET build: key: target-${{ matrix.dotnet_runtime }}-rust-${{ env.RUST_VERSION }}-dependencies-${{ env.CARGO_LOCK_HASH }} # - 1st key: the Rust runtime dependencies changed. Anyway, we might be able to re-use many previously built packages. # # - No match: alright, a new Rust version was released. Sadly, we cannot re-use anything now. Why? # The updated Rust compiler might mitigate some bugs or vulnerabilities. In order to apply # these changes to our app, we have to re-compile everything. That's the reason why it makes # no sense to use more parts for the cache key, like Tauri or Tauri build versions. restore-keys: | target-${{ matrix.dotnet_runtime }}-rust-${{ env.RUST_VERSION }}-dependencies- - name: Setup Rust (stable) uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.rust_target }} - name: Setup dependencies (Ubuntu-specific, x86) if: matrix.platform == 'ubuntu-22.04' && contains(matrix.rust_target, 'x86_64') run: | sudo apt-get update sudo apt-get install -y libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf - name: Setup Tauri (Unix) if: matrix.platform != 'windows-latest' run: | if ! cargo tauri --version > /dev/null 2>&1; then cargo install tauri-cli else echo "Tauri is already installed" fi - name: Setup Tauri (Windows) if: matrix.platform == 'windows-latest' run: | if (-not (cargo tauri --version 2>$null)) { cargo install tauri-cli } else { Write-Output "Tauri is already installed" } - name: Build Tauri project run: | cd runtime cargo tauri build --target ${{ matrix.rust_target }} --bundles ${{ matrix.tauri_bundle }} - name: Upload artifact (macOS) if: startsWith(matrix.platform, 'macos') uses: actions/upload-artifact@v4 with: name: MindWork AI Studio (macOS ${{ matrix.dotnet_runtime }}) path: "runtime/target/${{ matrix.rust_target }}/release/bundle/dmg/MindWork AI Studio_*.dmg" if-no-files-found: error retention-days: 1 - name: Upload artifact (Windows - MSI) if: startsWith(matrix.platform, 'windows') && contains(matrix.tauri_bundle, 'msi') uses: actions/upload-artifact@v4 with: name: MindWork AI Studio (Windows - MSI ${{ matrix.dotnet_runtime }}) path: "runtime/target/${{ matrix.rust_target }}/release/bundle/msi/MindWork AI Studio_*.msi" if-no-files-found: error retention-days: 1 - name: Upload artifact (Windows - NSIS) if: startsWith(matrix.platform, 'windows') && contains(matrix.tauri_bundle, 'nsis') uses: actions/upload-artifact@v4 with: name: MindWork AI Studio (Windows - NSIS ${{ matrix.dotnet_runtime }}) path: "runtime/target/${{ matrix.rust_target }}/release/bundle/nsis/MindWork AI Studio_*.exe" if-no-files-found: error retention-days: 1 - name: Upload artifact (Linux - Debian Package) if: startsWith(matrix.platform, 'ubuntu') && contains(matrix.tauri_bundle, 'deb') uses: actions/upload-artifact@v4 with: name: MindWork AI Studio (Linux - deb ${{ matrix.dotnet_runtime }}) path: "runtime/target/${{ matrix.rust_target }}/release/bundle/deb/mind-work-ai-studio_*.deb" if-no-files-found: error retention-days: 1 - name: Upload artifact (Linux - AppImage) if: startsWith(matrix.platform, 'ubuntu') && contains(matrix.tauri_bundle, 'appimage') uses: actions/upload-artifact@v4 with: name: MindWork AI Studio (Linux - AppImage ${{ matrix.dotnet_runtime }}) path: "runtime/target/${{ matrix.rust_target }}/release/bundle/appimage/mind-work-ai-studio_*.AppImage" if-no-files-found: error retention-days: 1 build_linux_arm64: name: Build app (linux-arm64) runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 with: lfs: true # Enable Git LFS - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8' dotnet-quality: 'ga' cache: true cache-dependency-path: 'app/MindWork AI Studio/packages.lock.json' - name: Build .NET project run: | cd "app/MindWork AI Studio" dotnet publish --configuration release --runtime linux-arm --disable-build-servers --force --output ../../publish/dotnet - name: Move & rename the .NET artifact run: | mkdir -p "app/MindWork AI Studio/bin/dist" cd publish/dotnet mv mindworkAIStudio "../../app/MindWork AI Studio/bin/dist/mindworkAIStudio-aarch64-unknown-linux-gnu" - name: Create parts for the Rust cache key run: | cd runtime echo "RUST_VERSION=$(rustc --version | sed 's/rustc \([0-9.]*\).*/\1/')" >> $GITHUB_ENV echo "CARGO_LOCK_HASH=${{ hashFiles('**/Cargo.lock') }}" >> $GITHUB_ENV - name: Cache linux arm64 runner image uses: actions/cache@v4 id: linux_arm_cache with: path: $RUNNER_TEMP/linux_arm_qemu_cache.img # When the entire key matches, Rust might just create the bundles using the current .NET build: key: target-linux-arm-rust-${{ env.RUST_VERSION }}-dependencies-${{ env.CARGO_LOCK_HASH }} # - 1st key: the Rust runtime dependencies changed. Anyway, we might be able to re-use many previously built packages. # # - No match: alright, a new Rust version was released. Sadly, we cannot re-use anything now. Why? # The updated Rust compiler might mitigate some bugs or vulnerabilities. In order to apply # these changes to our app, we have to re-compile everything. That's the reason why it makes # no sense to use more parts for the cache key, like Tauri or Tauri build versions. restore-keys: | target-linux-arm-rust-${{ env.RUST_VERSION }}-dependencies- - name: Build linux arm runner image uses: pguyot/arm-runner-action@v2.6.5 id: build-linux-arm-runner if: steps.linux_arm_cache.outputs.cache-hit != 'true' with: base_image: dietpi:rpi_armv8_bullseye cpu: cortex-a53 image_additional_mb: 5000 # ~ 5GB optimize_image: false shell: /bin/bash commands: | # Rust complains (rightly) that $HOME doesn't match eid home: export HOME=/root # Workaround to CI worker being stuck on Updating crates.io index: export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse # Update and upgrade the system: apt-get update --yes --allow-releaseinfo-change apt-get upgrade --yes apt-get autoremove --yes apt-get install curl wget --yes # Install Rust: curl https://sh.rustup.rs -sSf | sh -s -- -y . "$HOME/.cargo/env" # Install build tools and tauri-cli requirements: apt-get install --yes libwebkit2gtk-4.0-dev build-essential libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev # Setup Tauri: cargo install tauri-cli - name: Cache the built runner image if: steps.linux_arm_cache.outputs.cache-hit != 'true' run: | mv ${{ steps.build-linux-arm-runner.outputs.image }} $RUNNER_TEMP/linux_arm_qemu_cache.img - name: Compiling the Rust runtime uses: pguyot/arm-runner-action@v2.6.5 id: arm-runner if: steps.linux_arm_cache.outputs.cache-hit != 'true' with: base_image: file://$RUNNER_TEMP/linux_arm_qemu_cache.img cpu: cortex-a53 image_additional_mb: 5000 # ~ 5GB optimize_image: false shell: /bin/bash commands: | # Build the runtime: cd runtime cargo tauri build --target aarch64-unknown-linux-gnu --bundles deb - name: Upload artifact (Linux - Debian Package) uses: actions/upload-artifact@v4 with: name: MindWork AI Studio (Linux - deb linux-arm) path: "runtime/target/aarch64-unknown-linux-gnu/release/bundle/deb/mind-work-ai-studio_*.deb" if-no-files-found: error retention-days: 1