Tauri Build Actions

This commit is contained in:
Connor Yoh 2025-07-07 18:10:45 +01:00
parent 9a3712259b
commit 4fcfaa1f4d
3 changed files with 594 additions and 0 deletions

152
.github/workflows/README-tauri.md vendored Normal file
View File

@ -0,0 +1,152 @@
# Tauri Build Workflows
This directory contains GitHub Actions workflows for building Tauri desktop applications for Stirling-PDF.
## Workflows
### 1. `tauri-build.yml` - Production Build Workflow
**Purpose**: Build Tauri applications for all platforms (Windows, macOS, Linux) and optionally create releases.
**Triggers**:
- Manual dispatch with options for test mode and platform selection
- Pull requests affecting Tauri-related files
- Pushes to main branch affecting Tauri-related files
**Platforms**:
- **Windows**: x86_64 (exe and msi)
- **macOS**: Apple Silicon (aarch64) and Intel (x86_64) (dmg)
- **Linux**: x86_64 (deb and AppImage)
**Features**:
- Builds Java backend first
- Installs all dependencies
- Creates signed artifacts (if signing keys are configured)
- Validates all artifacts are created successfully
- Can create GitHub releases (when not in test mode)
### 2. `tauri-test.yml` - Test Workflow
**Purpose**: Test Tauri builds without creating releases - perfect for validating changes.
**Triggers**:
- Manual dispatch with platform selection
- Pull requests affecting Tauri-related files
**Features**:
- Allows testing specific platforms or all platforms
- Validates build artifacts are created
- Checks artifact sizes
- Reports results without creating releases
## Usage
### Testing Before Merge
1. **Test All Platforms**:
```bash
# Go to Actions tab in GitHub
# Run "Test Tauri Build" workflow
# Select "all" for platform
```
2. **Test Specific Platform**:
```bash
# Go to Actions tab in GitHub
# Run "Test Tauri Build" workflow
# Select specific platform (windows/macos/linux)
```
### Production Builds
1. **Test Mode** (recommended for PRs):
```bash
# Go to Actions tab in GitHub
# Run "Build Tauri Applications" workflow
# Set test_mode: true
```
2. **Release Mode**:
```bash
# Go to Actions tab in GitHub
# Run "Build Tauri Applications" workflow
# Set test_mode: false
# This will create a GitHub release
```
## Configuration
### Required Secrets (Optional)
For signed builds, configure these secrets in your repository:
- `TAURI_SIGNING_PRIVATE_KEY`: Private key for signing Tauri applications
- `TAURI_SIGNING_PRIVATE_KEY_PASSWORD`: Password for the signing private key
### File Structure
The workflows expect this structure:
```
├── frontend/
│ ├── src-tauri/
│ │ ├── Cargo.toml
│ │ ├── tauri.conf.json
│ │ └── src/
│ ├── package.json
│ └── src/
├── gradlew
└── stirling-pdf/
└── build/libs/
```
## Validation
Both workflows include comprehensive validation:
1. **Build Validation**: Ensures all expected artifacts are created
2. **Size Validation**: Checks artifacts aren't suspiciously small
3. **Platform Validation**: Verifies platform-specific requirements
4. **Integration Testing**: Tests that Java backend builds correctly
## Troubleshooting
### Common Issues
1. **Missing Dependencies**:
- Ubuntu: Ensure system dependencies are installed
- macOS: Check Rust toolchain targets
- Windows: Verify MSVC tools are available
2. **Java Backend Build Fails**:
- Check Gradle permissions (`chmod +x ./gradlew`)
- Verify JDK 21 is properly configured
3. **Artifact Size Issues**:
- Small artifacts usually indicate build failures
- Check that backend JAR is properly copied to Tauri resources
4. **Signing Issues**:
- Ensure signing secrets are configured if needed
- Check that signing keys are valid
### Debugging
1. **Check Logs**: Each step provides detailed logging
2. **Artifact Inspection**: Download artifacts to verify contents
3. **Local Testing**: Test builds locally before running workflows
## Integration with Existing Workflows
These workflows are designed to complement the existing build system:
- Uses same JDK and Gradle setup as `build.yml`
- Follows same security practices as `multiOSReleases.yml`
- Compatible with existing release processes
## Next Steps
1. Test the workflows on your branch
2. Verify all platforms build successfully
3. Check artifact quality and sizes
4. Configure signing if needed
5. Merge when all tests pass

252
.github/workflows/tauri-build.yml vendored Normal file
View File

@ -0,0 +1,252 @@
name: Build Tauri Applications
on:
workflow_dispatch:
inputs:
test_mode:
description: "Run in test mode (skip release step)"
required: false
default: "true"
type: boolean
target_platforms:
description: "Target platforms (comma-separated: windows,macos,linux)"
required: false
default: "windows,macos,linux"
pull_request:
branches: [main]
paths:
- 'frontend/src-tauri/**'
- 'frontend/src/**'
- 'frontend/package.json'
- 'frontend/package-lock.json'
- '.github/workflows/tauri-build.yml'
push:
branches: [main]
paths:
- 'frontend/src-tauri/**'
- 'frontend/src/**'
- 'frontend/package.json'
- 'frontend/package-lock.json'
- '.github/workflows/tauri-build.yml'
permissions:
contents: read
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
jobs:
build-tauri:
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- platform: 'macos-latest'
args: '--target aarch64-apple-darwin'
name: 'macos-aarch64'
- platform: 'macos-latest'
args: '--target x86_64-apple-darwin'
name: 'macos-x86_64'
- platform: 'ubuntu-20.04'
args: ''
name: 'linux-x86_64'
- platform: 'windows-latest'
args: '--target x86_64-pc-windows-msvc'
name: 'windows-x86_64'
runs-on: ${{ matrix.platform }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
- name: Setup Node.js
uses: actions/setup-node@0ad00a8b5b3388e41dc48b8dd2912fcdecfb8ca6 # v4.3.1
with:
node-version: 18
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Setup Rust
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336d9b35a # stable
with:
toolchain: stable
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Rust cache
uses: swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5
with:
workspaces: './frontend/src-tauri -> target'
- name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "21"
distribution: "temurin"
- name: Build Java backend
working-directory: ./
run: |
chmod +x ./gradlew
./gradlew clean build -x test
env:
DISABLE_ADDITIONAL_FEATURES: true
- name: Install frontend dependencies
working-directory: ./frontend
run: npm ci
- name: Copy backend JAR to Tauri resources
run: |
mkdir -p ./frontend/src-tauri/libs
cp ./stirling-pdf/build/libs/Stirling-PDF-*.jar ./frontend/src-tauri/libs/stirling-pdf.jar
- name: Build Tauri app
uses: tauri-apps/tauri-action@6fdd37473788d5a2b4dd80e7ccc0b3c7fe8a5bcd # v0.5.7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
projectPath: ./frontend
args: ${{ matrix.args }}
uploadToDraftRelease: false
- name: Rename artifacts
shell: bash
run: |
mkdir -p ./dist
cd ./frontend/src-tauri/target
# Find and rename artifacts based on platform
if [ "${{ matrix.platform }}" = "windows-latest" ]; then
find . -name "*.exe" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.exe" \;
find . -name "*.msi" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.msi" \;
elif [ "${{ matrix.platform }}" = "macos-latest" ]; then
find . -name "*.dmg" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.dmg" \;
find . -name "*.app" -exec cp -r {} "../../../dist/Stirling-PDF-${{ matrix.name }}.app" \;
else
find . -name "*.deb" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.deb" \;
find . -name "*.AppImage" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.AppImage" \;
fi
- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: tauri-${{ matrix.name }}
path: ./dist/*
retention-days: 7
test-build:
needs: build-tauri
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit
- name: Download all artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- name: Display structure of downloaded files
run: ls -la */
- name: Verify artifacts exist
run: |
expected_files=(
"tauri-windows-x86_64/Stirling-PDF-windows-x86_64.exe"
"tauri-macos-aarch64/Stirling-PDF-macos-aarch64.dmg"
"tauri-macos-x86_64/Stirling-PDF-macos-x86_64.dmg"
"tauri-linux-x86_64/Stirling-PDF-linux-x86_64.deb"
)
missing_files=()
for file in "${expected_files[@]}"; do
if [ ! -f "$file" ]; then
missing_files+=("$file")
fi
done
if [ ${#missing_files[@]} -gt 0 ]; then
echo "ERROR: Missing expected artifacts:"
printf '%s\n' "${missing_files[@]}"
exit 1
fi
echo "✅ All expected artifacts are present"
- name: Check artifact sizes
run: |
echo "Artifact sizes:"
find . -name "*.exe" -o -name "*.dmg" -o -name "*.deb" -o -name "*.AppImage" | while read file; do
size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || echo "unknown")
echo "$file: $size bytes"
done
create-release:
if: github.event_name != 'workflow_dispatch' || github.event.inputs.test_mode != 'true'
needs: [build-tauri, test-build]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Download all artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- name: Get version from package.json
id: version
run: |
VERSION=$(grep '"version"' frontend/package.json | cut -d'"' -f4)
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Create Release
uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # v2.3.2
with:
tag_name: v${{ steps.version.outputs.VERSION }}-tauri
name: Stirling-PDF Tauri v${{ steps.version.outputs.VERSION }}
body: |
# Stirling-PDF Tauri Desktop Applications
This release contains desktop applications built with Tauri for:
- Windows x86_64
- macOS Apple Silicon (ARM64)
- macOS Intel (x86_64)
- Linux x86_64
## Installation
### Windows
- Download `Stirling-PDF-windows-x86_64.exe` for a portable executable
- Download `Stirling-PDF-windows-x86_64.msi` for an installer
### macOS
- Download `Stirling-PDF-macos-aarch64.dmg` for Apple Silicon Macs
- Download `Stirling-PDF-macos-x86_64.dmg` for Intel Macs
### Linux
- Download `Stirling-PDF-linux-x86_64.deb` for Debian/Ubuntu
- Download `Stirling-PDF-linux-x86_64.AppImage` for universal Linux
draft: false
prerelease: true
files: |
tauri-*/*

190
.github/workflows/tauri-test.yml vendored Normal file
View File

@ -0,0 +1,190 @@
name: Test Tauri Build
on:
workflow_dispatch:
inputs:
platform:
description: "Platform to test (windows, macos, linux, or all)"
required: true
default: "all"
type: choice
options:
- all
- windows
- macos
- linux
pull_request:
branches: [main]
paths:
- 'frontend/src-tauri/**'
- 'frontend/src/**'
- 'frontend/package.json'
- 'frontend/package-lock.json'
- '.github/workflows/tauri-test.yml'
- '.github/workflows/tauri-build.yml'
permissions:
contents: read
jobs:
determine-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Determine build matrix
id: set-matrix
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
case "${{ github.event.inputs.platform }}" in
"windows")
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"}]}' >> $GITHUB_OUTPUT
;;
"macos")
echo 'matrix={"include":[{"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"}]}' >> $GITHUB_OUTPUT
;;
"linux")
echo 'matrix={"include":[{"platform":"ubuntu-20.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
;;
*)
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"ubuntu-20.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
;;
esac
else
# For PR/push events, test all platforms
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-latest","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"ubuntu-20.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
fi
test-build:
needs: determine-matrix
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.determine-matrix.outputs.matrix) }}
runs-on: ${{ matrix.platform }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
- name: Setup Node.js
uses: actions/setup-node@0ad00a8b5b3388e41dc48b8dd2912fcdecfb8ca6 # v4.3.1
with:
node-version: 18
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Setup Rust
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336d9b35a # stable
with:
toolchain: stable
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Rust cache
uses: swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5
with:
workspaces: './frontend/src-tauri -> target'
- name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "21"
distribution: "temurin"
- name: Build Java backend
working-directory: ./
run: |
chmod +x ./gradlew
./gradlew clean build -x test
env:
DISABLE_ADDITIONAL_FEATURES: true
- name: Install frontend dependencies
working-directory: ./frontend
run: npm ci
- name: Copy backend JAR to Tauri resources
run: |
mkdir -p ./frontend/src-tauri/libs
cp ./stirling-pdf/build/libs/Stirling-PDF-*.jar ./frontend/src-tauri/libs/stirling-pdf.jar
- name: Build Tauri app (test mode)
uses: tauri-apps/tauri-action@6fdd37473788d5a2b4dd80e7ccc0b3c7fe8a5bcd # v0.5.7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
projectPath: ./frontend
args: ${{ matrix.args }}
uploadToDraftRelease: false
- name: Verify build artifacts
shell: bash
run: |
cd ./frontend/src-tauri/target
# Check for expected artifacts based on platform
if [ "${{ matrix.platform }}" = "windows-latest" ]; then
echo "Checking for Windows artifacts..."
find . -name "*.exe" -o -name "*.msi" | head -5
if [ $(find . -name "*.exe" | wc -l) -eq 0 ]; then
echo "❌ No Windows executable found"
exit 1
fi
elif [ "${{ matrix.platform }}" = "macos-latest" ]; then
echo "Checking for macOS artifacts..."
find . -name "*.dmg" -o -name "*.app" | head -5
if [ $(find . -name "*.dmg" -o -name "*.app" | wc -l) -eq 0 ]; then
echo "❌ No macOS artifacts found"
exit 1
fi
else
echo "Checking for Linux artifacts..."
find . -name "*.deb" -o -name "*.AppImage" | head -5
if [ $(find . -name "*.deb" -o -name "*.AppImage" | wc -l) -eq 0 ]; then
echo "❌ No Linux artifacts found"
exit 1
fi
fi
echo "✅ Build artifacts found for ${{ matrix.name }}"
- name: Test artifact sizes
shell: bash
run: |
cd ./frontend/src-tauri/target
echo "Artifact sizes for ${{ matrix.name }}:"
find . -name "*.exe" -o -name "*.dmg" -o -name "*.deb" -o -name "*.AppImage" -o -name "*.msi" | while read file; do
if [ -f "$file" ]; then
size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || echo "unknown")
echo "$file: $size bytes"
# Check if file is suspiciously small (less than 1MB)
if [ "$size" != "unknown" ] && [ "$size" -lt 1048576 ]; then
echo "⚠️ Warning: $file is smaller than 1MB"
fi
fi
done
report-results:
needs: test-build
runs-on: ubuntu-latest
if: always()
steps:
- name: Report test results
run: |
if [ "${{ needs.test-build.result }}" = "success" ]; then
echo "✅ All Tauri build tests passed successfully!"
echo "The build action is ready to be merged."
else
echo "❌ Some Tauri build tests failed."
echo "Please check the logs and fix any issues before merging."
exit 1
fi