Skip to content

relizy-runner

relizy历史兼容层脚本。它最初主要服务于 relizy@1.2.1 一类版本:在执行 relizy 前补齐 Windows / independent 首次发版的前置条件,但不改写 relizy 自身的版本计算与发版算法。

随着上游 PR #53 与 PR #58 合并,本文需要把 runner 的能力拆成两类来看:

  1. release / bump--yes 预设:当前仍然有效。对这两个子命令,若参数中尚未包含 --yes,runner 会在调用 relizy 前自动追加 --yes,避免 bump 前交互确认在 CI 或非 TTY 下阻塞。若你需要本地逐步人工确认,请传入 runner 专用参数 --no-yes(不会转发给 relizy,且会关闭上述自动注入)。
  2. Windows GNU 工具补齐:这是历史兼容能力。它只对尚未包含 PR #58 的 relizy 版本仍然有意义;一旦你使用的 relizy 已经包含 PR #58,这部分能力就属于过时兜底。
  3. Independent 基线 tag 硬性预检:这也是历史兼容能力。它同样只对尚未包含 PR #58 的 relizy 版本仍然有意义;如果上游已支持 first-release bootstrap,这里的“先补 baseline tag 再继续”就不再是长期推荐路径。

先说结论:上游现在到底修没修?

截至 2026-04-14,结论要分三层说,不能简单写成一句“已经修了”:

观察面状态说明
仓库历史里是否已经有修复PR #53 与 PR #58 都已经合并
main / 最新稳定版是否已包含修复没有全部包含main 当前仍指向 v1.2.1,发布时间是 2026-03-19,早于这两个 PR
哪些分支或标签已经拿到修复部分拿到PR #53 已进入 develop,并出现在 v1.2.2-beta.0;PR #58 已合并到 fix/windows-support,但截至 2026-04-14 仍不在 main,也晚于 v1.3.0-beta.0 tag

换句话说:

  • 如果你问的是“LouisMazel/relizy 这个仓库里有没有修复提交”,答案是:
  • 如果你问的是“今天直接安装最新稳定版 npm 包就一定拿到了这些修复吗”,答案是:不一定,至少最新稳定版 v1.2.1 还没有
  • 如果你问的是“relizy-runner 文档里哪些能力应该标记为历史能力”,答案是:Windows GNU 工具补齐independent 基线 tag 硬性预检都该标记为“随上游版本推进而过时”的内容。

两个关键 PR 分别修了什么?

PR #53:修复 Windows 路径分隔符误报

上游 PR #53

  • 标题:fix(repo): normalize path separators to POSIX before commit body matching
  • 合并日期:2026-03-24
  • 合入分支:develop
  • 已进入标签:v1.2.2-beta.0

它修复的是这类误报:

text
× No packages to bump, no relevant commits found

根因是旧版本 relizy 在 isCommitOfTrackedPackages / getPackageCommits 里,用 Windows 的 path.relative() 结果去匹配 Git --name-status 的 POSIX 路径,导致:

  • Git 输出是 packages/admin/src/main.ts
  • Windows relative() 常得到 packages\\admin
  • commit.body.includes(relativePath) 因分隔符不一致直接失败

PR #53 的修复方式,是先把 relative(...) 的结果做成 POSIX 风格,再参与 includes 匹配。这个修复同时覆盖了:

  • isCommitOfTrackedPackages
  • getPackageCommits

所以,“Windows 路径分隔符误报”这个具体问题,已经被 PR #53 修掉了。但前提是:你实际使用的 relizy 版本必须已经包含 PR #53

PR #58:修复 Windows GNU 管道依赖与首次 independent 发版 bootstrap

上游 PR #58

  • 标题:fix: support Windows initial independent releases
  • 合并日期:2026-04-13
  • 合入分支:fix/windows-support
  • 截至 2026-04-14 的状态:还不在 main,也晚于 v1.3.0-beta.0 tag

它补的是 PR #53 之外的另一半问题:

  1. 去掉 Windows 纯 shell 环境下对 grep / head / sed 的剩余依赖,改成 git tag --sort=-creatordate 后在 Node.js 内过滤。
  2. 让全新仓库 / 全新子包在没有 baseline tag 时,也能通过内部 NEW_PACKAGE_MARKER + bootstrap baseline 正常走首次 independent 发版。

这意味着:一旦你使用的 relizy 版本真正包含 PR #58,runner 里的两类历史兼容能力就会明显过时

  • Windows GNU 工具补齐
  • “没有 baseline tag 就直接阻断”的硬性预检

现在还要不要用这个兼容层?

不要只看操作系统,更要先看你实际用的是哪一版 relizy。

你的 relizy 来源是否还建议依赖 runner原因
main / 最新稳定版 v1.2.1仍然建议PR #53、PR #58 都还不在稳定版里
已包含 PR #53,但未包含 PR #58 的 beta / 分支部分建议路径分隔符误报已修,但 GNU 工具补齐与首次 bootstrap 仍可能需要 runner
已包含 PR #58 的当前 canary / 分支(如本次 canary)仍需谨慎,不能直接删除 runner2026-04-14 的独立 worktree 测试表明:1.3.0-canary.a8967ef.0 在 brand-new independent first release 场景下仍未 end-to-end 成功
未来正式版且已重新通过同套矩阵验证才适合进一步降级这两类兼容能力只有当 upstream 版本既包含修复、又真正通过“全新 monorepo + Windows + independent 首发”矩阵时,Windows GNU / baseline 两项才适合下调

也就是说,今天再介绍 relizy-runner,不应该继续把它写成“永远都必须存在的 relizy 伴生层”。更准确的表述应该是:

  • 它是为旧版 relizy 或尚未吃到上游修复的版本准备的过渡层
  • 它的长期保留价值,更多在于仓库级参数策略(例如默认补 --yes),而不是继续替代上游的 Windows / bootstrap 逻辑。

为什么当前还有留存的必要性?

基于 docs/reports/2026-04-14-relizy-canary-initial-independent-release-test.md 的实测结果,截至 2026-04-15,这里还不能把 relizy-runner 直接写成“已经彻底过时,可以删除”。

那份报告的测试条件不是口头推测,而是一套明确的 A/B 矩阵:

  1. 独立 git worktree 内新建了一个全新的 pnpm monorepo。
  2. 两套 sandbox 都绕过 relizy-runner,直接调用 relizy@1.3.0-canary.a8967ef.0
  3. sandbox A 保留正常 Windows PATH;sandbox B 则主动裁剪 PATH,确保 bashshsedgrep 都不可见。
  4. 验证目标同时覆盖:
    • relizy changelog --dry-run
    • relizy release --dry-run
    • 真实 relizy release --no-publish --no-provider-release --no-push --yes
  5. 真实 release 的成功标准是:必须同时生成 changelog、release commit、package tags

原因要分清楚:

  1. 稳定版 relizy 仍未吃到全部修复
    main / latest 仍停在 v1.2.1,PR #53 与 PR #58 都没有完整进入稳定版。对这类版本,runner 里的 --yes 预设、Windows GNU 工具补齐、baseline tag 预检依然有现实意义。
  2. 即便切到包含 PR #58 的 canary,也还没有验证出“完全不需要 runner”
    针对 relizy@1.3.0-canary.a8967ef.0 做过一次独立 worktree 的全新 monorepo 回归测试,结论不是“已经全通”,而是:
    • 去掉 runner 后,最初会先暴露 origin 缺失导致的 provider 推断崩溃;
    • 补了本地 bare origin 后,又统一失败在 initialCommit^...main 这个首次 independent release 的提交范围计算;
    • sandbox B 在 bashshsedgrep 全部不可见时,仍然和 sandbox A 失败在同一处;
    • 两套 sandbox 最终都没有生成 CHANGELOG.md、没有 release commit、没有 package tags
  3. runner 现在更像“保守默认值”而不是“永久算法补丁”
    它不能修掉上游 relizy 自己的 initialCommit^...main 逻辑错误,但它仍然承担仓库级保守策略:统一补 --yes、在旧版 relizy 下补环境、在文档与技能里保留对首发风险的显式提醒。

所以,当前保留 runner 的准确理由不是“它已经证明自己永远不可替代”,而是:

  • 上游稳定版还没全量修完
  • canary 也还没通过 brand-new independent first release 的 end-to-end 验证
  • 仓库侧仍然需要一个保守、统一、可解释的调用入口

同样要强调:“仍需留存”不等于“runner 已经修掉上游 bug”。这两个判断必须分开。当前 runner 的价值,是继续充当过渡期的兼容入口与策略包装层;等 upstream 真正修完并重新通过整套矩阵,再讨论是否进一步降级它的必要性,才是更稳妥的路径。

这份报告对本文的直接影响

docs/reports/2026-04-14-relizy-canary-initial-independent-release-test.md 给本文带来的,不是“runner 被证明永远必要”,而是更克制的三条结论:

  1. 不能只因为 PR #58 已合并,就把本文里的兼容说明全部删除。
  2. 不能把 1.3.0-canary.a8967ef.0 误写成“已经足以替代 runner 的版本”。
  3. 本文必须把 runner 描述成“过渡期兼容入口”,而不是“永久修补 relizy 的上游替代品”。

所以,当前这份文档的写法故意保留了两个层次:

  • 一方面明确说明:Windows GNU 工具补齐与 baseline tag 预检,属于会随 upstream 演进而过时的历史兼容能力
  • 另一方面也明确写出:在 2026-04-14 这次实测里,当前 canary 还没证明这些能力已经可以整体移除

关于 Windows 下的误报「No packages to bump」

如果你在 Windows + independent monorepo 下遇到:

text
× No packages to bump, no relevant commits found

先不要立刻把它理解成「确实没有待发版改动」,但也不要再把所有同名报错都归因于历史上的路径分隔符故障。正确判断顺序应该是:

  1. 先确认当前 relizy 版本是否已经包含 PR #53。
  2. 未包含,优先把这条报错视为“可能命中历史上的 Windows 路径分隔符误报”。
  3. 已经包含 PR #53,再去检查是否真的没有可 bump 的提交、types 白名单是否过滤掉了最近的 feat / fix,以及是否还命中了 PR #58 修复前的首次 bootstrap / GNU 工具问题。
  4. 已经包含 PR #58,再出现同名报错时,就不应再优先怀疑 runner 或旧版 Windows 兼容 bug,而应优先检查当前配置与提交本身。

这一节的目的,是避免把三个问题混为一谈:

  • 历史上的 Windows 路径分隔符误报(PR #53)
  • 历史上的 GNU 管道依赖 / 首次 independent bootstrap(PR #58)
  • 当前仓库真实存在的 无可 bump 提交 / 配置过滤 / 类型白名单 问题

这和 relizy-runner 的关系是什么?

这里要区分清楚:

  • relizy-runner 负责:仓库级参数包装(默认补 --yes)、旧版 relizy 的 Windows GNU 工具补齐、旧版 relizy 的 baseline tag 预检
  • relizy-runner 不负责:改写 relizy 自身的 bump 计算、commit 过滤、版本推导、first-release 语义

所以:

  • 旧版 relizy 上,runner 只是“补环境、补前置校验”,并不能替代 PR #53 的路径分隔符修复。
  • 新版且已包含 PR #58 的 relizy 上,runner 里的 GNU / baseline 两项又会逐渐显得过时,因为这些逻辑本来就应该由上游 relizy 自己承担。

顺带结论:move-vercel-output-to-root 不是这次过时点

move-vercel-output-to-rootVercel 构建产物路径兼容脚本,不是 relizy 发版算法的一部分。它和 PR #53 / #58 的关系是:

  • 没有直接关系
  • 没有被这两个 PR 废弃
  • 只是随着 Vercel 官方提供 rootDirectorysourceFilesOutsideRootDirectoryvercel build --output 等能力,它的适用面比最初更窄了

更准确的评价是:

  • 不是像 relizy-runner 的 GNU / baseline 两项那样“被上游 relizy 修复后直接过时”
  • 它只是变成了一个更偏工作流、而不是平台刚需的脚本

如果你的 Vercel 工作流已经能直接用官方 rootDirectory / outputDirectory / vercel build --output 解决 .vercel/output 位置问题,通常就不再需要它;但对那些仍然先在子包里跑框架原生构建、再统一从 monorepo 根目录做 prebuilt 部署的流程,它依然有存在价值

⚠️ 重要:必须使用 bin 命令调用

CAUTION

禁止使用 tsx @ruan-cat/utils/relizy-runner 方式调用本脚本。

这种写法会导致 ERR_MODULE_NOT_FOUND 错误。原因是 tsx/node 等运行时的 CLI 参数只解释为文件系统路径,不会触发 node_modulespackage.jsonexports 模块解析。

本包通过标准的 bin 字段提供可执行命令,安装 @ruan-cat/utils 后即可直接调用。

安装

作为 monorepo 内的 workspace 依赖引用:

json
{
	"devDependencies": {
		"@ruan-cat/utils": "workspace:^"
	}
}

或者作为 npm 包安装:

bash
pnpm add -D @ruan-cat/utils

同时确保项目安装了 relizy

bash
pnpm add -D relizy

使用方式

方式一:通过快捷命令(推荐)

安装本包后,relizy-runner 命令自动注册到 node_modules/.bin

bash
npx relizy-runner release --no-publish --no-provider-release

方式二:通过统一入口命令

bash
npx ruan-cat-utils relizy-runner release --no-publish --no-provider-release

两种方式完全等价。

在 monorepo 根 package.json 中配置

在 monorepo 根目录的 package.json 中,推荐如下配置:

json
{
	"scripts": {
		"release": "relizy-runner release --no-publish --no-provider-release",
		"release:relizy": "relizy-runner release --no-publish --no-provider-release"
	}
}

通过 pnpm 脚本向 relizy 追加参数时,使用 -- 分隔:

bash
pnpm release:relizy -- --patch --dry-run --no-clean

常用命令示例

bash
# 正式发版(默认行为)
pnpm release

# 仅预览 changelog 生成(不写盘、不改仓库)
relizy-runner changelog --dry-run

# 兼容旧脚本 / skill 中显式写出的 --yes(runner 会忽略它,不再透传给 relizy)
relizy-runner changelog --dry-run --yes

# 预览完整 release 流程
relizy-runner release --dry-run --no-publish --no-provider-release

# 仅本地生成提交与 tag、不 push
relizy-runner release --no-publish --no-provider-release --no-push

# 指定 semver 升级策略
pnpm release:relizy -- --patch
pnpm release:relizy -- --minor

runner 专用参数

参数含义
--no-yes关闭 release / bump 的自动 --yes,恢复 relizy 交互确认;不会传给 relizy。

补充说明:

  • release / bump:若未显式传入 --yes,runner 会自动补一个。
  • changelog:runner 不会自动补 --yes
  • changelog --yes:runner 会兼容接受该参数,但会在调用 relizy 前将其吃掉。
  • --no-yes 只关闭自动注入;如果你在 release / bump 下显式写了 --yes,仍会按显式参数透传。

relizy 常用参数(透传)

以下参数大多由 relizy 本身处理;除 --no-yes 外,relizy-runner 通常只负责透传(并在 release / bump 上按需追加 --yes)。唯一的兼容例外是:changelog --yes 会被 runner 吞掉,不再传给上游 relizy。

参数含义
--dry-run预览,不写文件、不打 tag、不提交、不 publish
--no-push不 push 到远端
--no-publish不执行 npm publish
--no-provider-release不在 GitHub/GitLab 创建 Release
--no-commit不创建提交与 tag(与其它跳过项组合使用)
--no-changelog不生成 changelog 文件
--no-verify提交时跳过 git hooks
--yes跳过 relizy 确认提示;release / bump 下 runner 也会自动追加(除非使用 --no-yes);changelog 下仅兼容忽略
--major / --minor / --patch指定 semver 升级策略

查看 relizy 全部选项与子命令:

bash
relizy-runner --help
npx relizy --help
npx relizy release --help

首次接入 independent 模式(旧版 relizy 的历史流程)

如果你使用的 relizy 尚未包含 PR #58,那么首次接入 independent 时,仍应按旧流程先补基线 tag(版本号以当前 package.json 为准)。此时 relizy-runner 会在 release / bump 前自动检查,若缺少基线 tag 会打印类似以下命令:

bash
git tag "@my-scope/admin@1.0.0"
git tag "@my-scope/type@0.1.0"
git push origin "@my-scope/admin@1.0.0" "@my-scope/type@0.1.0"

执行上述命令补齐基线 tag 后,即可继续旧版 relizy 的发版流程。

如果你使用的 relizy 已经包含 PR #58,请优先以该版本的 first-release bootstrap 行为为准,不要再把“必须手工补 baseline tag”视为唯一正确流程。

配套 relizy.config.ts

relizy-runner 不要求特定的 relizy.config.ts 配置,但推荐配合 pnpm-workspace-yaml 解析工作区清单:

typescript
import { readFileSync } from "node:fs";
import { defineConfig } from "relizy";
import { parsePnpmWorkspaceYaml } from "pnpm-workspace-yaml";

const workspaceYaml = parsePnpmWorkspaceYaml(readFileSync("pnpm-workspace.yaml", "utf8"));
const workspacePackages = (workspaceYaml.toJSON().packages ?? []).filter((p) => !p.startsWith("!"));

export default defineConfig({
	monorepo: {
		packages: workspacePackages,
		versionMode: "independent",
	},
	publish: false,
	providerRelease: false,
});

编程式调用

如果需要在 TypeScript/JavaScript 代码中调用本脚本的功能:

typescript
import { runRelizyRunner, getWorkspacePackages, buildBootstrapInstructions } from "@ruan-cat/utils/node-esm";

// 运行 relizy(release / bump 会自动追加 --yes,除非传入 --no-yes)
const exitCode = runRelizyRunner(["release", "--no-publish", "--no-provider-release"]);

// 获取工作区包信息
const packages = getWorkspacePackages();

// 生成基线 tag 提示
const instructions = buildBootstrapInstructions(packages);

自动化测试

bash
pnpm exec vitest run packages/utils/src/node-esm/scripts/relizy-runner/index.test.ts

贡献者

The avatar of contributor named as ruan-cat ruan-cat
The avatar of contributor named as Cursor Cursor

页面历史

最近更新