Files
Stirling-PDF/.github/workflows/desktop-e2e.yml
T

231 lines
9.7 KiB
YAML

name: Desktop E2E
# Launches the real desktop app and exercises it. tauri-build.yml proves the
# bundle *compiles and packages*; nothing there ever runs it. This workflow
# covers what only shows up at runtime.
#
# Two suites, because tauri-driver has no macOS backend (Apple ships no
# WebDriver for WKWebView):
#
# smoke - launches the binary, reads the backend port off its stdout, and
# runs real tools over HTTP. No webview driver, so it runs on all
# three platforms. This is where per-platform runtime bugs live:
# a jlink runtime missing a module, a JRE older than the JAR, or
# JPDFium natives not published for this OS/arch.
# ui - drives the real webview through tauri-driver: window opens, the
# frontend mounts, and a tool runs end to end from the UI.
# Linux + Windows only.
on:
workflow_call:
inputs:
platform:
description: "Platform to test (linux, windows, macos, or all)."
required: false
type: string
default: "linux"
workflow_dispatch:
inputs:
platform:
description: "Platform to test (linux, windows, macos, or all)"
required: true
default: "all"
type: choice
options:
- all
- linux
- windows
- macos
permissions:
contents: read
jobs:
determine-matrix:
if: ${{ vars.CI_PROFILE != 'lite' }}
runs-on: ubuntu-latest
timeout-minutes: 3
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Determine test matrix
id: set-matrix
env:
PLATFORM: ${{ inputs.platform }}
run: |
# `webdriver` gates the UI suite: macOS runs the headless smoke only,
# because tauri-driver cannot drive WKWebView. macos-15 runners are
# Apple silicon, hence darwin-arm64 natives.
LINUX='{"os":"ubuntu-22.04","name":"linux","jpdfium_platforms":"linux-x64","webdriver":true}'
WINDOWS='{"os":"windows-latest","name":"windows","jpdfium_platforms":"windows-x64","webdriver":true}'
MACOS='{"os":"macos-15","name":"macos","jpdfium_platforms":"darwin-arm64","webdriver":false}'
case "$PLATFORM" in
windows) ENTRIES=("$WINDOWS") ;;
macos) ENTRIES=("$MACOS") ;;
all) ENTRIES=("$LINUX" "$WINDOWS" "$MACOS") ;;
*) ENTRIES=("$LINUX") ;;
esac
JOINED=$(IFS=','; echo "${ENTRIES[*]}")
echo "matrix={\"include\":[$JOINED]}" >> $GITHUB_OUTPUT
e2e:
name: desktop-e2e (${{ matrix.name }})
needs: determine-matrix
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.determine-matrix.outputs.matrix) }}
runs-on: ${{ matrix.os }}
timeout-minutes: 75
steps:
- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# webkit2gtk-driver supplies WebKitWebDriver, which tauri-driver proxies
# to; xvfb gives the app a display to open its window on.
- name: Install Linux dependencies
if: matrix.name == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev webkit2gtk-driver xvfb
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: "npm"
cache-dependency-path: frontend/package-lock.json
- name: Setup Rust
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
with:
toolchain: stable
- name: Cache Rust build
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: frontend/editor/src-tauri
# Shares tauri-build's cache: both build the app crate with real
# resources, so the dependency crates are byte-identical. macOS has no
# shared entry - tauri-build's macOS leg targets universal-apple-darwin
# while this one builds host-native - so it gets its own key.
shared-key: ${{ matrix.name == 'linux' && 'tauri-linux-x86_64' || matrix.name == 'windows' && 'tauri-windows-x86_64' || 'desktop-e2e-macos' }}
save-if: ${{ matrix.name == 'macos' && github.ref == 'refs/heads/main' }}
cache-on-failure: true
- name: Set up JDK 25
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: "25"
distribution: "temurin"
- name: Cache Gradle User Home
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ runner.arch }}-jdk-25-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties', 'gradle/libs.versions.toml', 'settings.gradle', 'build.gradle', 'app/**/build.gradle', 'gradle/**/*.gradle') }}
restore-keys: |
gradle-${{ runner.os }}-${{ runner.arch }}-jdk-25-
gradle-${{ runner.os }}-${{ runner.arch }}-
- name: Setup Task
uses: go-task/setup-task@01a4adf9db2d14c1de7a560f09170b6e0df736aa # v2.1.0
# --no-bundle: a launchable binary with the JRE and JAR staged beside it,
# without paying for deb/rpm/AppImage/MSI packaging that tauri-build
# already covers.
- name: Build desktop app (no bundle)
env:
MAVEN_USER: ${{ secrets.MAVEN_USER }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
MAVEN_PUBLIC_URL: ${{ secrets.MAVEN_PUBLIC_URL }}
DISABLE_ADDITIONAL_FEATURES: true
JPDFIUM_PLATFORMS: ${{ matrix.jpdfium_platforms }}
VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY: ${{ secrets.VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY || 'sb_publishable_UHz2SVRF5mvdrPHWkRteyA_yNlZTkYb' }} # gitleaks:allow
VITE_SAAS_SERVER_URL: ${{ secrets.VITE_SAAS_SERVER_URL || 'https://app.stirlingpdf.com' }}
VITE_SAAS_BACKEND_API_URL: ${{ secrets.VITE_SAAS_BACKEND_API_URL || 'https://api.stirlingpdf.com' }}
CI: true
run: task desktop:build:dev
# Runs everywhere, including macOS. Needs no npm install - the runner is
# plain Node - so this is the cheapest real coverage in the workflow.
- name: Run desktop smoke (Linux)
if: matrix.name == 'linux'
env:
WEBKIT_DISABLE_COMPOSITING_MODE: "1"
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x1024x24" task desktop:smoke
- name: Run desktop smoke (Windows / macOS)
if: matrix.name != 'linux'
run: task desktop:smoke
- name: Install E2E harness
if: matrix.webdriver
env:
CI: true
run: task desktop:e2e:install
# msedgedriver must match the installed WebView2/Edge major version. The
# runner image ships a driver that usually already matches; fall back to
# the exact build from Microsoft's CDN when it has drifted.
- name: Resolve Edge WebDriver (Windows)
if: matrix.name == 'windows'
shell: pwsh
run: |
$edgeExe = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
if (-not (Test-Path $edgeExe)) { Write-Host "[ERROR] Edge not found"; exit 1 }
$edgeVersion = (Get-Item $edgeExe).VersionInfo.ProductVersion
Write-Host "Edge version: $edgeVersion"
$preinstalled = "C:\SeleniumWebDrivers\EdgeDriver\msedgedriver.exe"
if (Test-Path $preinstalled) {
$driverVersion = (Get-Item $preinstalled).VersionInfo.ProductVersion
Write-Host "Preinstalled driver version: $driverVersion"
if ($driverVersion.Split('.')[0] -eq $edgeVersion.Split('.')[0]) {
Write-Host "Using preinstalled msedgedriver"
echo "TAURI_DRIVER_NATIVE=$preinstalled" >> $env:GITHUB_ENV
exit 0
}
Write-Host "Major version mismatch - downloading a matching driver"
}
$dest = Join-Path $env:RUNNER_TEMP "edgedriver"
New-Item -ItemType Directory -Force -Path $dest | Out-Null
$zip = Join-Path $env:RUNNER_TEMP "edgedriver.zip"
Invoke-WebRequest -Uri "https://msedgedriver.microsoft.com/$edgeVersion/edgedriver_win64.zip" -OutFile $zip
Expand-Archive -Path $zip -DestinationPath $dest -Force
echo "TAURI_DRIVER_NATIVE=$dest\msedgedriver.exe" >> $env:GITHUB_ENV
- name: Run desktop UI E2E (Linux)
if: matrix.name == 'linux'
env:
# WebKitGTK's compositing path is unreliable under Xvfb's software
# GL; the app already disables the DMA-BUF renderer itself.
WEBKIT_DISABLE_COMPOSITING_MODE: "1"
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x1024x24" task desktop:e2e
- name: Run desktop UI E2E (Windows)
if: matrix.name == 'windows'
run: task desktop:e2e
- name: Upload E2E logs
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: desktop-e2e-${{ matrix.name }}-${{ github.run_id }}
path: frontend/desktop-e2e/logs/
retention-days: 7
if-no-files-found: ignore