☰
release-it 干运行(Dry Run)指南:安全预览版本发布流程与命令执行
2026/9/25 3:10:20 网站建设 项目流程
  • 开发工具
  • DevOps

【免费下载链接】release-it

🚀 Automate versioning and package publishing

项目地址:https://gitcode.com/gh_mirrors/re/release-it
点击查看免费下载

导读

release-it是一款自动化版本号管理、Git 标签/提交、Changelog 生成与 npm/GitHub/GitLab 发布的工具。在真正执行一次发布之前,你可能希望先"预览":它会执行哪些命令?会修改哪些文件?交互式提示长什么样?docs/dry-runs.md中介绍的Dry Run(干运行)模式正是为此而生。阅读本文后,你将掌握--dry-run、--release-version、--changelog三个核心标志的用法、$与!输出符号的确切含义,以及从源码层面理解 release-it 如何区分"只读命令"与"写操作命令"。

一、Dry Run 是什么

Dry Run 是 release-it 提供的一种零风险预览模式:它完整模拟一次版本发布的流程(包括版本递增、Git 操作、发布平台调用、交互提示),但不实际写入任何内容。

在 lib/cli.js 的帮助文本中,--dry-run(短别名-d)的官方描述是:

Do not touch or write anything, but show the commands

即:"不触碰、不写入任何内容,只展示将要执行的命令"。该标志在 lib/args.js 中被注册为d: 'dry-run',并在 lib/config.js 中通过isDryRungetter 暴露给整个运行时使用。

二、基本用法:release-it --dry-run

在项目根目录直接运行:

release-it --dry-run

release-it 会展示完整的交互过程以及它本将要执行的命令。典型输出形如:

$ git rev-parse --git-dir .git ! git add package.json ! git commit --message="Release 0.8.3"

关键点在于输出前缀符号的语义:

  • $ ...表示这是一条只读命令,它仍然会被真实执行(例如git rev-parse --git-dir、git log等读取性操作);
  • ! ...表示这是一条潜在的写入/变更命令,在 dry-run 模式下不会被执行(例如git add、git commit、git push等)。

三、源码级原理:$与!是如何产生的

3.1 写操作拦截点:lib/shell.js

release-it 所有外部命令(git、npm 等)都经由 lib/shell.js 中的execFormattedCommand统一执行。核心逻辑如下:

const { isDryRun } = this.config; const isWrite = options.write !== false; // 未显式声明 write: false 的命令都被视为"写操作" if (isDryRun && isWrite) { this.log.exec(command, { isDryRun }); // 只记录命令,不真正执行 return noop; }

也就是说:在 dry-run 模式下,凡是options.write未显式设为false的命令,都会被拦截——release-it不会调用child_process去执行它,而是立即返回一个已决议的 Promise,并把命令交给 Logger 输出。

3.2 前缀符号生成点:lib/log.js

命令前缀$或!由 lib/log.js 的exec方法生成:

const prefix = isExecutedInDryRun == null ? '$' : '!';
  • 当命令是通过 dry-run 拦截标记(即isExecutedInDryRun非空)打印时,前缀为!;
  • 当命令是正常记录(只读命令)时,前缀为$。

因此,前缀!不是命令本身的属性,而是 dry-run 拦截的结果——只有被判定为"写操作且未执行"的命令才会被打上!标记。

3.3 哪些命令被声明为只读

从源码结构看,各插件通过{ write: false }显式声明只读命令:

  • lib/plugin/git/Git.js:Git 插件的默认执行选项const options = { write: false },即git rev-parse、git log、git tag --list等读取类命令照常执行,用于获取真实的仓库信息;
  • lib/plugin/npm/npm.js:getOptions返回{ write: false, env: getNpmEnv() },用于npm view、npm dist-tag ls等只读查询。

而git add、git commit、git push等命令在 Git 插件的release()流程(lib/plugin/git/Git.js)中通过this.step(...)执行,默认视为写操作,因此在 dry-run 下只打印!前缀命令而不真正执行。

四、Dry Run 模式下各发布平台的降级行为

dry-run 不只是"跳过命令",从源码看,各插件还为 dry-run 提供了短路式假成功路径,保证流程能完整走完、不因缺少真实响应而中断:

  • GitHub 插件(lib/plugin/github/GitHub.js):isAuthenticated与isCollaborator在config.isDryRun为真时直接返回true(跳过 API 鉴权);createRelease在 dry-run 下打印命令后设置{ isReleased: true, releaseUrl: ... }并返回true(GitHub.js);uploadAssets、updateRelease、publishRelease、commentOnResolvedItems同样只打印octokit ...调用并直接返回;
  • GitLab 插件(lib/plugin/gitlab/GitLab.js):isAuthenticated、isCollaborator同样在 dry-run 下短路;createRelease打印gitlab releases#createRelease后返回true并设置假的发布上下文;
  • npm 插件(lib/plugin/npm/npm.js):发布命令会追加真实的--dry-run参数(npm publish ... --dry-run),让 npm 自身也进入 dry-run 模式;当 npm 返回 "publish over the previously published version" 之类的错误时,dry-run 下也会被吞掉并正常结束,同时logWouldStage()会提示 "📦 Would stage (dry-run). Approve at ... after a real run."。

这保证了你可以在 dry-run 下完整预览 Git、npm、GitHub/GitLab 三个环节的全部操作,而不会在鉴权或 API 调用处提前中断。

五、只打印版本号:--release-version

如果你只需要知道"下一次会发布哪个版本号",而不想看完整流程,使用--release-version标志:

release-it --release-version

该标志会:

  • 计算并打印下一个版本号(如1.2.3)到标准输出;
  • 然后立即以成功状态退出,不做任何 Git/npm/发布操作。

如果当前没有可用的下一个版本,则什么都不打印,并以成功状态退出(exit code 0)。这一行为在 lib/index.js 中有明确实现:

if (isReleaseVersion) { if (version) { console.log(version); } process.exit(0); }

该标志非常适合在脚本中捕获版本号:

NEXT_VERSION=$(release-it --release-version) echo "即将发布版本:$NEXT_VERSION"

注意:版本计算依赖插件链,例如 Git 插件从git describe/ 标签中读取 latest version,再根据提交历史与--increment(major/minor/patch/pre*)计算下一个版本;在没有提交时可能拿不到下一个版本,此时输出为空。

六、只打印 Changelog:--changelog

如果你只想预览本次发布会生成哪些 Changelog 内容,使用--changelog标志:

release-it --changelog

它会打印本次要发布的版本所对应的 Changelog(来自 docs/changelog.md 所述的默认git log命令或自定义的git.changelog配置),然后退出。与--release-version的差异在于:找不到 Changelog 时它会打印警告并以退出码 1 结束,而非静默成功(lib/index.js):

if (isChangelog) { if (changelog) { console.log(changelog); process.exit(0); } else { log.warn('No changelog found'); process.exit(1); } }

该标志适合在 CI 中生成发布说明草稿,或与github.releaseNotes/gitlab.releaseNotes配置联调校验 Changelog 输出。

七、组合使用与实战建议

7.1 三个标志可以搭配其他参数使用

dry-run 与其他 CLI 参数完全兼容,例如指定递增级别:

release-it minor --dry-run release-it --dry-run --increment=preminor

也可以配合--ci(无交互)在 CI 中做发布预演,配合--verbose/-VV查看更详细的内部命令输出(参见 lib/cli.js 的完整帮助文本)。

7.2 何时使用 Dry Run

  • 上线前预演:发布前先跑一次--dry-run,核对将要执行的 git 命令、npm publish 命令与 GitHub/GitLab release 调用是否与预期一致;
  • 配置联调:修改.release-it.json、hooks、插件配置后,用 dry-run 验证配置是否被正确解析、hook 是否会触发(注意:外部 hook 脚本在 dry-run 下仍会执行,因为它们属于用户自定义动作,这一点在 lib/index.js 的runHook中通过shell.exec(script, { external: true }, ...)调用,需要自行留意);
  • 脚本集成:--release-version与--changelog是纯输出型标志,适合嵌入 CI 流水线生成版本号与发布说明。

7.3 注意事项

  • dry-run 并非"绝对零副作用":只读命令仍会真实执行(如git log、git describe),且npm publish --dry-run会触发 npm 自身的校验流程;
  • 需要保证 Git 工作区干净(requireCleanWorkingDir默认开启),否则即使 dry-run 也会在初始化阶段报错(见 lib/plugin/git/Git.js);
  • dry-run 输出的!命令只是"本应执行"的预告,实际发布时命令参数可能因上下文(如推送到哪条分支、上游是否已配置)略有差异,最终以真实运行为准。

八、相关资源

  • 本文依据的官方文档:docs/dry-runs.md
  • CLI 参数与帮助文本:lib/cli.js、参数解析与别名定义:lib/args.js
  • 执行与拦截核心:lib/shell.js、输出符号生成:lib/log.js、运行主流程:lib/index.js
  • 相关配置说明:docs/configuration.md、docs/git.md、docs/github-releases.md、docs/gitlab-releases.md、docs/npm.md
  • 开发工具
  • DevOps

【免费下载链接】release-it

🚀 Automate versioning and package publishing

项目地址:https://gitcode.com/gh_mirrors/re/release-it
点击查看免费下载
上一篇:DeepSurv超参数优化:提升生存预测模型性能的实用技巧
下一篇:从Helium到Moshi再到PersonaPlex:Kyutai与NVIDIA语音AI技术栈梳理

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询