Skip to content

Commit 0bbcc26

Browse files
authored
Merge branch 'main' into dependabot/cargo/tar-0.4.45
2 parents 5b29e5d + a215012 commit 0bbcc26

244 files changed

Lines changed: 24382 additions & 9957 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1-
blank_issues_enabled: false
1+
blank_issues_enabled: true
22
contact_links:
33
- name: Questions & Help
44
url: https://github.com/mcpmux/mcp-mux/discussions/categories/q-a
55
about: Ask questions and get help in GitHub Discussions
66
- name: Feature Ideas
77
url: https://github.com/mcpmux/mcp-mux/discussions/categories/ideas
88
about: Share and discuss feature ideas
9+
- name: Contribute a Server Definition (PR)
10+
url: https://github.com/mcpmux/mcp-servers/blob/main/CONTRIBUTING.md
11+
about: Server definitions live in the mcp-servers repo and land via PR — read the guide
12+
- name: Request a Server
13+
url: https://github.com/mcpmux/mcp-servers/issues/new?template=request-server.yml
14+
about: Ask the community to add an MCP server to the registry
15+
- name: Report a Server Definition Bug
16+
url: https://github.com/mcpmux/mcp-servers/issues/new?template=bug-report.yml
17+
about: Found a broken or incorrect server in the registry? Report it here

.github/workflows/build-tauri.yml

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
name: Build Tauri
2+
3+
# Reusable build for the desktop app across all platforms. Shared by the
4+
# stable release flow, the per-merge pre-release flow, and the promote flow so
5+
# every channel is built with identical logic (no drift).
6+
on:
7+
workflow_call:
8+
inputs:
9+
ref:
10+
description: 'Git ref to build (empty = the caller ref)'
11+
type: string
12+
default: ''
13+
set_version:
14+
description: 'If set, stamp this version onto the working tree before building'
15+
type: string
16+
default: ''
17+
release_id:
18+
description: 'Upload artifacts to this existing release id (stable flow)'
19+
type: string
20+
default: ''
21+
tag_name:
22+
description: 'Create/append to a release with this tag (pre-release / promote flow)'
23+
type: string
24+
default: ''
25+
release_name:
26+
description: 'Release title when creating via tag_name'
27+
type: string
28+
default: ''
29+
release_body:
30+
description: 'Release body when creating via tag_name'
31+
type: string
32+
default: ''
33+
prerelease:
34+
description: 'Mark the created release as a pre-release'
35+
type: boolean
36+
default: false
37+
draft:
38+
description: 'Create the release as a draft'
39+
type: boolean
40+
default: false
41+
apple_full_signing:
42+
description: 'Import the Apple Developer cert (true) or ad-hoc sign (false)'
43+
type: boolean
44+
default: true
45+
46+
env:
47+
CARGO_TERM_COLOR: always
48+
49+
jobs:
50+
build:
51+
strategy:
52+
fail-fast: false
53+
matrix:
54+
include:
55+
- os: ubuntu-latest
56+
target: x86_64-unknown-linux-gnu
57+
artifact: linux
58+
- os: windows-latest
59+
target: x86_64-pc-windows-msvc
60+
artifact: windows
61+
- os: macos-latest
62+
target: aarch64-apple-darwin
63+
artifact: macos-arm
64+
- os: macos-15-intel
65+
target: x86_64-apple-darwin
66+
artifact: macos-intel
67+
68+
runs-on: ${{ matrix.os }}
69+
permissions:
70+
contents: write
71+
steps:
72+
- uses: actions/checkout@v4
73+
with:
74+
ref: ${{ inputs.ref }}
75+
76+
# Stamp a pre-release / promote version onto the working tree (transient,
77+
# never committed) so the binary, bundle, and latest.json all agree.
78+
- name: Set build version
79+
if: inputs.set_version != ''
80+
shell: bash
81+
run: node scripts/set-version.mjs "${{ inputs.set_version }}"
82+
83+
- name: Install Linux deps
84+
if: matrix.os == 'ubuntu-latest'
85+
uses: ./.github/actions/install-linux-deps
86+
with:
87+
verify_glib: 'false'
88+
89+
- uses: dtolnay/rust-toolchain@stable
90+
with:
91+
targets: ${{ matrix.target }}
92+
env:
93+
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
94+
95+
- uses: Swatinem/rust-cache@v2
96+
with:
97+
key: ${{ matrix.target }}-release
98+
env:
99+
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
100+
101+
- uses: pnpm/action-setup@v4
102+
- uses: actions/setup-node@v4
103+
with:
104+
node-version: 20
105+
cache: 'pnpm'
106+
107+
- run: pnpm install --frozen-lockfile
108+
109+
# Import Apple certificate ourselves, then DON'T pass APPLE_CERTIFICATE
110+
# to tauri-action. Tauri's bundler uses var_os() which treats empty
111+
# strings as present (Some("")), so we must completely omit the env var.
112+
# Instead we import the cert here and only pass APPLE_SIGNING_IDENTITY.
113+
# When apple_full_signing is false (pre-releases), we ad-hoc sign ("-").
114+
- name: Import Apple certificate
115+
if: runner.os == 'macOS'
116+
id: apple-cert
117+
env:
118+
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
119+
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
120+
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
121+
run: |
122+
if [ "${{ inputs.apple_full_signing }}" != "true" ]; then
123+
echo "Ad-hoc signing requested (pre-release build)"
124+
echo "identity=-" >> "$GITHUB_OUTPUT"
125+
exit 0
126+
fi
127+
if [ -z "$APPLE_CERTIFICATE" ] || [ -z "$KEYCHAIN_PASSWORD" ]; then
128+
echo "No Apple certificate configured — using ad-hoc signing"
129+
echo "identity=-" >> "$GITHUB_OUTPUT"
130+
exit 0
131+
fi
132+
echo "$APPLE_CERTIFICATE" | base64 --decode > certificate.p12
133+
if [ ! -s certificate.p12 ]; then
134+
echo "Certificate decode produced empty file — using ad-hoc signing"
135+
rm -f certificate.p12
136+
echo "identity=-" >> "$GITHUB_OUTPUT"
137+
exit 0
138+
fi
139+
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
140+
security default-keychain -s build.keychain
141+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
142+
if ! security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign; then
143+
echo "Certificate import failed — using ad-hoc signing"
144+
rm -f certificate.p12
145+
echo "identity=-" >> "$GITHUB_OUTPUT"
146+
exit 0
147+
fi
148+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
149+
rm certificate.p12
150+
echo "identity=${{ secrets.APPLE_SIGNING_IDENTITY }}" >> "$GITHUB_OUTPUT"
151+
echo "cert_ok=true" >> "$GITHUB_OUTPUT"
152+
153+
# IMPORTANT: Do NOT pass APPLE_CERTIFICATE, APPLE_ID, APPLE_PASSWORD,
154+
# or APPLE_TEAM_ID to tauri-action. Tauri's bundler uses var_os() which
155+
# treats empty strings as "present" and attempts certificate import /
156+
# notarization even when values are empty, causing build failures.
157+
# We handle cert import ourselves above and only pass APPLE_SIGNING_IDENTITY.
158+
#
159+
# Two variants so each path passes EXACTLY the inputs it needs:
160+
# • release_id set → upload to the pre-created (draft) release by id.
161+
# Pass ONLY releaseId — never tagName/draft/prerelease, which could
162+
# flip the draft early or mismatch its state. (Stable + promote.)
163+
# • release_id empty → create/append to a tagged release. (Pre-release.)
164+
- name: Build Tauri app (upload to existing release)
165+
if: inputs.release_id != ''
166+
uses: tauri-apps/tauri-action@v0
167+
env:
168+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
169+
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
170+
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
171+
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
172+
APPLE_SIGNING_IDENTITY: ${{ runner.os == 'macOS' && steps.apple-cert.outputs.identity || '' }}
173+
VITE_POSTHOG_KEY: ${{ secrets.VITE_POSTHOG_KEY }}
174+
VITE_POSTHOG_HOST: ${{ secrets.VITE_POSTHOG_HOST }}
175+
with:
176+
projectPath: apps/desktop
177+
releaseId: ${{ inputs.release_id }}
178+
updaterJsonKeepUniversal: true
179+
args: --target ${{ matrix.target }}
180+
181+
- name: Build Tauri app (create tagged release)
182+
if: inputs.release_id == ''
183+
uses: tauri-apps/tauri-action@v0
184+
env:
185+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
186+
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
187+
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
188+
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
189+
APPLE_SIGNING_IDENTITY: ${{ runner.os == 'macOS' && steps.apple-cert.outputs.identity || '' }}
190+
VITE_POSTHOG_KEY: ${{ secrets.VITE_POSTHOG_KEY }}
191+
VITE_POSTHOG_HOST: ${{ secrets.VITE_POSTHOG_HOST }}
192+
with:
193+
projectPath: apps/desktop
194+
tagName: ${{ inputs.tag_name }}
195+
releaseName: ${{ inputs.release_name }}
196+
releaseBody: ${{ inputs.release_body }}
197+
releaseDraft: ${{ inputs.draft }}
198+
prerelease: ${{ inputs.prerelease }}
199+
updaterJsonKeepUniversal: true
200+
args: --target ${{ matrix.target }}

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,12 @@ jobs:
387387
if: steps.playwright-cache.outputs.cache-hit != 'true'
388388
run: pnpm exec playwright install --with-deps chromium
389389

390+
# TODO(playwright-migration): the web E2E suite has stale assertions from
391+
# the IA redesign and is being replaced (tauri-playwright spike on
392+
# spike/playwright-e2e). Non-blocking until that lands so it doesn't gate
393+
# PRs on pre-existing failures; results still surface via the report below.
390394
- name: Run web-only E2E tests
395+
continue-on-error: true
391396
run: pnpm test:e2e:web --project=chromium
392397

393398
- name: Upload E2E web test results

.github/workflows/e2e-desktop.yml

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,12 @@ jobs:
112112
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
113113
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
114114

115+
# TODO(playwright-migration): desktop E2E has stale assertions from the IA
116+
# redesign and is being replaced (tauri-playwright spike). Non-blocking
117+
# until then; results still surface via the report job below.
115118
- name: Run desktop E2E tests (Linux)
116119
if: matrix.os == 'ubuntu-latest'
120+
continue-on-error: true
117121
run: |
118122
# Start dbus session and unlock gnome-keyring with a dummy password for CI.
119123
# Two-step process: unlock creates the login keyring, start exports env vars.
@@ -131,16 +135,54 @@ jobs:
131135
if: matrix.os == 'windows-latest'
132136
shell: pwsh
133137
run: |
134-
# Tauri uses the WebView2 runtime, not Edge directly.
135-
# msedgedriver must match the WebView2 runtime version, not the Edge browser version.
138+
# Tauri uses the WebView2 runtime, not Edge directly, so msedgedriver must be
139+
# compatible with the WebView2 runtime (matching the major version is sufficient).
140+
# Microsoft does not publish a driver for every exact runtime build, so try the
141+
# exact version first, then fall back to the latest driver for the same major
142+
# version, then LATEST_STABLE. This keeps the job from breaking whenever the
143+
# runner's WebView2 build outpaces the published Edge drivers.
144+
$ErrorActionPreference = 'Stop'
136145
$wv2Key = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}'
137146
if (-not (Test-Path $wv2Key)) { $wv2Key = 'HKLM:\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' }
138147
$wv2Version = (Get-ItemProperty $wv2Key).pv
139-
Write-Host "WebView2 runtime version: $wv2Version"
140-
$driverUrl = "https://msedgewebdriverstorage.blob.core.windows.net/edgewebdriver/$wv2Version/edgedriver_win64.zip"
148+
$wv2Major = $wv2Version.Split('.')[0]
149+
Write-Host "WebView2 runtime version: $wv2Version (major $wv2Major)"
150+
151+
# Microsoft locked down the old msedgewebdriverstorage blob (now returns HTTP 409
152+
# "Public access is not permitted"); the current host is msedgedriver.microsoft.com.
153+
$base = "https://msedgedriver.microsoft.com"
154+
155+
# Ordered list of candidate driver versions to try.
156+
$candidates = [System.Collections.Generic.List[string]]::new()
157+
$candidates.Add($wv2Version)
158+
foreach ($marker in @("LATEST_RELEASE_${wv2Major}_WINDOWS", "LATEST_STABLE")) {
159+
try {
160+
$resolved = (Invoke-WebRequest -UseBasicParsing -Uri "$base/$marker").Content
161+
# Markers are UTF-16/BOM encoded; keep only version characters.
162+
$resolved = ($resolved -replace '[^0-9\.]', '').Trim()
163+
if ($resolved) { $candidates.Add($resolved); Write-Host "marker $marker -> $resolved" }
164+
} catch {
165+
Write-Host "marker $marker unavailable: $($_.Exception.Message)"
166+
}
167+
}
168+
141169
$zipPath = "$env:TEMP\edgedriver.zip"
142170
$extractDir = "$env:TEMP\edgedriver"
143-
Invoke-WebRequest -Uri $driverUrl -OutFile $zipPath
171+
$ok = $false
172+
foreach ($v in ($candidates | Select-Object -Unique)) {
173+
$driverUrl = "$base/$v/edgedriver_win64.zip"
174+
Write-Host "Trying EdgeDriver $v -> $driverUrl"
175+
try {
176+
Invoke-WebRequest -UseBasicParsing -Uri $driverUrl -OutFile $zipPath
177+
Write-Host "Downloaded EdgeDriver $v"
178+
$ok = $true
179+
break
180+
} catch {
181+
Write-Host " not available: $($_.Exception.Message)"
182+
}
183+
}
184+
if (-not $ok) { throw "No compatible msedgedriver found for WebView2 $wv2Version (tried: $($candidates -join ', '))" }
185+
144186
Expand-Archive -Path $zipPath -DestinationPath $extractDir -Force
145187
$driverDir = "$extractDir\edgedriver_win64"
146188
if (-not (Test-Path "$driverDir\msedgedriver.exe")) { $driverDir = $extractDir }
@@ -149,6 +191,7 @@ jobs:
149191
150192
- name: Run desktop E2E tests (Windows)
151193
if: matrix.os == 'windows-latest'
194+
continue-on-error: true
152195
run: pnpm test:e2e
153196

154197
# Upload test results and artifacts

0 commit comments

Comments
 (0)