GitHub Actions 自動化發佈

GitHub Actions 自動化發佈

使用 GitHub Actions 設置自動化的 MCP 服務器發佈流程。

學習目標

完成本教程後,您將擁有:

  • 自動發佈服務器的 GitHub Actions 工作流
  • 對 GitHub OIDC 身份驗證的理解
  • 自動化發佈的最佳實踐知識
  • Node.js、Python 和 Docker 項目的工作示例

前提條件

  • 瞭解一般發佈要求,如包驗證(參見 發佈指南
  • 包含您的 MCP 服務器代碼的 GitHub 倉庫

GitHub Actions 設置

步驟 1:創建工作流文件

創建 .github/workflows/publish-mcp.yml。以下是 NPM 包的示例,但 MCP Registry 發佈步驟對所有包類型都相同:

name: Publish to MCP Registry

on:
  push:
    tags: ["v*"]  # 在版本標籤(如 v1.0.0)上觸發

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # OIDC 身份驗證所需
      contents: read

    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Setup Node.js  # 根據您的語言調整
        uses: actions/setup-node@v5
        with:
          node-version: "lts/*"

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm run test --if-present

      - name: Build package
        run: npm run build --if-present

      - name: Publish to npm
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Install MCP Publisher
        run: |
          curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher

      - name: Login to MCP Registry
        run: ./mcp-publisher login github-oidc

      - name: Publish to MCP Registry
        run: ./mcp-publisher publish

步驟 2:配置密鑰

您無需為使用 GitHub OIDC 發佈到 MCP Registry 配置任何密鑰。

但是,您可能需要為您的包註冊中心添加密鑰。例如,上述工作流需要 NPM_TOKEN(您可以在 設置 → 密鑰和變量 → Actions 中添加)。

步驟 3:標記和發佈

創建版本標籤以觸發工作流:

git tag v1.0.0
git push origin v1.0.0

工作流運行測試、構建您的包、發佈到 npm,併發布到 MCP Registry。

身份驗證方法

GitHub Actions OIDC(推薦)

- name: Login to MCP Registry
  run: mcp-publisher login github-oidc

這是推薦的方法,因為它:

  • 無需存儲密鑰
  • 使用 GitHub 的內置身份驗證
  • 自動訪問您的 GitHub 命名空間

GitHub 個人訪問令牌

- name: Login to MCP Registry
  run: mcp-publisher login github --token ${{ secrets.GITHUB_TOKEN }}
  env:
    GITHUB_TOKEN: ${{ secrets.MCP_GITHUB_TOKEN }}

添加具有倉庫訪問權限的 GitHub PAT 作為 MCP_GITHUB_TOKEN 密鑰。

DNS 身份驗證

對於自定義域名命名空間 (com.yourcompany/*):

- name: Login to MCP Registry
  run: |
    echo "${{ secrets.MCP_PRIVATE_KEY }}" > key.pem
    mcp-publisher login dns --domain yourcompany.com --private-key-file key.pem

將您的 Ed25519 私鑰作為 MCP_PRIVATE_KEY 密鑰添加。

多語言示例

Node.js/NPM 項目

name: Publish NPM MCP Server

on:
  push:
    tags: ["v*"]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v5
      
      - uses: actions/setup-node@v5
        with:
          node-version: "lts/*"
          registry-url: "https://registry.npmjs.org"

      - run: npm ci
      - run: npm test
      - run: npm run build --if-present
      
      - name: Publish to NPM
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Install MCP Publisher
        run: |
          curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_linux_amd64.tar.gz" | tar xz mcp-publisher

      - name: Publish to MCP Registry
        run: |
          ./mcp-publisher login github-oidc
          ./mcp-publisher publish

Python/PyPI 項目

name: Publish Python MCP Server

on:
  push:
    tags: ["v*"]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v5
      
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install build twine

      - name: Build package
        run: python -m build

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          password: ${{ secrets.PYPI_API_TOKEN }}

      - name: Install MCP Publisher
        run: |
          curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_linux_amd64.tar.gz" | tar xz mcp-publisher

      - name: Publish to MCP Registry
        run: |
          ./mcp-publisher login github-oidc
          ./mcp-publisher publish

Docker/OCI 項目

name: Publish Docker MCP Server

on:
  push:
    tags: ["v*"]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v5

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: |
            ${{ steps.meta.outputs.labels }}
            io.modelcontextprotocol.server.name=io.github.${{ github.repository_owner }}/my-server

      - name: Install MCP Publisher
        run: |
          curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_linux_amd64.tar.gz" | tar xz mcp-publisher

      - name: Publish to MCP Registry
        run: |
          ./mcp-publisher login github-oidc
          ./mcp-publisher publish

NuGet/.NET 項目

name: Publish NuGet MCP Server

on:
  push:
    tags: ["v*"]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v5
      
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: "8.0.x"

      - name: Restore dependencies
        run: dotnet restore

      - name: Build
        run: dotnet build --configuration Release --no-restore

      - name: Test
        run: dotnet test --no-restore --verbosity normal

      - name: Pack
        run: dotnet pack --configuration Release --no-build --output ./artifacts

      - name: Publish to NuGet
        run: dotnet nuget push ./artifacts/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json

      - name: Install MCP Publisher
        run: |
          curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_linux_amd64.tar.gz" | tar xz mcp-publisher

      - name: Publish to MCP Registry
        run: |
          ./mcp-publisher login github-oidc
          ./mcp-publisher publish

版本同步技巧

您可以使用以下方法自動保持包版本和 server.json 版本同步:

- name: Update server.json version
  run: |
    VERSION=${GITHUB_REF#refs/tags/v}
    jq --arg v "$VERSION" '.version = $v' server.json > tmp && mv tmp server.json

高級配置

條件發佈

僅在特定條件下發布到 Registry:

- name: Publish to MCP Registry
  if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-')
  run: |
    ./mcp-publisher login github-oidc
    ./mcp-publisher publish

多環境發佈

為不同環境使用不同的配置:

- name: Publish to MCP Registry
  run: |
    ./mcp-publisher login github-oidc
    if [[ "${{ github.ref }}" == *"-alpha"* ]]; then
      ./mcp-publisher publish --file=server-alpha.json
    else
      ./mcp-publisher publish
    fi

失敗通知

添加失敗通知:

- name: Notify on failure
  if: failure()
  uses: actions/github-script@v7
  with:
    script: |
      github.rest.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: '❌ MCP Registry 發佈失敗. 請檢查 Actions 日誌.'
      })

最佳實踐

1. 使用發佈標籤

# 僅在發佈標籤上觸發
on:
  push:
    tags: ["v*"]

2. 驗證後發佈

- name: Validate before publish
  run: |
    ./mcp-publisher publish --dry-run

3. 緩存依賴

- name: Cache dependencies
  uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

4. 矩陣構建

對多個版本進行測試:

strategy:
  matrix:
    node-version: [18, 20, 22]

故障排除

“Authentication failed”(身份驗證失敗)

  • 確保為 OIDC 設置了 id-token: write 權限
  • 檢查密鑰配置

“Package validation failed”(包驗證失敗)

  • 驗證您的包首先成功發佈到您的註冊中心(NPM、PyPI 等)
  • 確保您已完成 發佈教程 中的必要驗證步驟

“Version mismatch”(版本不匹配)

  • 確保 server.json 中的版本與包版本匹配
  • 使用版本同步腳本

“Rate limiting”(速率限制)

  • 避免在短時間內多次發佈
  • 實施適當的重試邏輯

真實示例

查看這些自動化發佈工作流的真實示例:

下一步

自動化優勢: 使用 GitHub Actions 可以確保每個發佈都經過測試、構建和驗證,減少人為錯誤並提高發布質量。