Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/actions/check-comment-trigger/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Check if e2e-desktop should run: trigger in comment, or (optional) main branch, or [e2e] in commit.
# Use in e2e-desktop-comment.yml (comment only) or ci.yml (comment + main + commit).

name: Check comment trigger
description: Check if trigger phrase in PR comment; optionally also main branch or [e2e] in commit
inputs:
trigger:
description: Trigger phrase to look for (e.g. /e2e-desktop)
required: true
check_main:
description: Also return true when ref is refs/heads/main
required: false
default: "false"
check_commit:
description: Also return true when [e2e] in commit message
required: false
default: "false"
allow_workflow_dispatch:
description: When true, workflow_dispatch events always return true (for manual runs)
required: false
default: "false"
outputs:
should_run:
description: "true if any condition matches, else false"
value: ${{ steps.check.outputs.should_run }}
runs:
using: composite
steps:
- name: Check if e2e-desktop should run
id: check
uses: actions/github-script@v7
env:
TRIGGER: ${{ inputs.trigger }}
CHECK_MAIN: ${{ inputs.check_main }}
CHECK_COMMIT: ${{ inputs.check_commit }}
ALLOW_WORKFLOW_DISPATCH: ${{ inputs.allow_workflow_dispatch }}
with:
script: |
const trigger = process.env.TRIGGER;
const checkMain = process.env.CHECK_MAIN === 'true';
const checkCommit = process.env.CHECK_COMMIT === 'true';
const allowWorkflowDispatch = process.env.ALLOW_WORKFLOW_DISPATCH === 'true';

if (allowWorkflowDispatch && context.eventName === 'workflow_dispatch') {
core.setOutput('should_run', 'true');
return;
}

if (checkMain && context.ref === 'refs/heads/main') {
core.setOutput('should_run', 'true');
return;
}

if (checkCommit) {
let msg = '';
if (context.eventName === 'push' && context.payload.head_commit) {
msg = context.payload.head_commit.message || '';
} else if (context.eventName === 'pull_request' && context.payload.pull_request) {
const pr = context.payload.pull_request;
const { data: commit } = await github.rest.repos.getCommit({
owner: context.repo.owner,
repo: context.repo.repo,
ref: pr.head.sha,
});
msg = commit.commit?.message || '';
}
if (msg.includes('[e2e]')) {
core.setOutput('should_run', 'true');
return;
}
}

let commentMatch = false;
if (context.eventName === 'issue_comment' && context.payload.issue?.pull_request) {
commentMatch = (context.payload.comment?.body || '').includes(trigger);
} else if (context.eventName === 'pull_request' && context.payload.pull_request) {
const pr = context.payload.pull_request;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
});
commentMatch = comments.some(c => c.body && c.body.includes(trigger));
}

core.setOutput('should_run', commentMatch ? 'true' : 'false');
33 changes: 33 additions & 0 deletions .github/actions/install-linux-deps/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Install Linux deps
description: Install build and runtime deps for Tauri app on Ubuntu
inputs:
e2e:
description: Include E2E desktop deps (webkit2gtk-driver, xvfb, gnome-keyring)
required: false
default: 'false'
verify_glib:
description: Run glib verification (dpkg, pkg-config checks)
required: false
default: 'true'
runs:
using: composite
steps:
- name: Install Linux deps
shell: bash
run: |
BASE_DEPS="build-essential pkg-config libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libsecret-1-dev"
E2E_DEPS="webkit2gtk-driver xvfb gnome-keyring"
sudo apt-get update
if [ "${{ inputs.e2e }}" = "true" ]; then
sudo apt-get install -y $BASE_DEPS $E2E_DEPS
else
sudo apt-get install -y $BASE_DEPS
fi
if [ "${{ inputs.verify_glib }}" = "true" ]; then
echo "=== Verifying glib-2.0 installation ==="
dpkg -l | grep libglib2.0-dev || echo "libglib2.0-dev not installed"
find /usr -name 'glib-2.0.pc' 2>/dev/null || echo "glib-2.0.pc not found"
pkg-config --modversion glib-2.0 || echo "pkg-config cannot find glib-2.0"
pkg-config --exists 'glib-2.0 >= 2.70' && echo "glib-2.0 >= 2.70 found" || (echo "ERROR: glib-2.0 >= 2.70 not found"; exit 1)
fi
echo "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV
136 changes: 31 additions & 105 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ on:
branches: [main]

# Cancel in-progress runs when a new commit is pushed to the same PR.
# PR: same group per PR so new push cancels previous run. Push to main: unique group so no cancel.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
Expand All @@ -31,15 +30,7 @@ jobs:
- uses: actions/checkout@v4

- name: Install Linux deps
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libsecret-1-dev
echo "=== Verifying glib-2.0 installation ==="
dpkg -l | grep libglib2.0-dev || echo "libglib2.0-dev not installed"
find /usr -name 'glib-2.0.pc' 2>/dev/null || echo "glib-2.0.pc not found"
pkg-config --modversion glib-2.0 || echo "pkg-config cannot find glib-2.0"
pkg-config --exists 'glib-2.0 >= 2.70' && echo "glib-2.0 >= 2.70 found" || (echo "ERROR: glib-2.0 >= 2.70 not found"; exit 1)
echo "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV
uses: ./.github/actions/install-linux-deps

- uses: dtolnay/rust-toolchain@stable
with:
Expand Down Expand Up @@ -73,10 +64,9 @@ jobs:
- uses: actions/checkout@v4

- name: Install Linux deps
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libsecret-1-dev
echo "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV
uses: ./.github/actions/install-linux-deps
with:
verify_glib: 'false'

- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
Expand Down Expand Up @@ -112,15 +102,7 @@ jobs:

- name: Install Linux deps
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libsecret-1-dev
echo "=== Verifying glib-2.0 installation ==="
dpkg -l | grep libglib2.0-dev || echo "libglib2.0-dev not installed"
find /usr -name 'glib-2.0.pc' 2>/dev/null || echo "glib-2.0.pc not found"
pkg-config --modversion glib-2.0 || echo "pkg-config cannot find glib-2.0"
pkg-config --exists 'glib-2.0 >= 2.70' && echo "glib-2.0 >= 2.70 found" || (echo "ERROR: glib-2.0 >= 2.70 not found"; exit 1)
echo "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV
uses: ./.github/actions/install-linux-deps

- uses: dtolnay/rust-toolchain@stable
with:
Expand Down Expand Up @@ -168,15 +150,7 @@ jobs:

- name: Install Linux deps
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libsecret-1-dev
echo "=== Verifying glib-2.0 installation ==="
dpkg -l | grep libglib2.0-dev || echo "libglib2.0-dev not installed"
find /usr -name 'glib-2.0.pc' 2>/dev/null || echo "glib-2.0.pc not found"
pkg-config --modversion glib-2.0 || echo "pkg-config cannot find glib-2.0"
pkg-config --exists 'glib-2.0 >= 2.70' && echo "glib-2.0 >= 2.70 found" || (echo "ERROR: glib-2.0 >= 2.70 not found"; exit 1)
echo "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV
uses: ./.github/actions/install-linux-deps

- uses: dtolnay/rust-toolchain@stable
with:
Expand Down Expand Up @@ -243,80 +217,32 @@ jobs:
retention-days: 7

# ─────────────────────────────────────────────────────────────
# E2E Tests (Full Tauri with WebDriver - Linux/Windows only)
# macOS not supported: no WKWebView driver
# Only runs on main branch or when [e2e] in commit message
# E2E Desktop trigger check: main, [e2e] in commit, or /e2e-desktop comment on PR
# ─────────────────────────────────────────────────────────────
e2e-tauri:
needs: [build]
# Run on main, or when explicitly requested with [e2e] tag
if: github.ref == 'refs/heads/main' || contains(github.event.head_commit.message, '[e2e]')
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: windows-latest
# macOS NOT supported - no WKWebView driver

runs-on: ${{ matrix.os }}
e2e-trigger-check:
runs-on: ubuntu-latest
permissions:
pull-requests: read
contents: read
outputs:
run_e2e: ${{ steps.check.outputs.should_run }}
steps:
- uses: actions/checkout@v4

- name: Install Linux deps
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libsecret-1-dev webkit2gtk-driver xvfb
echo "=== Verifying glib-2.0 installation ==="
dpkg -l | grep libglib2.0-dev || echo "libglib2.0-dev not installed"
find /usr -name 'glib-2.0.pc' 2>/dev/null || echo "glib-2.0.pc not found"
pkg-config --modversion glib-2.0 || echo "pkg-config cannot find glib-2.0"
pkg-config --exists 'glib-2.0 >= 2.70' && echo "glib-2.0 >= 2.70 found" || (echo "ERROR: glib-2.0 >= 2.70 not found"; exit 1)
echo "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV

- uses: dtolnay/rust-toolchain@stable
env:
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig

- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
- name: Check if e2e-desktop should run
id: check
uses: ./.github/actions/check-comment-trigger
with:
node-version: 20
cache: 'pnpm'

- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.os }}-e2e
env:
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
trigger: '/e2e-desktop'
check_main: 'true'
check_commit: 'true'

# Cache tauri-driver binary
- name: Cache tauri-driver
uses: actions/cache@v4
id: tauri-driver-cache
with:
path: ~/.cargo/bin/tauri-driver*
key: tauri-driver-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}

- name: Install tauri-driver
if: steps.tauri-driver-cache.outputs.cache-hit != 'true'
run: cargo install tauri-driver --locked
env:
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig

- run: pnpm install --frozen-lockfile

- name: Build app
run: pnpm build
env:
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}

- name: Run Tauri E2E tests (Linux)
if: matrix.os == 'ubuntu-latest'
run: xvfb-run --auto-servernum pnpm test:e2e

- name: Run Tauri E2E tests (Windows)
if: matrix.os == 'windows-latest'
run: pnpm test:e2e
# ─────────────────────────────────────────────────────────────
# E2E Tests (Desktop app with WebDriver - Linux/Windows only)
# Runs when: main branch, [e2e] in commit, or /e2e-desktop comment on PR
# ─────────────────────────────────────────────────────────────
e2e-desktop:
needs: [build, e2e-trigger-check]
if: needs.e2e-trigger-check.outputs.run_e2e == 'true'
uses: ./.github/workflows/e2e-desktop.yml
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
secrets: inherit
58 changes: 58 additions & 0 deletions .github/workflows/e2e-desktop-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Trigger desktop E2E tests when someone comments /e2e-desktop on a PR, or manually.
# Calls the reusable e2e-desktop workflow with the PR head ref.

name: E2E Desktop (Comment Trigger)

on:
issue_comment:
types: [created]
workflow_dispatch:
inputs:
pr:
description: PR number to run E2E on (required for manual run)
required: true
type: number

jobs:
check-trigger:
runs-on: ubuntu-latest
outputs:
should_run: ${{ steps.check.outputs.should_run }}
steps:
- name: Check comment trigger
id: check
uses: ./.github/actions/check-comment-trigger
with:
trigger: '/e2e-desktop'
allow_workflow_dispatch: 'true'

get-pr-ref:
needs: check-trigger
if: needs.check-trigger.outputs.should_run == 'true'
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
ref: ${{ steps.pr.outputs.sha }}
steps:
- name: Get PR head ref
id: pr
uses: actions/github-script@v7
with:
script: |
const prNumber = context.eventName === 'workflow_dispatch'
? context.payload.inputs.pr
: context.issue.number;
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: Number(prNumber),
});
core.setOutput('sha', pr.data.head.sha);

e2e-desktop:
needs: get-pr-ref
uses: ./.github/workflows/e2e-desktop.yml
with:
ref: ${{ needs.get-pr-ref.outputs.ref }}
secrets: inherit
Loading
Loading