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”(速率限制)

  • 避免在短时间内多次发布
  • 实施适当的重试逻辑

真实示例

查看这些自动化发布工作流的真实示例:

下一步

了解手动发布流程 掌握 mcp-publisher 命令 了解版本控制最佳实践 理解命名空间和安全性
自动化优势: 使用 GitHub Actions 可以确保每个发布都经过测试、构建和验证,减少人为错误并提高发布质量。