使用 Semantic Release 实现 NPM 全自动发版 monorepo 和 单仓库 项目

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

  1. 登录 npmjs.com
  2. 点击头像 → Access Tokens
  3. 点击 "Generate New Token"
  4. 选择 "Automation" 类型
  5. 复制生成的 token

example: npm_Easwh8OQHMbxxxxxxxxx

3.4.2. 获取 GitHub Token

  1. 创建 Github 个人访问令牌
  2. 点击 Generate new token
  3. 根据你的需求选择 Repository access
  4. 生成具有以下权限的新令牌:
    • 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

  1. 进入你的 GitHub 仓库
  2. Settings → Secrets and variables → Actions
  3. 点击 "Repository secrets"
  4. 添加 NPM_TOKEN,值为3.4.1获取的 NPM token
  5. 添加 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 后,你的发版流程将变得极其简单:

  1. 开发功能 → 按规范提交代码
  2. 推送到 master → 自动触发发版流程
  3. 自动完成 → 版本升级、打标签、发布包、创建 Release

如果这篇文章对你有帮助,别忘了给项目点个 ⭐ Star!有问题欢迎在评论区讨论。

相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax