1.前言
作为项目维护者,你是否也遇到过这样的痛点:
- 每次发版都要手动修改
package.json
版本号 - 手写
CHANGELOG.md
既费时又容易遗漏 - 在 GitHub 创建 Release、打 Tag、发布 NPM 包,一套流程下来十几分钟
- 重复性工作多,容易出错,影响开发效率
如果你也有这些困扰,那么今天介绍的 Semantic Release 工作链路 将彻底解放你的双手!
并且会讲到我在公司里工程化的实践,包含 gitlab
, github
, 私有化npm
, 单仓库
, monorepo
仓库下怎么实现发版。并且在github
会提供一个相关联
2.什么是 Semantic Release?
Semantic Release 是一个全自动的版本管理和发布工具。它通过分析你的 Git 提交信息,自动完成以下所有工作:
- 🎯 自动确定版本号:根据提交类型决定是 patch、minor 还是 major 版本
- 📝 自动生成 CHANGELOG:基于提交信息生成美观的变更日志
- 🏷️ 自动打 Git Tag:无需手动管理版本标签
- 📦 自动发布 NPM 包:一键发布到 npm registry
- 🚀 自动创建 GitHub Release:生成详细的发布说明
3. 单仓库 配置 (github)
模版地址: github.com/electroluxc...
3.1 安装依赖
shell
# 安装 semantic-release 核心包
npm install --save-dev semantic-release
# 安装常用插件
npm install --save-dev @semantic-release/commit-analyzer
npm install --save-dev @semantic-release/release-notes-generator
npm install --save-dev @semantic-release/changelog
npm install --save-dev @semantic-release/npm
npm install --save-dev @semantic-release/git
3.2 Semantic 配置文件 - releaserc.json
创建 .releaserc.json
文件:
javascript
{
"repositoryUrl": "git@github.com:electroluxcode/semantic-release-bolierplate.git",
"branches": [
"master"
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],
"@semantic-release/npm",
[
"@semantic-release/git",
{
"assets": [
"CHANGELOG.md", "package.json"
],
"message": "chore(release): v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
}
其中各个参数说明如下
js
{
// 仓库地址
repositoryUrl: '',
branches: ["master"], // 指定在哪个分支下要执行发布操作
plugins: [
// 1. 解析 commit 信息,默认就是 Angular 规范
"@semantic-release/commit-analyzer",
// 2. 生成发布信息
"@semantic-release/release-notes-generator",
// 3. 把发布日志写入该文件
[
"@semantic-release/changelog",
{
changelogFile: "CHANGELOG.md",
},
],
// 4. 发布 NPM
"@semantic-release/npm",
// 5. changelog 和 vesion,需要重新写入 package.json
[
"@semantic-release/git",
{
assets: ["CHANGELOG.md", "package.json"],
},
],
],
};
3.3 配置 GitHub Actions
创建 .github/workflows/release.yml
:
yaml
name: Release
on:
push:
## 触发的分支
branches: [master]
# 重要:配置必要权限
permissions:
contents: write
issues: write
pull-requests: write
packages: write
id-token: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v3
with:
fetch-depth: 0
persist-credentials: false
- name: 设置 Node.js
uses: actions/setup-node@v3
with:
node-version: "18"
cache: 'npm'
- name: 安装依赖
run: npm ci
- name: 运行测试(可选)
run: npm test || echo "No tests found"
- name: 构建项目(可选)
run: npm run build || echo "No build script found"
- name: 语义化发版
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
3.4 配置 Token
3.4.1. 获取 NPM Token
- 登录 npmjs.com
- 点击头像 → Access Tokens
- 点击 "Generate New Token"
- 选择 "Automation" 类型
- 复制生成的 token
example: npm_Easwh8OQHMbxxxxxxxxx
3.4.2. 获取 GitHub Token
- 创建 Github 个人访问令牌
- 点击
Generate new token
- 根据你的需求选择
Repository access
- 生成具有以下权限的新令牌:
- Actions - read and write
- Commit statuses - read and write
- Contents - read and write
- Deployments - read and write
example: github_pat_xxxxxxxxxxx
3.4.3 在仓库中配置 Secrets
- 进入你的 GitHub 仓库
- Settings → Secrets and variables → Actions
- 点击 "Repository secrets"
- 添加
NPM_TOKEN
,值为3.4.1
获取的 NPM token - 添加
GH_TOKEN
,值为3.4.2
获取的 GH token
4. 单仓库 配置 (gitlab)
在上面的基础上, 安装一个 gitlab 插件然后指向一下地址就好了
shell
npm install --save-dev @semantic-release/gitlab
.release
js
{
"branches": ["master"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/gitlab",
{
"gitlabUrl": "your url"
}
],
"@semantic-release/changelog",
[
"@semantic-release/npm"
],
[
"@semantic-release/git",
{
"assets": ["package.json", "CHANGELOG.md"],
"message": "chore(release): v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
],
"debug": true
}
5. monorepo 仓库配置 (github)
模版地址: github.com/electroluxc...
token
配置我们都可以复用上面的配置,有一些专属于monorepo
的插件和细节需要我们配置一下
5.1 安装依赖
shell
# 安装 semantic-release 核心包
npm install --save-dev semantic-release
# 安装常用插件
npm install --save-dev @semantic-release/commit-analyzer
npm install --save-dev @semantic-release/release-notes-generator
npm install --save-dev @semantic-release/changelog
npm install --save-dev @semantic-release/npm
npm install --save-dev @semantic-release/git
# monorepo 专属插件
npm install --save-dev semantic-release-monorepo
npm install --save-dev semantic-release-monorepo-npm-plugin
5.2 Semantic 配置文件 - releaserc.json
我们在子仓库的根路径配置 下面的 .releaserc.json
文件即可, 参数不做解释了,基本跟单仓库的差不多
js
{
"repositoryUrl": "git@github.com:electroluxcode/semantic-release-monorepo-bolierplate.git",
"branches": [
"master"
],
"plugins": [
"@semantic-release/commit-analyzer",
["semantic-release-monorepo-npm-plugin", {
"isReplaceWorkspace": true
}],
"@semantic-release/release-notes-generator",
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],
[
"@semantic-release/git",
{
"assets": [
"CHANGELOG.md", "package.json"
],
"message": "chore(release): v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
],
"extends": "semantic-release-monorepo"
}
5.3 配置 Token
跟上面的一样,略
5.4 配置 GitHub Actions
yaml
name: Release
# 当 master 分支被 push,就会触发
on:
push:
branches: [master]
# 权限
permissions:
contents: write
issues: write
pull-requests: write
packages: write
id-token: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: 签出代码
uses: actions/checkout@v3
with:
fetch-depth: 0
persist-credentials: false
- name: 安装 nodejs
uses: actions/setup-node@v2.5.2
with:
node-version: "20.8.1" # node 版本
- name: 构建 dist # 构建,根据自己的仓库构建命令来
run: |
npm -v
node -v
npm install -g pnpm@latest-8
pnpm config set registry https://registry.npmmirror.com
pnpm install
- name: 发布 npm 包
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
pnpm config set registry https://registry.npmjs.org
pnpm -r --workspace-concurrency=1 exec -- npx --no-install semantic-release -e semantic-release-monorepo
6. monorepo 仓库配置 (gitlab)
同样在上面的基础上
安装一个 gitlab 插件然后指向一下地址就好了
shell
npm install --save-dev @semantic-release/gitlab
Senantic 配置文件示例如下
json
{
"branches": ["master"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
["semantic-release-monorepo-npm-plugin", {
"isReplaceWorkspace": true
}],
[
"@semantic-release/gitlab",
{
"gitlabUrl": "your url"
}
],
"@semantic-release/changelog",
[
"@semantic-release/git",
{
"assets": ["package.json", "CHANGELOG.md"],
"message": "chore(release): v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
],
"extends": "semantic-release-monorepo",
"debug": true
}
7. 其他
7.1 私有仓库怎么配置
在发版的流程script中加入如下的代码就可以了
bash
CI_JOB_TOKEN=${CI_JOB_TOKEN:-"your_default_token"}
{
echo "//registry.npmmirror.com/:_authToken=${CI_JOB_TOKEN}"
echo "registry=https://registry.npmmirror.com/"
} | tee .npmrc
7.2 如果我想要跨版本发布怎么办
场景: 仓库的版本是 1.0.0,想要直接升级到 1.4.0 的版本。
这个时候 需要在仓库那里 打一个 tag
, 例如 1.3.0,然后commit 一个 feat 的type就可以了
因为 semantic-release 的 逻辑是 会用仓库中 最近的 tag
做基准, 然后进行发布仓库的仓库
总结
使用 Semantic Release 后,你的发版流程将变得极其简单:
- 开发功能 → 按规范提交代码
- 推送到 master → 自动触发发版流程
- 自动完成 → 版本升级、打标签、发布包、创建 Release
如果这篇文章对你有帮助,别忘了给项目点个 ⭐ Star!有问题欢迎在评论区讨论。