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/for-write-note-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 {
branches: ["main", "next"], // 哪些 git 分支需要触发 semantic-release
plugins: [
// 1.安装(pnpm i -D semantic-release) 后, 默认会有这4个插件
// commit-analyzer/release-notes-generator/npm/github
[
// 分析提交记录的 conventional-changelog, 用于生成变更日志
// https://github.com/semantic-release/commit-analyzer
"@semantic-release/commit-analyzer",
{
// 会根据提交记录的 分析出修改的版本
// 用于控制修改版本规则 major.minor.patch
// 推荐阅读: https://www.conventionalcommits.org/zh-hans/v1.0.0/
// 如果需要修改 major 版本, 只需要在 commit 类型后添加 ! 即可, 如: feat!: xxx
// 并且在 git 提交消息体中增加: BREAKING CHANGE: xxx, 如:
// feat!: 增加了xxx功能,优化了xxx性能
// (注意按照规范, 这里必须有个空行)
// BREAKING CHANGE: xxx
releaseRules: [
{ type: "fix", release: "patch" }, // 如果 push 代码时有 fix 类型的提交信息, 则修改版本号为 patch
{ type: "refactor", release: "patch" },
{ type: "perf", release: "patch" },
{ type: "chore", release: "patch" },
{ type: "feat", release: "minor" }, // 如果 push 代码时有 feat 类型的提交信息, 则修改版本号为 minor
],
},
],
// 2.如果需要给插件传入参数, 可以使用数组形式, 数组第一个元素是插件名称,
// 后面是插件参数, 不需要传参可以用字符串的形式
// 这个插件的功能是: 使用 conventional-changelog 生成变更日志内容
// https://github.com/semantic-release/npm
// https://github.com/semantic-release/release-notes-generator
"@semantic-release/release-notes-generator",
// 3.每个发布步骤都是通过可配置的插件实现的, 为了实现更方便的功能, 可以去官网找更多需要的插件:
// https://semantic-release.gitbook.io/semantic-release/extending/plugins-list
[
// 将 Github Actions 生成的提交记录, 写入到 CHANGELOG.md 文件中
"@semantic-release/changelog",
{
changelogFile: "CHANGELOG.md",
},
],
// 3. 将代码发布到 npmjs.com 仓库
// https://github.com/semantic-release/npm
[
"@semantic-release/npm",
{
// npmPublish: 是否发布到 npm 仓库, false: 表示不发布 true:表示发布到 npm 仓库
// 1.注意需要配置 github secrets
// 2.会自动修改 package.json 的 version 字段
// 3.如果开启了 2fa 安全验证码, 需要在生成 npm token 时选择 "Automation" 类型
npmPublish: true,
},
],
// 4. 默认情况下 semantic-release 打包发布的版本与 commit 的版本号一致, 但是与 package.json
// 的版本号不一致, 所以要配置让 github tag 和 package.json 版本号保持一致
[
"@semantic-release/git",
{
assets: ["dist"],
message:
"ci(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
},
],
// 5.这个是发布到 tags 页面的额外资源, 比如一些软件会把构建结果的包放在这里
// 比如: https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/v2.0.2
// 除了源码(tar.gz)压缩包之外, 还增加了很多构建好的软件, 如: Clash.Verge_2.0.2_x64-setup.exe
// 我这里就把这个项目的 typescript 构建好的代码都放在这里
// https://github.com/semantic-release/git
[
"@semantic-release/github",
{
assets: ["dist"],
},
],
],
};
5. 配置 GitHub Actions workflows
在项目根目录下新建 .github/workflows/release.yml
文件, 内容如下:
name: Release
on:
push:
branches:
- main
pull_request:
types: [closed]
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write # 确保有写入权限
packages: write # 如果你也在发布包的话
pull-requests: write # 如果需要处理 PR 相关的事情
steps:
- name: download codes
uses: actions/checkout@v4
- name: install pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: install node
uses: actions/setup-node@v4
with:
node-version: 20
- name: install dependencies
run: pnpm install
# - name: run unit tests
# run: pnpm test
- name: build
run: pnpm build
- name: run semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # 注意这2个变量,要和github screts中配置的一致
run: pnpm run release
TIP
如果这些步骤都没有问题, 目录结构应该是这样的
.
├── .github
│ └── workflows
│ └── release.yaml
├── dist
│ └── index.js
├── 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
字段
"repository": {
"type": "git",
"url": "git+https://github.com/liaohui5/single-utils-demo"
}
- 将 github 配置的 secrets 中的 NPM_TOKEN 修改为 verdaccio 私服的 token