From 4a4245fe79f9e9a3eaff963fb845c9dd047888f7 Mon Sep 17 00:00:00 2001 From: Mohammod Al Amin Ashik Date: Mon, 2 Feb 2026 02:34:37 +0800 Subject: [PATCH 1/2] chore(ci): enable release workflow and fix Linux build deps --- .../{release.yml.disabled => release.yml} | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) rename .github/workflows/{release.yml.disabled => release.yml} (84%) diff --git a/.github/workflows/release.yml.disabled b/.github/workflows/release.yml similarity index 84% rename from .github/workflows/release.yml.disabled rename to .github/workflows/release.yml index f03c484e..0b70bbf5 100644 --- a/.github/workflows/release.yml.disabled +++ b/.github/workflows/release.yml @@ -73,13 +73,24 @@ jobs: 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 + echo "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV + - uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} + env: + PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig - uses: Swatinem/rust-cache@v2 with: key: ${{ matrix.target }}-release + 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 @@ -87,12 +98,6 @@ jobs: node-version: 20 cache: 'pnpm' - - name: Install Linux deps - if: matrix.os == 'ubuntu-latest' - run: | - sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libsecret-1-dev - - run: pnpm install --frozen-lockfile # Import Apple certificate for macOS signing @@ -119,6 +124,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig # macOS signing APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} @@ -154,13 +160,24 @@ jobs: 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 + echo "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV + - uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} + env: + PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig - uses: Swatinem/rust-cache@v2 with: key: ${{ matrix.target }}-nightly + 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 @@ -168,16 +185,11 @@ jobs: node-version: 20 cache: 'pnpm' - - name: Install Linux deps - if: matrix.os == 'ubuntu-latest' - run: | - sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libsecret-1-dev - - run: pnpm install --frozen-lockfile - run: pnpm build env: TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig - name: Upload artifacts uses: actions/upload-artifact@v4 From 0d0dd1c0c111cee216a510a05d078bb6513803bd Mon Sep 17 00:00:00 2001 From: Mohammod Al Amin Ashik Date: Mon, 2 Feb 2026 02:42:16 +0800 Subject: [PATCH 2/2] rename ci --- .../actions/check-comment-trigger/action.yml | 86 +++++++++++ .github/actions/install-linux-deps/action.yml | 33 +++++ .github/workflows/ci.yml | 136 ++++-------------- .github/workflows/e2e-desktop-comment.yml | 58 ++++++++ .github/workflows/e2e-desktop.yml | 84 +++++++++++ .github/workflows/e2e-tauri-comment.yml | 104 -------------- .github/workflows/release.yml | 14 +- README.md | 3 + apps/desktop/src-tauri/tauri.conf.json | 4 +- tests/e2e/README.md | 3 +- tests/e2e/wdio.conf.ts | 6 + 11 files changed, 311 insertions(+), 220 deletions(-) create mode 100644 .github/actions/check-comment-trigger/action.yml create mode 100644 .github/actions/install-linux-deps/action.yml create mode 100644 .github/workflows/e2e-desktop-comment.yml create mode 100644 .github/workflows/e2e-desktop.yml delete mode 100644 .github/workflows/e2e-tauri-comment.yml diff --git a/.github/actions/check-comment-trigger/action.yml b/.github/actions/check-comment-trigger/action.yml new file mode 100644 index 00000000..f44259d2 --- /dev/null +++ b/.github/actions/check-comment-trigger/action.yml @@ -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'); diff --git a/.github/actions/install-linux-deps/action.yml b/.github/actions/install-linux-deps/action.yml new file mode 100644 index 00000000..1586248f --- /dev/null +++ b/.github/actions/install-linux-deps/action.yml @@ -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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53a92a69..af69ef4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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' }} @@ -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: @@ -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 @@ -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: @@ -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: @@ -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 diff --git a/.github/workflows/e2e-desktop-comment.yml b/.github/workflows/e2e-desktop-comment.yml new file mode 100644 index 00000000..3c3100de --- /dev/null +++ b/.github/workflows/e2e-desktop-comment.yml @@ -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 diff --git a/.github/workflows/e2e-desktop.yml b/.github/workflows/e2e-desktop.yml new file mode 100644 index 00000000..bc51d1b5 --- /dev/null +++ b/.github/workflows/e2e-desktop.yml @@ -0,0 +1,84 @@ +# Reusable workflow: Desktop E2E tests (Linux + Windows) +# Call with workflow_call from ci.yml or e2e-desktop-comment.yml +name: E2E Desktop + +on: + workflow_call: + inputs: + ref: + description: Git ref to checkout (e.g. PR head SHA or github.sha) + required: true + type: string + secrets: + TAURI_SIGNING_PRIVATE_KEY: + required: false + +env: + PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig + +jobs: + e2e-desktop: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + - os: windows-latest + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + + - name: Install Linux deps + if: matrix.os == 'ubuntu-latest' + uses: ./.github/actions/install-linux-deps + with: + e2e: 'true' + + - uses: dtolnay/rust-toolchain@stable + env: + PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig + + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.os }}-e2e-desktop + 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 + with: + node-version: 20 + cache: 'pnpm' + + - 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 desktop E2E tests (Linux) + if: matrix.os == 'ubuntu-latest' + run: | + dbus-run-session -- bash -c 'gnome-keyring-daemon --unlock < /dev/null; sleep 2; xvfb-run --auto-servernum pnpm test:e2e' + + - name: Run desktop E2E tests (Windows) + if: matrix.os == 'windows-latest' + run: pnpm test:e2e diff --git a/.github/workflows/e2e-tauri-comment.yml b/.github/workflows/e2e-tauri-comment.yml deleted file mode 100644 index 6abf7f6a..00000000 --- a/.github/workflows/e2e-tauri-comment.yml +++ /dev/null @@ -1,104 +0,0 @@ -# Run Tauri E2E tests when someone comments /e2e-tauri on a PR. -# Usage: Add a comment "/e2e-tauri" on any PR to trigger desktop E2E tests. - -name: E2E Tauri (Comment Trigger) - -on: - issue_comment: - types: [created] - -env: - PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig - -jobs: - e2e-tauri: - # Only run when comment on a PR contains /e2e-tauri - if: | - github.event.issue.pull_request != null && - contains(github.event.comment.body, '/e2e-tauri') - strategy: - fail-fast: false - matrix: - include: - - os: ubuntu-latest - - os: windows-latest - - runs-on: ${{ matrix.os }} - permissions: - contents: read - pull-requests: read - steps: - - name: Get PR head ref - id: pr - uses: actions/github-script@v7 - with: - script: | - const pr = await github.rest.pulls.get({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: context.issue.number, - }); - core.setOutput('ref', pr.data.head.ref); - core.setOutput('sha', pr.data.head.sha); - core.setOutput('pr_number', context.issue.number); - - - uses: actions/checkout@v4 - with: - ref: ${{ steps.pr.outputs.sha }} - - - 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: Swatinem/rust-cache@v2 - with: - key: ${{ matrix.os }}-e2e-comment - 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 - with: - node-version: 20 - cache: 'pnpm' - - - 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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0b70bbf5..097afbde 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -75,10 +75,9 @@ 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 "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV + uses: ./.github/actions/install-linux-deps + with: + verify_glib: 'false' - uses: dtolnay/rust-toolchain@stable with: @@ -162,10 +161,9 @@ 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 "PKG_CONFIG_PATH=$(pkg-config --variable pc_path pkg-config)" >> $GITHUB_ENV + uses: ./.github/actions/install-linux-deps + with: + verify_glib: 'false' - uses: dtolnay/rust-toolchain@stable with: diff --git a/README.md b/README.md index 03475d46..074b9532 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,9 @@ - [Node.js](https://nodejs.org/) 18+ - [pnpm](https://pnpm.io/) 9+ +**Linux system dependencies** (for credential storage via Secret Service): +- `gnome-keyring` (or another `org.freedesktop.secrets` implementation like KWallet on KDE) + ### Development ```bash diff --git a/apps/desktop/src-tauri/tauri.conf.json b/apps/desktop/src-tauri/tauri.conf.json index f109f6a6..d5045e84 100644 --- a/apps/desktop/src-tauri/tauri.conf.json +++ b/apps/desktop/src-tauri/tauri.conf.json @@ -82,11 +82,11 @@ "bundleMediaFramework": false }, "deb": { - "depends": [], + "depends": ["libsecret-1-0", "gnome-keyring", "librsvg2-2"], "desktopTemplate": "linux/mcpmux.desktop" }, "rpm": { - "depends": [] + "depends": ["libsecret", "gnome-keyring", "librsvg2"] } } } diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 2ee8f435..09b26e11 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -33,7 +33,8 @@ cargo install tauri-driver --locked # Add msedgedriver.exe to PATH # Linux: -sudo apt-get install webkit2gtk-driver +sudo apt-get install webkit2gtk-driver gnome-keyring +# gnome-keyring provides Secret Service API (org.freedesktop.secrets) for credential storage # macOS: NOT SUPPORTED (no WKWebView driver) ``` diff --git a/tests/e2e/wdio.conf.ts b/tests/e2e/wdio.conf.ts index bdcda64f..2b508326 100644 --- a/tests/e2e/wdio.conf.ts +++ b/tests/e2e/wdio.conf.ts @@ -247,6 +247,12 @@ export const config: Options.Testrunner = { // Verify prerequisites before running onPrepare: async function () { + // Create output directories (gitignored; needed for CI and fresh clones) + const screenshotsDir = path.resolve('./tests/e2e/screenshots'); + const videosDir = path.resolve('./tests/e2e/videos'); + fs.mkdirSync(screenshotsDir, { recursive: true }); + fs.mkdirSync(videosDir, { recursive: true }); + // Verify tauri-driver is installed const hasTauriDriver = checkTauriDriver(); if (!hasTauriDriver) {