前言
我最近编写了一个 MCP 服务器:nailuoGG/anki-mcp-server。
但是有一个问题,用户安装时需要在本地进行构建,流程比较复杂,能否更简单一点呢?
我想到了将其发布到 npm 上,然后使用 `npx anki-mcp-server` 命令来使用。
进一步想,作为一个开源项目,为什么不使用 GitHub Actions 来进行自动化发布呢?而且至少有以下几个好处:
- 安全性,防止开发者本地电脑被侵入导致意外发包的情况,而且能保持让打包构建过程公开透明
- 便利性,便于多人协作,这样发布时就不依赖单个开发者,也能够保持发布的一致性
准备
- 在 Npm 上创建账户,并创建并获取 Access Tokens,记为 NPM_TOKEN。https://www.npmjs.com/
- 在 GitHub 上创建工程仓库 https://github.com/
- 在 GitHub 仓库设置页面添加 secrets
这里详细记录一下如何添加 secrets:
操作路径是:仓库首页 -> settings -> Security -> Secrets and Variables -> Actions
注意此时有 `Environment secrets` 和 `Repository secrets` 这两种 secrets,关于他们的区别:管理部署环境 - GitHub 文档
因为我们只是发布 NPM 包,不涉及多环境部署,因此需要使用 `Repository secrets` 而不是 `Environment secrets`。详细的操作流程请看 Using secrets in GitHub Actions - GitHub Docs
添加工作流
在仓库中添加 `.github/workflow/publish.yaml`,下面放上工程中正在使用的工作流文件,并且实时更新。
anki-mcp-server/.github/workflows/publish.yaml at master · nailuoGG/anki-mcp-server
name: Publish to NPM
on:
workflow_run:
workflows: ["Release Test"]
types:
- completed
jobs:
publish:
runs-on: ubuntu-latest
# Only run if the test workflow succeeded
if: ${{ github.event.workflow_run.conclusion == 'success' }}
permissions:
contents: read
id-token: write # Required for npm provenance
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20.x"
registry-url: "https://registry.npmjs.org"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Publish to NPM
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Upload npm logs
if: always()
uses: actions/upload-artifact@v4
with:
name: npm-logs
path: |
/home/runner/.npm/_logs/*.log
retention-days: 7
解析:
workflow_run:
workflows: ["Release Test"]
types:
- completed
这里配置成了在前一个 Workflow 执行完毕后,再执行发布工作流,这样可以确保每次发布都经过了测试:
anki-mcp-server/.github/workflows/release-test.yaml at master
node-version: "20.x"
registry-url: "https://registry.npmjs.org"
cache: "npm"
这里关键是使用了 node 20 作为发布环境,
npm publish --provenance --access public
如果是这个包的第一次发布,需要加上 `–access public`,来确定包的访问权限范围是公开可见,后续发布就可以不加,默认公开可见。
`–provenance` 是一种安全策略,防止供应链攻击。效果是在 npm 页面上会有一个认证徽章:anki-mcp-server - npm
详情可见:
- https://docs.npmjs.com/generating-provenance-statements
- https://github.blog/security/supply-chain-security/introducing-npm-package-provenance/
发布的整体流程
如果基于 GitHub Actions 来发布到 NPM,一般来说就不建议再在开发者电脑上手动操作发布了。因此整个发布流程如下:
- 本地执行语义化版本升级,并 push 到仓库
- 在 GitHub 仓库页面创建一个发布,并使用`Generate release notes` 功能来生成发布日志
- 点击发布,就会触发我们设定的 `Publish to NPM` 的 Workflow。稍等一会就会正常发布
详细的发布流程,可以看仓库中的介绍:anki-mcp-server/RELEASE.md at master · nailuoGG/anki-mcp-server