使用 pnpm workspace 与 Changesets 版本管理工具
@otter-hacker/tooling 项目为例。

CleanShot 2024-01-16 at 21.33.46@2x.png

如果不想发布根项目目录下的 package.json,就将根目录的 package.json 设置为私有项目

"private": true,

这样使用 pnpm publish -r 发布时就会跳过这个 package

本地命令发布

文档:在 pnpm 中使用 Changesets | pnpm

  1. 如果开发完一个功能,执行 pnpm changeset ,选择变更的包, 描述此次的改动是什么,这将在.changeset 目录生成 md 文件,需要提交到仓库
  2. 全部功能开发完毕,需要发布了,执行 pnpm changeset version,这将消耗之前生成的changeset md 文件,并生成 CHANGELOG
  3. 执行 pnpm install,这将更新锁文件并重新构建包。
  4. 提交更改。
  5. 运行 pnpm publish -r。 此命令将发布所有包含被更新版本且尚未出现在包注册源中的包。

详细说明:

当所有变更都准备好之后(push 到远程)首先执行

pnpm changeset
 
# 或者 
 
pnpm changeset add

执行pnpm changeset 之后会弹出交互式命令:

🦋  Which packages would you like to include? · @otter-hacker/eslint-config, @otter-hacker/prettier-config, @otter-hacker/stylelint-config, @otter-hacker/tailwind-config, @otter-hacker/tsconfig
 
🦋  Which packages should have a major bump? · No items were selected
🦋  Which packages should have a minor bump? · No items were selected
🦋  The following packages will be patch bumped:
🦋  @otter-hacker/[email protected]
🦋  @otter-hacker/[email protected]
🦋  @otter-hacker/[email protected]
🦋  @otter-hacker/[email protected]
🦋  @otter-hacker/[email protected]
🦋  Please enter a summary for this change (this will be in the changelogs).
🦋    (submit empty line to open external editor)
🦋  Summary · remove tooling package
🦋  
🦋  === Summary of changesets ===
🦋  patch:  @otter-hacker/eslint-config, @otter-hacker/prettier-config, @otter-hacker/stylelint-config, @otter-hacker/tailwind-config, @otter-hacker/tsconfig
🦋  
🦋  Note: All dependents of these packages that will be incompatible with
🦋  the new version will be patch bumped when this changeset is applied.
🦋  
🦋  Is this your desired changeset? (Y/n) · true
🦋  Changeset added! - you can now commit it
🦋  
🦋  If you want to modify or expand on the changeset summary, you can find it here
🦋  info /Users/ly/code/github/tooling/.changeset/plenty-snails-burn.md

注意这里会首先让你选择哪些软件包应该进行重大更新,选择之后这个包的版本号会进行大版本变化 1.0 2.0,回车可以跳过

Which packages should have a major bump? · No items were selected

跳过之后会让你选择哪些软件包应该进行小版本升级?同上,选择之后包的版本号会进行小版本升级 1.0 1.1

Which packages should have a minor bump? · No items were selected

如果都不选择,则会自动选择 patch 补丁升级 1.1.0 1.1.1

The following packages will be patch bumped:

选择完成后 changeset 会生成一个改动说明文件,在 .changeset 文件夹下,这个文件需要提交到仓库

Changeset added! - you can now commit it

将这些文件保存提交远程后执行 pnpm changeset version ,此命令修改需要发布的包的版本号,并且为每个 package 生成 CHANGELOG 说明文件,**然后执行 pnpm install 更新lock 文件依赖,**将生成的文件提交到仓库。

pnpm changeset version

执行 pnpm publish -r 将发布注册表中尚未存在的已升级版本的所有软件包。

pnpm publish -r

等成功提交后就会在控制台提示了

npm notice 📦  @otter-hacker/[email protected]
npm notice === Tarball Contents === 
npm notice 799B README.md   
npm notice 145B index.ts    
npm notice 748B package.json
npm notice 107B postcss.js  
npm notice === Tarball Details === 
npm notice name:          @otter-hacker/tailwind-config           
npm notice version:       2.0.1                                   
npm notice filename:      otter-hacker-tailwind-config-2.0.1.tgz  
npm notice package size:  925 B                                   
npm notice unpacked size: 1.8 kB                                  
npm notice shasum:        7138499d9f93cd8115bde73d2781f3c84138951f
npm notice integrity:     sha512-XwxovLFghyYff[...]MUFKaGbgzC8jA==
npm notice total files:   4                                       
npm notice 
npm notice Publishing to https://registry.npmjs.org/ with tag latest and public access
+ @otter-hacker/[email protected]

注意,执行 pnpm publish 之前确保已经登录了 npm 账号, 使用 npm whoami 可以查看当前登录的 npm 账号,否则没有权限提交

Github Action 发布

添加 publish.yml 文件,这个文件每当有代码提交到 main 分支的时候都会执行,会执行 changesets/action@v1 判断 .changeset 文件夹中有没有未消耗的 changeset 文件,有的话会消耗掉这些文件,修改需要发布的 package version 并创建发布 PR,如果没有的话,就会直接发布到 npm。

name: Publish
on:
  push:
    branches:
      - "main"
 
concurrency: ${{ github.workflow }}-${{ github.ref }}
 
env:
  CI: true
  PNPM_CACHE_FOLDER: .pnpm-store
jobs:
  version:
    timeout-minutes: 15
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
        with:
          version: 8
      - uses: actions/setup-node@v3
        with:
          node-version: 20.x
          cache: "pnpm"
      - name: install dependencies
        run: pnpm install
      - name: create and publish versions
        uses: changesets/action@v1
        with:
          version: pnpm run version
          commit: "chore: update versions"
          title: "chore: update versions"
          publish: pnpm run release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
 

官方文档:
在 pnpm 中使用 Changesets | pnpm

详细说明

  1. dev 分支开发完成一个功能,执行 pnpm changeset,选择变更的包, 描述此次的改动是什么,这将在.changeset 目录生成 md 文件,需要提交到仓库
  2. 全部功能开发完毕,将 dev 分支合并到 main 触发 Github Action, 此时会自动执行 yml 配置中的 pnpm run version 命令,也就是 pnpm changeset version, 将会修改变动的包的版本号,以及生成对应的 CHANGELOG 日志文件,执行完毕后会创建一个 Pull Request ,目标分支为 changeset-release/main,这时候 package 还未真正发布到 npm
  3. Merge Pull Request,再次触发 Github Action, 这时候会执行 changesets/action@v1,此时.changesets 文件中的更改集已经被 pnpm changeset version 命令使用掉,所以 No changesets found, attempting to publish any unpublished packages to npm。未找到任何更改集,尝试将所有未发布的软件包发布到npm。然后会执行 pnpm run lint && pnpm publish -r 命令,将 package 发布到 npm 中。

CleanShot 2024-01-18 at 00.26.44@2x.png

如果报错 The requested URL returned error: 403 没有 Github TOTEN 的权限,需要修改项目的配置设置

如果Action 遇到了 The process '/usr/bin/git' failed with exit code 128 的错误
CleanShot 2023-02-25 at 03.15.45@2x.png
需要设置 workflow 使用 GITHUB_TOKEN的权限,在仓库的 Setting Actions General 下设置 Workflow Permissions,勾选 Read and write permissions 选项 。如果 Action 需要创建 pull requests,则需要将最后的 Allow Github Actions to create and approve pull request 选项也勾选上,否则会报
GitHub Actions is not permitted to create or approve pull requests. 错误

如果是组织项目,则需要在组织的设置中去设置

CleanShot 2023-02-25 at 03.22.38@2x.png

保存后重新执行失败的Publish Action,如果一切没问题,就会在看到的仓库的 Pull requests 下有了新的 PR:Version Packages,确认合并当前 PR,会自动运行 Action。运行成功后不出意外就会发布到 Npm 上。
但是,如果是新的仓库,大概率会运行失败,如果出现了下面的错误,则还是权限的错误

参考