From d48796d4129898009d0d05230dcc2a24d54eb6bb Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 05:31:52 -0700 Subject: [PATCH 01/10] Refactor CI workflow with separate jobs for macOS, Ubuntu, and Alpine --- .github/workflows/ci.yml | 76 ++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1942e300..fff04998 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,31 +11,77 @@ permissions: pull-requests: write jobs: - test: - timeout-minutes: 5 + setup: + runs-on: ubuntu-latest + outputs: + swift-versions: ${{ steps.set-matrix.outputs.swift-versions }} + env: + # Define Swift versions - add new versions here + SWIFT_VERSIONS: | + 6.0.3 + 6.1.0 + steps: + - id: set-matrix + run: | + # Convert multi-line string to JSON array (jq is pre-installed on GitHub runners) + VERSIONS=$(echo "$SWIFT_VERSIONS" | jq -R -s -c 'split("\n") | map(select(length > 0))') + echo "swift-versions=$VERSIONS" >> $GITHUB_OUTPUT + + test-macos: + needs: setup strategy: matrix: - os: [macos-latest, ubuntu-latest] - swift-version: - - 6.0.3 - - 6.1.0 + swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} + runs-on: macos-latest + timeout-minutes: 5 + name: Test (macOS, Swift ${{ matrix.swift-version }}) + steps: + - uses: actions/checkout@v4 - runs-on: ${{ matrix.os }} - name: Test (${{ matrix.os }}, Swift ${{ matrix.swift-version }}) + - name: Setup Swift + uses: swift-actions/setup-swift@v2 + with: + swift-version: ${{ matrix.swift-version }} + - name: Build + run: swift build -v + + - name: Run tests + run: swift test -v + + test-ubuntu: + needs: setup + strategy: + matrix: + swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} + runs-on: ubuntu-latest + timeout-minutes: 5 + name: Test (Ubuntu, Swift ${{ matrix.swift-version }}) steps: - uses: actions/checkout@v4 - - name: Setup Swift on Linux - if: matrix.os == 'ubuntu-latest' + - name: Setup Swift uses: vapor/swiftly-action@v0.2 with: toolchain: ${{ matrix.swift-version }} - - name: Setup Swift on macOS - if: matrix.os == 'macos-latest' - uses: swift-actions/setup-swift@v2 - with: - swift-version: ${{ matrix.swift-version }} + + - name: Build + run: swift build -v + + - name: Run tests + run: swift test -v + + test-alpine: + needs: setup + strategy: + matrix: + swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} + runs-on: ubuntu-latest + timeout-minutes: 5 + container: swift:${{ matrix.swift-version }}-alpine + name: Test (Alpine, Swift ${{ matrix.swift-version }}) + steps: + - uses: actions/checkout@v4 - name: Build run: swift build -v From ad054261b6d56a103e9fd47308a7500f7d6909ec Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 05:35:53 -0700 Subject: [PATCH 02/10] Add support for platforms with Musl Replace os checks with canImport --- Sources/MCP/Base/Transports/StdioTransport.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sources/MCP/Base/Transports/StdioTransport.swift b/Sources/MCP/Base/Transports/StdioTransport.swift index cd9f1ae1..055e523a 100644 --- a/Sources/MCP/Base/Transports/StdioTransport.swift +++ b/Sources/MCP/Base/Transports/StdioTransport.swift @@ -13,9 +13,11 @@ import struct Foundation.Data import Darwin.POSIX #elseif canImport(Glibc) import Glibc +#elseif canImport(Musl) + import Musl #endif -#if canImport(Darwin) || canImport(Glibc) +#if canImport(Darwin) || canImport(Glibc) || canImport(Musl) /// An implementation of the MCP stdio transport protocol. /// /// This transport implements the [stdio transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#stdio) @@ -100,6 +102,8 @@ import struct Foundation.Data Task { await readLoop() } + + messageContinuation.finish() } /// Configures a file descriptor for non-blocking I/O From bce265855190748c7ae69bdfee53429668ac1470 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 05:39:22 -0700 Subject: [PATCH 03/10] Use alpine:latest --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fff04998..bc0d10ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,11 +78,16 @@ jobs: swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} runs-on: ubuntu-latest timeout-minutes: 5 - container: swift:${{ matrix.swift-version }}-alpine + container: alpine:latest name: Test (Alpine, Swift ${{ matrix.swift-version }}) steps: - uses: actions/checkout@v4 + - name: Setup Swift + uses: vapor/swiftly-action@v0.2 + with: + toolchain: ${{ matrix.swift-version }} + - name: Build run: swift build -v From 07cebc4d9f1359aceefe0582a85d307092ac4759 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 05:42:46 -0700 Subject: [PATCH 04/10] Add step to install system dependencies on Alpine Linux --- .github/workflows/ci.yml | 3 +++ README.md | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc0d10ca..3182d27d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,6 +83,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install system dependencies + run: apk add --no-cache bash curl jq gnupg + - name: Setup Swift uses: vapor/swiftly-action@v0.2 with: diff --git a/README.md b/README.md index 6c582b82..56bbf921 100644 --- a/README.md +++ b/README.md @@ -833,15 +833,13 @@ The Swift SDK has the following platform requirements: | watchOS | 9.0+ | | tvOS | 16.0+ | | visionOS | 1.0+ | -| Linux | Distributions with `glibc` | +| Linux | Distributions with `glibc` or `musl` | While the core library works on any platform supporting Swift 6 (including Linux and Windows), running a client or server requires a compatible transport. -We're actively working to expand platform support: -- [Alpine Linux support](https://github.com/modelcontextprotocol/swift-sdk/pull/64) -- [Windows support](https://github.com/modelcontextprotocol/swift-sdk/pull/64) +We're actively working to add [Windows support](https://github.com/modelcontextprotocol/swift-sdk/pull/64). ## Debugging and Logging From 47fc3a28ac9fe589441bd59ea0e7854d15b8e651 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 05:50:42 -0700 Subject: [PATCH 05/10] Update CI workflow --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3182d27d..5ff4103b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,6 @@ jobs: outputs: swift-versions: ${{ steps.set-matrix.outputs.swift-versions }} env: - # Define Swift versions - add new versions here SWIFT_VERSIONS: | 6.0.3 6.1.0 From 543a4762daa8b234e07a7e87b8d21960b690e2e2 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 05:51:45 -0700 Subject: [PATCH 06/10] Add name to setup step --- .github/workflows/ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ff4103b..ce062351 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,7 @@ permissions: jobs: setup: + name: Setup runs-on: ubuntu-latest outputs: swift-versions: ${{ steps.set-matrix.outputs.swift-versions }} @@ -27,13 +28,13 @@ jobs: echo "swift-versions=$VERSIONS" >> $GITHUB_OUTPUT test-macos: + name: Test (macOS, Swift ${{ matrix.swift-version }}) needs: setup strategy: matrix: swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} runs-on: macos-latest timeout-minutes: 5 - name: Test (macOS, Swift ${{ matrix.swift-version }}) steps: - uses: actions/checkout@v4 @@ -49,13 +50,13 @@ jobs: run: swift test -v test-ubuntu: + name: Test (Ubuntu, Swift ${{ matrix.swift-version }}) needs: setup strategy: matrix: swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} runs-on: ubuntu-latest timeout-minutes: 5 - name: Test (Ubuntu, Swift ${{ matrix.swift-version }}) steps: - uses: actions/checkout@v4 @@ -71,6 +72,7 @@ jobs: run: swift test -v test-alpine: + name: Test (Alpine, Swift ${{ matrix.swift-version }}) needs: setup strategy: matrix: @@ -78,7 +80,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 container: alpine:latest - name: Test (Alpine, Swift ${{ matrix.swift-version }}) steps: - uses: actions/checkout@v4 From 0752109889e3f1b8d208546cf2b186c9bf2797f2 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 05:58:52 -0700 Subject: [PATCH 07/10] Add step to build for Alpine Linux using Static Linux SDK --- .github/workflows/ci.yml | 53 ++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce062351..57c571ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,28 +71,61 @@ jobs: - name: Run tests run: swift test -v - test-alpine: - name: Test (Alpine, Swift ${{ matrix.swift-version }}) + build-for-alpine: + name: Build for Alpine (Ubuntu, Swift ${{ matrix.swift-version }}) needs: setup strategy: matrix: swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} runs-on: ubuntu-latest - timeout-minutes: 5 - container: alpine:latest steps: - uses: actions/checkout@v4 - - name: Install system dependencies - run: apk add --no-cache bash curl jq gnupg - - name: Setup Swift uses: vapor/swiftly-action@v0.2 with: toolchain: ${{ matrix.swift-version }} - - name: Build - run: swift build -v + - name: Install Static Linux SDK + run: | + # Install the static Linux SDK for musl target + swift sdk install --swift-version $SWIFT_VERSION static-linux - - name: Run tests + # Verify installation + swift sdk list + + - name: Build for x86_64-musl + run: swift build --swift-sdk x86_64-swift-linux-musl -v + + - name: Run tests (host) run: swift test -v + + - name: Upload build artifacts + uses: actions/upload-artifact@v3 + with: + name: alpine-binaries-${{ matrix.swift-version }} + path: .build/x86_64-swift-linux-musl/debug + + test-alpine: + name: Test (Alpine, Swift ${{ matrix.swift-version }}) + needs: [setup, build-for-alpine] + strategy: + matrix: + swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} + runs-on: ubuntu-latest + timeout-minutes: 5 + container: alpine:latest + steps: + - uses: actions/checkout@v4 + + - name: Download compiled binaries + uses: actions/download-artifact@v3 + with: + name: alpine-binaries-${{ matrix.swift-version }} + path: .build/debug + + - name: Set permissions + run: chmod +x .build/debug/* + + - name: Run tests + run: .build/debug/MCPTests From 1fabf88ccab2188bd369604e06b2681b990ff18a Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 06:00:34 -0700 Subject: [PATCH 08/10] Use actions/upload-artifact@v4 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57c571ca..7f9c312a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -101,7 +101,7 @@ jobs: run: swift test -v - name: Upload build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: alpine-binaries-${{ matrix.swift-version }} path: .build/x86_64-swift-linux-musl/debug @@ -119,7 +119,7 @@ jobs: - uses: actions/checkout@v4 - name: Download compiled binaries - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: alpine-binaries-${{ matrix.swift-version }} path: .build/debug From 5c9911245f5a956c9eec29b7fe55c573e1ed2798 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 06:07:07 -0700 Subject: [PATCH 09/10] Build and test with static Linux SDK for latest Swift 6.1 --- .github/workflows/ci.yml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f9c312a..7fe56248 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,11 +72,8 @@ jobs: run: swift test -v build-for-alpine: - name: Build for Alpine (Ubuntu, Swift ${{ matrix.swift-version }}) + name: Build for Alpine (Ubuntu, Swift 6.1) needs: setup - strategy: - matrix: - swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -84,12 +81,13 @@ jobs: - name: Setup Swift uses: vapor/swiftly-action@v0.2 with: - toolchain: ${{ matrix.swift-version }} + toolchain: 6.1.0 - name: Install Static Linux SDK run: | # Install the static Linux SDK for musl target - swift sdk install --swift-version $SWIFT_VERSION static-linux + # https://www.swift.org/install/linux/debian/12/#versions + swift sdk install https://download.swift.org/swift-6.1-release/static-sdk/swift-6.1-RELEASE/swift-6.1-RELEASE_static-linux-0.0.1.artifactbundle.tar.gz --checksum 111c6f7d280a651208b8c74c0521dd99365d785c1976a6e23162f55f65379ac6 # Verify installation swift sdk list @@ -103,15 +101,12 @@ jobs: - name: Upload build artifacts uses: actions/upload-artifact@v4 with: - name: alpine-binaries-${{ matrix.swift-version }} + name: alpine-binaries-6.1.0 path: .build/x86_64-swift-linux-musl/debug test-alpine: - name: Test (Alpine, Swift ${{ matrix.swift-version }}) + name: Test (Alpine, Swift 6.1) needs: [setup, build-for-alpine] - strategy: - matrix: - swift-version: ${{ fromJson(needs.setup.outputs.swift-versions) }} runs-on: ubuntu-latest timeout-minutes: 5 container: alpine:latest @@ -121,7 +116,7 @@ jobs: - name: Download compiled binaries uses: actions/download-artifact@v4 with: - name: alpine-binaries-${{ matrix.swift-version }} + name: alpine-binaries-6.1.0 path: .build/debug - name: Set permissions From 2df70f8f43070bebc86f7c0b3bed0b56f4f5ba21 Mon Sep 17 00:00:00 2001 From: Mattt Zmuda Date: Thu, 10 Apr 2025 06:13:18 -0700 Subject: [PATCH 10/10] Find test executable in Alpine build --- .github/workflows/ci.yml | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fe56248..ba76a1db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,10 +93,12 @@ jobs: swift sdk list - name: Build for x86_64-musl - run: swift build --swift-sdk x86_64-swift-linux-musl -v - - - name: Run tests (host) - run: swift test -v + run: | + swift build --swift-sdk x86_64-swift-linux-musl -v + swift test --swift-sdk x86_64-swift-linux-musl -v + # List contents to verify test binary location + find .build/x86_64-swift-linux-musl -name "*Test*" -type f | sort + ls -la .build/x86_64-swift-linux-musl/debug - name: Upload build artifacts uses: actions/upload-artifact@v4 @@ -113,6 +115,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install system dependencies + run: apk add --no-cache bash + - name: Download compiled binaries uses: actions/download-artifact@v4 with: @@ -120,7 +125,22 @@ jobs: path: .build/debug - name: Set permissions - run: chmod +x .build/debug/* + shell: bash + run: | + chmod +x .build/debug/* + ls -la .build/debug - name: Run tests - run: .build/debug/MCPTests + shell: bash + run: | + # Try to find and run the test executable + TEST_EXEC=$(find .build/debug -name "*Test*" -type f | head -1) + if [ -n "$TEST_EXEC" ]; then + echo "Running test executable: $TEST_EXEC" + chmod +x "$TEST_EXEC" + $TEST_EXEC + else + echo "Test executable not found!" + ls -la .build/debug + exit 1 + fi