Skip to content

Publish to npm

Publish to npm #9

Workflow file for this run

name: Publish to npm
on:
# 任意分支 push 时发布测试包(依赖 CI 测试通过)
push:
branches:
- '**'
# GitHub Release 触发正式发布
release:
types: [published]
# 手动触发
workflow_dispatch:
inputs:
publish_type:
description: '发布类型 / Publish type'
required: true
default: 'test'
type: choice
options:
- official # 正式发布
- test # 测试发布
version:
description: '版本号(留空则自动递增)/ Version (leave empty for auto-increment)'
required: false
type: string
version_bump:
description: '版本递增类型(仅自动递增时有效)/ Version bump type (only for auto-increment)'
required: false
default: 'patch'
type: choice
options:
- patch # 0.0.1 -> 0.0.2
- minor # 0.0.1 -> 0.1.0
- major # 0.0.1 -> 1.0.0
jobs:
# 等待 CI 测试通过(仅 push 触发时)
wait-for-ci:
name: Wait for CI
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- name: Wait for CI workflow (Node 18.x)
uses: lewagon/[email protected]
with:
ref: ${{ github.sha }}
check-name: 'build (18.x)'
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
allowed-conclusions: success
- name: Wait for CI workflow (Node 20.x)
uses: lewagon/[email protected]
with:
ref: ${{ github.sha }}
check-name: 'build (20.x)'
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
allowed-conclusions: success
- name: Wait for CI workflow (Node 22.x)
uses: lewagon/[email protected]
with:
ref: ${{ github.sha }}
check-name: 'build (22.x)'
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
allowed-conclusions: success
# 测试包发布(push 触发)
publish-test:
name: Publish Test Package
runs-on: ubuntu-latest
needs: wait-for-ci
if: github.event_name == 'push'
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: Upgrade npm for Trusted Publishers
run: |
npm --version
npm install -g npm@latest
npm --version
- name: Determine test version
id: version
run: |
# 获取包名
PACKAGE_NAME=$(node -p "require('./package.json').name")
echo "PACKAGE_NAME=${PACKAGE_NAME}" >> $GITHUB_OUTPUT
# 获取基础版本号
BASE_VERSION=$(node -p "require('./package.json').version")
# 生成唯一标识符:优先使用 run_id,否则使用时间戳
if [ -n "${{ github.run_id }}" ]; then
UNIQUE_ID="${{ github.run_id }}"
else
UNIQUE_ID=$(date +%Y%m%d%H%M%S)
fi
# 生成 prerelease 版本号
VERSION="${BASE_VERSION}-test.${UNIQUE_ID}"
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
echo "Test version: ${VERSION}"
- name: Update package.json version
run: |
VERSION="${{ steps.version.outputs.VERSION }}"
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.version = process.env.VERSION;
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
echo "Updated package.json:"
cat package.json | head -5
env:
VERSION: ${{ steps.version.outputs.VERSION }}
- name: Clean and install dependencies
run: |
rm -rf node_modules package-lock.json
npm install
- name: Build
run: npm run build
- name: Publish test package (Trusted Publishers - no token needed)
run: |
PACKAGE_NAME="${{ steps.version.outputs.PACKAGE_NAME }}"
VERSION="${{ steps.version.outputs.VERSION }}"
echo "Publishing ${PACKAGE_NAME}@${VERSION} with tag=test"
# Remove any .npmrc that might interfere with OIDC
rm -f ~/.npmrc
rm -f .npmrc
rm -f /home/runner/work/_temp/.npmrc
# Publish using Trusted Publishers (OIDC)
npm publish --tag test --access public --provenance
env:
# Clear the environment variables that might interfere with OIDC
NPM_CONFIG_USERCONFIG: ''
NODE_AUTH_TOKEN: ''
- name: Summary
run: |
PACKAGE_NAME="${{ steps.version.outputs.PACKAGE_NAME }}"
VERSION="${{ steps.version.outputs.VERSION }}"
echo "## 🧪 Test Package Published!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Package:** ${PACKAGE_NAME}@${VERSION}" >> $GITHUB_STEP_SUMMARY
echo "- **Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Install with:" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "npm install ${PACKAGE_NAME}@${VERSION}" >> $GITHUB_STEP_SUMMARY
echo "# or install latest test version" >> $GITHUB_STEP_SUMMARY
echo "npm install ${PACKAGE_NAME}@test" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
# 正式发布(release 或手动触发)
publish-official:
name: Publish Official Package
runs-on: ubuntu-latest
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_type == 'official')
permissions:
contents: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.DEPLOY_KEY }}
ref: main
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: Upgrade npm for Trusted Publishers
run: |
npm --version
npm install -g npm@latest
npm --version
- name: Determine version
id: config
run: |
PACKAGE_NAME=$(node -p "require('./package.json').name")
echo "PACKAGE_NAME=${PACKAGE_NAME}" >> $GITHUB_OUTPUT
# 确定版本号
if [ "${{ github.event_name }}" = "release" ]; then
VERSION="${{ github.event.release.tag_name }}"
VERSION="${VERSION#v}" # 移除 v 前缀
echo "Triggered by release: $VERSION"
else
VERSION="${{ inputs.version }}"
if [ -z "$VERSION" ]; then
# 自动递增版本号
NPM_RESPONSE=$(npm view "$PACKAGE_NAME" version 2>/dev/null || echo "")
if [ -z "$NPM_RESPONSE" ]; then
CURRENT_VERSION="0.0.0"
else
CURRENT_VERSION="$NPM_RESPONSE"
fi
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
BUMP_TYPE="${{ inputs.version_bump }}"
if [ -z "$BUMP_TYPE" ]; then
BUMP_TYPE="patch"
fi
case "$BUMP_TYPE" in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
esac
VERSION="${MAJOR}.${MINOR}.${PATCH}"
fi
fi
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
echo "Official version: ${VERSION}"
- name: Update package.json
run: |
VERSION="${{ steps.config.outputs.VERSION }}"
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.version = process.env.VERSION;
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
echo "Updated package.json:"
cat package.json | head -5
env:
VERSION: ${{ steps.config.outputs.VERSION }}
- name: Commit version changes
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git add package.json
if git diff --staged --quiet; then
echo "No version changes to commit"
else
git commit -m "chore: bump version to ${{ steps.config.outputs.VERSION }}"
git push
fi
- name: Clean and install dependencies
run: |
rm -rf node_modules package-lock.json
npm install
- name: Build
run: npm run build
- name: Publish to npm (Trusted Publishers - no token needed)
run: |
PACKAGE_NAME="${{ steps.config.outputs.PACKAGE_NAME }}"
VERSION="${{ steps.config.outputs.VERSION }}"
echo "Publishing ${PACKAGE_NAME}@${VERSION} with tag=latest"
# Remove any .npmrc that might interfere with OIDC
rm -f ~/.npmrc
rm -f .npmrc
rm -f /home/runner/work/_temp/.npmrc
# Publish using Trusted Publishers (OIDC)
npm publish --tag latest --access public --provenance
env:
# Clear the environment variables that might interfere with OIDC
NPM_CONFIG_USERCONFIG: ''
NODE_AUTH_TOKEN: ''
- name: Summary
run: |
PACKAGE_NAME="${{ steps.config.outputs.PACKAGE_NAME }}"
VERSION="${{ steps.config.outputs.VERSION }}"
echo "## 🚀 Official Package Released!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Package Name:** ${PACKAGE_NAME}" >> $GITHUB_STEP_SUMMARY
echo "- **Version:** ${VERSION}" >> $GITHUB_STEP_SUMMARY
echo "- **NPM Tag:** latest" >> $GITHUB_STEP_SUMMARY
echo "- **Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Install with:" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "npm install ${PACKAGE_NAME}@${VERSION}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
# 手动触发测试发布
publish-test-manual:
name: Publish Test Package (Manual)
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && inputs.publish_type == 'test'
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: Upgrade npm for Trusted Publishers
run: |
npm --version
npm install -g npm@latest
npm --version
- name: Determine version
id: version
run: |
PACKAGE_NAME=$(node -p "require('./package.json').name")
echo "PACKAGE_NAME=${PACKAGE_NAME}" >> $GITHUB_OUTPUT
VERSION="${{ inputs.version }}"
if [ -z "$VERSION" ]; then
# 自动生成测试版本号
BASE_VERSION=$(node -p "require('./package.json').version")
# 生成唯一标识符:优先使用 run_id,否则使用时间戳
if [ -n "${{ github.run_id }}" ]; then
UNIQUE_ID="${{ github.run_id }}"
else
UNIQUE_ID=$(date +%Y%m%d%H%M%S)
fi
VERSION="${BASE_VERSION}-test.${UNIQUE_ID}"
fi
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
echo "Test version: ${VERSION}"
- name: Update package.json version
run: |
VERSION="${{ steps.version.outputs.VERSION }}"
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.version = process.env.VERSION;
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
env:
VERSION: ${{ steps.version.outputs.VERSION }}
- name: Clean and install dependencies
run: |
rm -rf node_modules package-lock.json
npm install
- name: Build
run: npm run build
- name: Publish test package (Trusted Publishers - no token needed)
run: |
PACKAGE_NAME="${{ steps.version.outputs.PACKAGE_NAME }}"
VERSION="${{ steps.version.outputs.VERSION }}"
echo "Publishing ${PACKAGE_NAME}@${VERSION} with tag=test"
# Remove any .npmrc that might interfere with OIDC
rm -f ~/.npmrc
rm -f .npmrc
rm -f /home/runner/work/_temp/.npmrc
# Publish using Trusted Publishers (OIDC)
npm publish --tag test --access public --provenance
env:
# Clear the environment variables that might interfere with OIDC
NPM_CONFIG_USERCONFIG: ''
NODE_AUTH_TOKEN: ''
- name: Summary
run: |
PACKAGE_NAME="${{ steps.version.outputs.PACKAGE_NAME }}"
VERSION="${{ steps.version.outputs.VERSION }}"
echo "## 🧪 Test Package Published (Manual)!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Package:** ${PACKAGE_NAME}@${VERSION}" >> $GITHUB_STEP_SUMMARY
echo "- **Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Install with:" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "npm install ${PACKAGE_NAME}@${VERSION}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY