GitHub Actions NPM可信发布完整教程:从零配置OIDC到成功部署
NPM可信发布(Trusted Publishing)使用OIDC(OpenID Connect)技术,让GitHub Actions可以直接安全地发布包到NPM,无需管理长期有效的访问令牌。本教程将带你从零开始完成配置。
前置条件
- GitHub账号和仓库
- NPM账号(需要Pro或付费套餐启用可信发布)
- 要发布的Node.js包
- 启用GitHub Actions的权限
第一步:NPM账号配置
1.1 启用双因素认证(2FA)
登录NPM官网 → 点击头像 → Settings → Authentication → 启用2FA
1.2 配置发布来源设置
# 在NPM上配置可信发布
npm profile enable-2fa auth-and-writes
npm profile set-oidc-issuer "https://token.actions.githubusercontent.com"
第二步:GitHub仓库配置
2.1 添加NPM_TOKEN(作为后备方案)
- 访问 https://www.npmjs.com/settings/tokens
- 创建新的Access Token,选择"Automation"类型
- 复制Token值
- 在GitHub仓库:Settings → Secrets and variables → Actions → New repository secret
- 名称:NPM_TOKEN,值:粘贴刚才复制的Token
2.2 配置仓库权限
在仓库Settings → Actions → General页面:
- √ 启用"Read and write permissions"
- √ 允许GitHub Actions创建和批准拉取请求
第三步:创建GitHub Actions工作流
3.1 基础发布工作流
在项目根目录创建:.github/workflows/publish.yml
name: Publish to NPM
on:
push:
tags:
- 'v*' # 监听v开头的tag,如v1.0.0
# 或者使用release触发:
# release:
# types: [published]
jobs:
publish:
name: Publish Package to NPM
runs-on: ubuntu-latest
# 关键:OIDC必需权限
permissions:
id-token: write # 用于OIDC令牌
contents: read # 用于代码访问
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整历史用于版本检测
- name: Setup Node.js with OIDC support
uses: actions/setup-node@v4
with:
node-version: '20.x' # 至少使用Node 20
registry-url: 'https://registry.npmjs.org/'
# 注意:Node 18需要额外升级npm步骤
# 验证Node和npm版本(重要!)
- name: Verify Environment
run: |
echo "Node version: $(node --version)"
echo "npm version: $(npm --version)"
# 确保npm版本支持OIDC
if ! npm --version | grep -q '^[0-9][0-9]'; then
echo "⚠️ npm版本可能过低,正在升级..."
npm install -g npm@latest
fi
- name: Install Dependencies
run: npm ci # 使用clean install确保一致性
- name: Run Tests
run: npm test # 发布前运行测试
- name: Build Package
run: npm run build # 如果有build脚本
- name: Publish to NPM with OIDC
run: npm publish --provenance --access public
env:
# NPM_TOKEN作为后备方案,OIDC失败时使用
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
3.2 支持旧Node版本的完整工作流
name: Publish to NPM with OIDC
on:
push:
tags: ['v*']
jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js (版本兼容方案)
uses: actions/setup-node@v4
with:
# 如果你的项目需要特定Node版本
node-version: '18' # 示例:使用Node 18
registry-url: 'https://registry.npmjs.org/'
cache: 'npm'
# 关键:升级npm以支持OIDC
- name: Upgrade npm for OIDC support
run: |
echo "当前npm版本: $(npm --version)"
# 检查是否支持provenance
if npm config list | grep -q provenance; then
echo "npm已支持provenance"
else
echo "升级npm到最新版本以支持OIDC..."
npm install -g npm@latest
fi
echo "升级后npm版本: $(npm --version)"
- name: Install Dependencies
run: npm ci
# 可选:版本验证
- name: Validate Package
run: |
# 检查package.json
echo "包名: $(node -p "require('./package.json').name")"
echo "版本: $(node -p "require('./package.json').version")"
# 验证是否有发布权限
npm access ls-collaborators $(node -p "require('./package.json').name") || echo "权限检查跳过"
- name: Publish with Provenance
id: publish
run: |
# 获取当前tag版本
CURRENT_TAG=${GITHUB_REF#refs/tags/}
PACKAGE_VERSION=$(node -p "require('./package.json').version")
echo "GitHub Tag: $CURRENT_TAG"
echo "Package Version: $PACKAGE_VERSION"
# 验证版本是否匹配
if [ "$CURRENT_TAG" != "v$PACKAGE_VERSION" ]; then
echo "错误:GitHub tag ($CURRENT_TAG) 与package.json版本 (v$PACKAGE_VERSION) 不匹配"
exit 1
fi
# 执行发布
echo "开始发布到NPM..."
npm publish --provenance --access public
echo "✅ 发布成功!"
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# 发布后操作
- name: Create GitHub Release
if: success()
uses: softprops/action-gh-release@v1
with:
generate_release_notes: true
files: |
README.md
CHANGELOG.md
dist/*.js
第四步:测试配置
4.1 创建测试发布
- 更新
package.json版本号 - 创建并推送git tag:
# 更新版本号
npm version patch # 或 minor, major
# 推送tag到GitHub
git push --follow-tags
4.2 监控发布过程
- 访问GitHub仓库的Actions标签页
- 查看工作流执行日志
- 检查NPM包的版本发布状态
第五步:高级配置选项
5.1 条件发布(只发布特定分支)
on:
push:
branches: [main]
tags: ['v*']
jobs:
publish:
# 只对tag或main分支的发布事件执行
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
5.2 多环境发布(测试/生产)
name: Publish with Environments
on:
push:
tags: ['v*']
jobs:
test-publish:
runs-on: ubuntu-latest
environment: test
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org/'
- name: Test Publish (Dry Run)
run: npm publish --dry-run --provenance
production-publish:
needs: test-publish
runs-on: ubuntu-latest
environment: production
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org/'
- name: Production Publish
run: npm publish --provenance --access public
第六步:故障排除
常见错误及解决方案
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
npm ERR! code ENEEDAUTH |
OIDC认证失败 | 1. 检查permissions包含id-token: write2. 升级Node到25+或npm到10+ |
npm notice Access token expired or revoked |
NPM不支持当前OIDC配置 | 运行npm install -g npm@latest升级npm |
Provenance not enabled |
NPM账号未启用可信发布 | 升级到NPM Pro套餐或启用功能 |
E403 Forbidden |
包名已存在或无发布权限 | 1. 检查包名唯一性 2. 验证NPM账号权限 |
调试技巧
# 在工作流中添加调试步骤
- name: Debug Information
run: |
# 查看环境变量
echo "GITHUB_REF: $GITHUB_REF"
echo "GITHUB_SHA: $GITHUB_SHA"
# 检查npm配置
npm config list
# 测试OIDC令牌
curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://registry.npmjs.org" | jq .
第七步:最佳实践
7.1 安全性最佳实践
- ✅ 始终使用
npm ci而不是npm install - ✅ 在
package.json中固定依赖版本 - ✅ 启用GitHub Actions的工作流权限限制
- ✅ 定期轮换NPM_TOKEN(即使主要使用OIDC)
- ❌ 不要在代码中硬编码任何令牌
- ❌ 避免使用
--always-auth等不安全选项
7.2 性能优化
# 使用缓存加速构建
- name: Cache npm dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-
- name: Cache build outputs
uses: actions/cache@v3
with:
path: dist # 或你的构建输出目录
key: build-${{ github.sha }}
restore-keys: |
build-
总结
通过GitHub Actions和NPM OIDC可信发布,你可以实现:
- 完全自动化的发布流程
- 增强安全性,无需管理长期令牌
- 可验证的发布来源,提高包的可信度
- 版本一致性,确保每次发布都可追溯
记住关键点:
- 确保使用Node 25+或手动升级npm到10+
- 工作流中必须包含
permissions: id-token: write - 使用
--provenance标志启用可信发布 - 始终保留NPM_TOKEN作为后备方案
现在你的NPM包发布流程已经具备了企业级的安全性和可靠性!



最新评论