Skip to content

Commit da01d04

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/taskbar-icon-visibility
2 parents 4d0baf9 + 005ab3e commit da01d04

38 files changed

Lines changed: 3390 additions & 317 deletions

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ jobs:
243243
env:
244244
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
245245
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
246+
# Ad-hoc signing (no Apple Developer ID)
247+
APPLE_SIGNING_IDENTITY: '-'
246248

247249
# ─────────────────────────────────────────────────────────────
248250
# Test Results Report (separate checks per test type and OS)

.github/workflows/e2e-desktop.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
- uses: pnpm/action-setup@v4
5555
- uses: actions/setup-node@v4
5656
with:
57-
node-version: 20
57+
node-version: 22
5858
cache: 'pnpm'
5959

6060
# Cache pnpm store for faster installs
@@ -162,6 +162,20 @@ jobs:
162162
pattern: e2e-desktop-results-*
163163
path: test-results
164164

165+
# Remove malformed/empty JUnit XMLs that crash dorny/test-reporter.
166+
# This can happen when tauri-driver crashes mid-spec and the JUnit
167+
# reporter writes incomplete XML (missing testsuites or test names).
168+
- name: Sanitize JUnit XML reports
169+
if: always()
170+
run: |
171+
for f in test-results/e2e-desktop-results-*/reports/*.xml; do
172+
[ -f "$f" ] || continue
173+
if ! grep -q '<testsuites' "$f" 2>/dev/null; then
174+
echo "Removing malformed JUnit XML: $f"
175+
rm "$f"
176+
fi
177+
done
178+
165179
- name: 'Report: E2E Desktop Tests (Linux)'
166180
uses: dorny/test-reporter@v2
167181
if: always()

.github/workflows/nightly.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ jobs:
5959
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
6060
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
6161
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
62+
# Ad-hoc signing for macOS (no Apple Developer ID)
63+
APPLE_SIGNING_IDENTITY: ${{ matrix.os == 'macos-latest' && '-' || '' }}
6264

6365
- name: Upload artifacts
6466
uses: actions/upload-artifact@v4

.github/workflows/release.yml

Lines changed: 127 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
- os: macos-latest
5454
target: aarch64-apple-darwin
5555
artifact: macos-arm
56-
- os: macos-15
56+
- os: macos-13
5757
target: x86_64-apple-darwin
5858
artifact: macos-intel
5959

@@ -89,22 +89,39 @@ jobs:
8989

9090
- run: pnpm install --frozen-lockfile
9191

92-
# Import Apple certificate for macOS signing
92+
# Import Apple certificate for macOS signing (only when Developer ID is available)
9393
- name: Import Apple certificate
9494
if: matrix.os == 'macos-latest' || matrix.os == 'macos-15'
9595
env:
9696
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
9797
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
9898
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
9999
run: |
100-
if [ -n "$APPLE_CERTIFICATE" ]; then
101-
echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
102-
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
103-
security default-keychain -s build.keychain
104-
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
105-
security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
106-
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
107-
rm certificate.p12
100+
if [ -z "$APPLE_CERTIFICATE" ] || [ -z "$KEYCHAIN_PASSWORD" ]; then
101+
echo "No Apple certificate configured — skipping import"
102+
exit 0
103+
fi
104+
echo "$APPLE_CERTIFICATE" | base64 --decode > certificate.p12
105+
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
106+
security default-keychain -s build.keychain
107+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
108+
security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
109+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
110+
rm certificate.p12
111+
112+
# Determine macOS signing identity: Developer ID if available, ad-hoc (-) otherwise
113+
- name: Resolve macOS signing identity
114+
if: matrix.os == 'macos-latest' || matrix.os == 'macos-15'
115+
id: macos-signing
116+
env:
117+
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
118+
run: |
119+
if [ -n "$APPLE_SIGNING_IDENTITY" ]; then
120+
echo "identity=$APPLE_SIGNING_IDENTITY" >> "$GITHUB_OUTPUT"
121+
echo "Using Developer ID signing"
122+
else
123+
echo "identity=-" >> "$GITHUB_OUTPUT"
124+
echo "Using ad-hoc signing (no Apple Developer ID)"
108125
fi
109126
110127
- name: Build Tauri app
@@ -114,11 +131,11 @@ jobs:
114131
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
115132
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
116133
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
117-
# macOS signing
118-
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
134+
# macOS signing — falls back to ad-hoc (-) when no Apple Developer cert
135+
APPLE_SIGNING_IDENTITY: ${{ steps.macos-signing.outputs.identity }}
119136
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
120137
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
121-
# macOS notarization
138+
# macOS notarization (only works with Developer ID)
122139
APPLE_ID: ${{ secrets.APPLE_ID }}
123140
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
124141
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
@@ -131,3 +148,100 @@ jobs:
131148
releaseDraft: false
132149
prerelease: false
133150
updaterJsonKeepUniversal: true
151+
152+
# ─────────────────────────────────────────────────────────────
153+
# Update Homebrew Tap: Push new version to homebrew-mcpmux
154+
# ─────────────────────────────────────────────────────────────
155+
update-homebrew:
156+
needs: [release-please, build-release]
157+
if: needs.release-please.outputs.release_created == 'true'
158+
runs-on: ubuntu-latest
159+
permissions:
160+
contents: read
161+
steps:
162+
- name: Wait for release assets
163+
env:
164+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
165+
run: |
166+
VERSION="${{ needs.release-please.outputs.version }}"
167+
TAG="${{ needs.release-please.outputs.tag_name }}"
168+
echo "Checking release assets for $TAG..."
169+
170+
# Wait up to 5 minutes for macOS DMGs to appear
171+
for i in $(seq 1 30); do
172+
ASSETS=$(gh api repos/${{ github.repository }}/releases/tags/$TAG --jq '.assets[].name' 2>/dev/null || echo "")
173+
if echo "$ASSETS" | grep -q "aarch64.dmg" && echo "$ASSETS" | grep -q "x64.dmg"; then
174+
echo "Both macOS DMGs found"
175+
break
176+
fi
177+
echo "Waiting for macOS DMGs... (attempt $i/30)"
178+
sleep 10
179+
done
180+
181+
- name: Compute SHA256 and update cask
182+
env:
183+
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
184+
run: |
185+
VERSION="${{ needs.release-please.outputs.version }}"
186+
BASE_URL="https://github.com/${{ github.repository }}/releases/download/v${VERSION}"
187+
188+
# Download DMGs and compute SHA256
189+
echo "Downloading macOS DMGs..."
190+
curl -fSL "${BASE_URL}/McpMux_${VERSION}_aarch64.dmg" -o arm64.dmg || { echo "ARM64 DMG not found — skipping Homebrew update"; exit 0; }
191+
curl -fSL "${BASE_URL}/McpMux_${VERSION}_x64.dmg" -o x64.dmg || { echo "x64 DMG not found — skipping Homebrew update"; exit 0; }
192+
193+
SHA_ARM64=$(shasum -a 256 arm64.dmg | cut -d' ' -f1)
194+
SHA_X64=$(shasum -a 256 x64.dmg | cut -d' ' -f1)
195+
echo "ARM64 SHA256: $SHA_ARM64"
196+
echo "x64 SHA256: $SHA_X64"
197+
198+
# Clone the tap repo and update the cask
199+
git clone https://x-access-token:${GH_TOKEN}@github.com/ion-ash/homebrew-mcpmux.git tap
200+
201+
# Generate cask file (Ruby heredoc content with shell variable expansion)
202+
CASK_FILE="tap/Casks/mcpmux.rb"
203+
{
204+
echo 'cask "mcpmux" do'
205+
echo ' arch arm: "aarch64", intel: "x64"'
206+
echo ''
207+
echo " version \"${VERSION}\""
208+
echo " sha256 arm: \"${SHA_ARM64}\","
209+
echo " intel: \"${SHA_X64}\""
210+
echo ''
211+
echo ' url "https://github.com/ion-ash/mcp-mux/releases/download/v#{version}/McpMux_#{version}_#{arch}.dmg",'
212+
echo ' verified: "github.com/ion-ash/mcp-mux/"'
213+
echo ''
214+
echo ' name "McpMux"'
215+
echo ' desc "Unified MCP gateway and manager for AI clients"'
216+
echo ' homepage "https://mcpmux.com"'
217+
echo ''
218+
echo ' depends_on macos: ">= :high_sierra"'
219+
echo ''
220+
echo ' livecheck do'
221+
echo ' url "https://github.com/ion-ash/mcp-mux/releases/latest"'
222+
echo ' strategy :github_latest'
223+
echo ' end'
224+
echo ''
225+
echo ' app "McpMux.app"'
226+
echo ''
227+
echo ' # Remove quarantine for ad-hoc signed app (no Apple Developer ID)'
228+
echo ' postflight do'
229+
echo ' system_command "/usr/bin/xattr",'
230+
echo ' args: ["-cr", "#{appdir}/McpMux.app"]'
231+
echo ' end'
232+
echo ''
233+
echo ' zap trash: ['
234+
echo ' "~/Library/Application Support/com.mcpmux.desktop",'
235+
echo ' "~/Library/Preferences/com.mcpmux.desktop.plist",'
236+
echo ' "~/Library/Caches/com.mcpmux.desktop",'
237+
echo ' "~/Library/Saved Application State/com.mcpmux.desktop.savedState",'
238+
echo ' ]'
239+
echo 'end'
240+
} > "$CASK_FILE"
241+
242+
cd tap
243+
git config user.name "github-actions[bot]"
244+
git config user.email "github-actions[bot]@users.noreply.github.com"
245+
git add Casks/mcpmux.rb
246+
git commit -m "Update mcpmux to ${VERSION}"
247+
git push

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.0.11"
2+
".": "0.0.12"
33
}

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## [0.0.12](https://github.com/ion-ash/mcp-mux/compare/v0.0.11...v0.0.12) (2026-02-14)
4+
5+
6+
### Features
7+
8+
* Capture and stream process stderr to server log manager ([#63](https://github.com/ion-ash/mcp-mux/issues/63)) ([96795b0](https://github.com/ion-ash/mcp-mux/commit/96795b0b54ecfaa9743bb9e6045bfc86ddadcc2f))
9+
* Streamable HTTP transport with SSE notifications and E2E tests ([#61](https://github.com/ion-ash/mcp-mux/issues/61)) ([ca5b0ff](https://github.com/ion-ash/mcp-mux/commit/ca5b0ffab19aa395a75c5f10a18ab0e6efb1752a))
10+
* support default values for input definitions ([#70](https://github.com/ion-ash/mcp-mux/issues/70)) ([a1d9599](https://github.com/ion-ash/mcp-mux/commit/a1d9599601c212c1b7054fc4c5c76f065e0ea920))
11+
* update logo with bolder strokes and regenerate icons/screenshots ([#71](https://github.com/ion-ash/mcp-mux/issues/71)) ([68c292c](https://github.com/ion-ash/mcp-mux/commit/68c292c424671edf4a914484a7af570770fac71e))
12+
313
## [0.0.11](https://github.com/ion-ash/mcp-mux/compare/v0.0.10...v0.0.11) (2026-02-12)
414

515

0 commit comments

Comments
 (0)