semantic-release 是什么?
semantic-release 是一个自动化版本管理和包发布的工具, 它允许开发者根据语义化版本控制 (Semantic Versioning, SemVer)规范来自动发布软件包, 通过集成到持续集成/持续部署(CI/CD)管道中 semantic-release 可以在每次代码提交时检查是否满足发布新版本的条件, 并且如果满足, 则会自动确定新的版本号、生成变更日志、发布到注册表或仓库
semantic-release 能做什么?
根据 git 提交记录自动生成变更日志, 但是 git 提交记录的格式必须要符合提交规范, 推荐阅读
自动生成版本号
自动上传 assets 到 GitHub Releases
社区强大, 也可以发布其他语言 package manager 的软件包到它对应的网站, 比如:
1.准备项目
# 1. 创建一个空的 npm 项目
mkdir semantic-release-demo
cd semantic-release-demo
pnpm init
# 2. 安装 typescript 和 semantic-release 及需要的插件
pnpm i -D semantic-release
pnpm i -D @semantic-release/changelog
pnpm i -D @semantic-release/git
# 安装 typescript, 因为现在大多项目都需要编译, 为了还原真实
# 的开发环境, 且尽量减少配置, 这里使用 typescript 编译
pnpm i -D typescript
// 3. 修改 package.json(json文件不能有注释, 这里添加注释是为了做笔记
{
"name": "semantic-release-demo-a1b2c3", // 注意包名必须是唯一的,不能有重复的
"version": "0.0.1",
"main": "dist/index.js",
"type": "module",
"scripts": {
"build": "tsc",
"release": "semantic-release --debug",
},
"repository": {
"type": "git",
"url": "git+https://github.com/liaohui5/semantic-release-demo.git", // 填写自己的仓库地址
},
"keywords": [],
"author": "",
"license": "MIT",
"description": "",
"devDependencies": {
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"semantic-release": "^24.2.1",
"typescript": "^5.7.3",
},
}
// 4. 插件 tsconfig.json 配置文件
{
"include": ["./src/**/*.ts"],
"compilerOptions": {
"target": "es2016",
"module": "ES2015",
"rootDirs": ["."],
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"strict": true,
"skipLibCheck": true,
},
}
// 创建 src/index.ts, 代码无所谓, 主要是为了测试 ci/cd
export function for_test_release_ci_cd_func() {
console.log("1");
}
# 编译并测试
npm run build
# 如果前面都没有问题, 目录应该是这样的
.
├── dist # 编译后的文件
│ └── index.js
├── package-lock.json
├── package.json
├── src
│ └── index.ts # 源文件
└── tsconfig.json
2.准备 GitHub 仓库
做这些步骤之前, 请先自行注册并登录 github 账号
1.获取 Github Token 用于 Github Actions
2.创建一个空的 GitHub 仓库, 并配置 GitHub Actions Secrets
3.准备 npmjs.com 的账号的 token
请先自行注册并登录 npmjs.com
1.获取 npmjs.com Token 用于 Github Actions
2.将获取到的 npmjs.com Token 配置到 GitHub Actions Secrets
4.配置 semantic-release
在项目目录中创建 release.config.js
文件, 内容如下:
代码没有多少, 主要都是注释...😄😄😄
/**
* @type {import('semantic-release').GlobalConfig}
*/
export default {
// 在哪些 git 分支上进行 release,
// 注意配合 Github Actions workflow 使用
branches: ["main", "next"],
// 插件配置: 默认有内置的 4 个插件, 不需要手动安装
// commit-analyzer release-notes-generator npm github
plugins: [
// 1.分析 commit 信息(请注意git提交规范 https://semver.org)
// 插件文档: https://github.com/semantic-release/commit-analyzer
"@semantic-release/commit-analyzer",
// 2.根据提交历史生成 release notes 说明
// 插件文档: https://github.com/semantic-release/release-notes-generator
"@semantic-release/release-notes-generator",
// 3.自动生成或更新 CHANGELOG.md 文件, 记录每个版本的变更内容
// 注意这个插件不是必须的, 它需要手动安装
// 插件文档: https://github.com/semantic-release/changelog
["@semantic-release/changelog", { changelogFile: "./CHANGELOG.md" }],
// 4.自动更新 package.json 中的 version 字段, 并支持发布到 npm 仓库
// 插件文档: https://github.com/semantic-release/npm
[
"@semantic-release/npm",
{
// 仅修改 package.json 的 version 字段, 不要发布到 npm 仓库
npmPublish: false,
},
],
// 5.自动生成 git commit 并提交(assets: 指定哪些文件需要更新&提交)
// 注意这个插件不是必须的, 它需要手动安装
// 插件文档: https://github.com/semantic-release/git
[
"@semantic-release/git",
{
// assets: ["package.json", "CHANGELOG.md"],
message: "chore(release): ${nextRelease.version} [skip ci]",
},
],
// 6.在 GitHub 上创建 Release 和 Tag, 并将 Release Notes 作为正文内容
// 插件文档: https://github.com/semantic-release/github
"@semantic-release/github",
],
};
5. 配置 GitHub Actions workflows
在项目根目录下新建 .github/workflows/release.yml
文件, 内容如下:
name: Release
on:
push:
branches:
- main
- next
jobs:
release:
name: Release
runs-on: ubuntu-latest
permissions: # 权限设置
contents: write
packages: write
pull-requests: write
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整的提交历史(semantic-release 需要)
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Install Dependencies
run: pnpm install
- name: Configure Git
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "actions@github.com"
- name: Run Semantic Release
run: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} # 需要在仓库主页的 settings 中配置
# NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# 如果需要自动发布到 npm 仓库, 请取消注释
# 注意修改 .releaserc.js 中的 `npmPublish` 字段的值为 true
TIP
如果这些步骤都没有问题, 目录结构应该是这样的
.
├── .github
│ └── workflows
│ └── release.yaml
├── node_modules
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── release.config.js
├── src
│ └── index.ts
└── tsconfig.json
6.提交代码
- 注意分支必须是
main
- 注意提交代码时, 提交信息必须符合规范(才能保证正确生成 changelog)
- 提交之后查看 github runners, 会自动发布到 npmjs.com 仓库和 github releases 页面
可以看到没有问题, 已经操作成功了
7. 修改代码再次提交测试
这次不要在 main
分支修改代码, 而是新建一个 next
分支, 修改代码后在提交测试
提交之后, 会提示有 pull-request
需要合并到 main
分支, 点击 Compare & pull request
合并
合并请求后,会自动触发 release
workflow, 然后重新打 tag, 生成 changelog, 上传 assets, 发布到 npm
扩展
一般企业内部非开源的代码不会放到 github 和 npm 上去
如何搭建 npm 私服并且将包发布到私服, 而不是 npmjs.com?
- 搭建 npm 私服
- 获取 npm 私服的 token, 登录私服后会存在
~/.npmrc
文件中
- 在 package.json 中添加
publishConfig
字段
{
"publishConfig": {
"registry": "https://your-npmjs.com/",
"tag": "latest"
}
}
- 将 github 配置的 secrets 中的 NPM_TOKEN 修改为 verdaccio 私服的 token
如何使用 gitea/gitlab 完成这些操作?
只要安装对应代码托管凭他的插件
将
release.config.js
中的@semantic-release/github
修改即可将
.github/workflows/release.yml
修改为对应平台的 cicd 工作流即可