@icebreakers/monorepo-templates 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/.agents/skills/repoctl/SKILL.md +2 -0
- package/assets/.agents/skills/repoctl/references/commands.md +224 -13
- package/assets/.agents/skills/repoctl/references/config.md +70 -6
- package/assets/.agents/skills/repoctl/references/dependencies.md +37 -0
- package/assets/.agents/skills/repoctl/references/knip.md +34 -0
- package/assets/.agents/skills/repoctl/references/templates.md +23 -0
- package/assets/.github/workflows/ci.yml +10 -10
- package/assets/package.json +5 -9
- package/assets/pnpm-workspace.yaml +2 -1
- package/assets/repoctl.config.ts +1 -1
- package/assets/turbo.json +2 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +281 -1
- package/dist/index.mjs +1137 -74
- package/dist/{prepare-2VvFwYDz.mjs → prepare-BYNSxvoB.mjs} +76 -4
- package/package.json +2 -1
- package/template-data.mjs +24 -0
- package/templates/client/package.json +1 -1
- package/templates/next/README.md +31 -0
- package/templates/next/eslint.config.js +5 -0
- package/templates/next/gitignore +7 -0
- package/templates/next/next.config.ts +5 -0
- package/templates/next/package.json +36 -0
- package/templates/next/src/app/api/health/route.ts +5 -0
- package/templates/next/src/app/counter.tsx +19 -0
- package/templates/next/src/app/favicon.ico +0 -0
- package/templates/next/src/app/globals.css +109 -0
- package/templates/next/src/app/layout.tsx +17 -0
- package/templates/next/src/app/page.tsx +16 -0
- package/templates/next/stylelint.config.js +3 -0
- package/templates/next/test/counter.test.tsx +22 -0
- package/templates/next/tsconfig.json +40 -0
- package/templates/next/turbo.json +24 -0
- package/templates/next/vitest.config.js +9 -0
- package/templates/react-lib/LICENSE +21 -0
- package/templates/react-lib/README.md +52 -0
- package/templates/react-lib/eslint.config.js +5 -0
- package/templates/react-lib/gitignore +4 -0
- package/templates/react-lib/package.json +48 -0
- package/templates/react-lib/src/counter.tsx +28 -0
- package/templates/react-lib/src/index.ts +2 -0
- package/templates/react-lib/src/style.css +36 -0
- package/templates/react-lib/stylelint.config.js +3 -0
- package/templates/react-lib/test/counter.test.tsx +28 -0
- package/templates/react-lib/test-d/index.test-d.ts +11 -0
- package/templates/react-lib/tsconfig.app.json +15 -0
- package/templates/react-lib/tsconfig.build.json +12 -0
- package/templates/react-lib/tsconfig.json +4 -0
- package/templates/react-lib/tsconfig.node.json +11 -0
- package/templates/react-lib/vite.config.ts +22 -0
- package/templates/react-lib/vitest.config.ts +5 -0
- package/templates/react-vite/README.md +27 -0
- package/templates/react-vite/eslint.config.js +5 -0
- package/templates/react-vite/gitignore +6 -0
- package/templates/react-vite/index.html +13 -0
- package/templates/react-vite/package.json +36 -0
- package/templates/react-vite/src/app.tsx +22 -0
- package/templates/react-vite/src/main.tsx +15 -0
- package/templates/react-vite/src/style.css +95 -0
- package/templates/react-vite/stylelint.config.js +3 -0
- package/templates/react-vite/test/app.test.tsx +22 -0
- package/templates/react-vite/tsconfig.app.json +26 -0
- package/templates/react-vite/tsconfig.json +11 -0
- package/templates/react-vite/tsconfig.node.json +18 -0
- package/templates/react-vite/vite.config.ts +6 -0
- package/templates/react-vite/vitest.config.ts +9 -0
- package/templates/vitepress/.vitepress/navigation/routes.ts +7 -0
- package/templates/vitepress/reference/artifacts.md +51 -0
- package/templates/vitepress/reference/commands.md +149 -0
- package/templates/vitepress/reference/config.md +101 -7
- package/templates/vitepress/reference/dependencies.md +116 -0
- package/templates/vitepress/reference/dependency-admission.md +67 -0
- package/templates/vitepress/reference/devcontainer.md +25 -0
- package/templates/vitepress/reference/index.md +1 -0
- package/templates/vitepress/reference/install-security.md +51 -0
- package/templates/vitepress/reference/knip.md +55 -0
- package/templates/vitepress/reference/move.md +39 -0
- package/templates/vitepress/reference/organization-presets.md +89 -0
- package/templates/vitepress/reference/removal.md +42 -0
- package/templates/vitepress/reference/template-assets.md +39 -0
- package/templates/vitepress/reference/templates.md +372 -9
- package/templates/vitepress/start/diagnose.md +19 -2
- package/templates/vitepress/tasks/checks.md +149 -1
- package/templates/vitepress/tasks/ci.md +93 -1
- package/templates/vitepress/tasks/release.md +72 -6
- package/templates/vitepress/zh/reference/artifacts.md +51 -0
- package/templates/vitepress/zh/reference/commands.md +148 -0
- package/templates/vitepress/zh/reference/config.md +94 -2
- package/templates/vitepress/zh/reference/dependencies.md +116 -0
- package/templates/vitepress/zh/reference/dependency-admission.md +67 -0
- package/templates/vitepress/zh/reference/devcontainer.md +25 -0
- package/templates/vitepress/zh/reference/index.md +1 -0
- package/templates/vitepress/zh/reference/install-security.md +51 -0
- package/templates/vitepress/zh/reference/knip.md +55 -0
- package/templates/vitepress/zh/reference/move.md +39 -0
- package/templates/vitepress/zh/reference/organization-presets.md +89 -0
- package/templates/vitepress/zh/reference/removal.md +42 -0
- package/templates/vitepress/zh/reference/template-assets.md +19 -4
- package/templates/vitepress/zh/reference/templates.md +352 -9
- package/templates/vitepress/zh/start/diagnose.md +24 -13
- package/templates/vitepress/zh/tasks/checks.md +150 -0
- package/templates/vitepress/zh/tasks/ci.md +93 -1
- package/templates/vitepress/zh/tasks/release.md +72 -6
- package/templates/vue-lib/package.json +1 -1
|
@@ -81,6 +81,12 @@ repo verify staged-typecheck packages/ui/src/button.ts templates/client/src/App.
|
|
|
81
81
|
| 变更范围任务 | 按 workspace 改动范围补跑 `build`、`test`、`tsd` |
|
|
82
82
|
| 失败处理 | 任一任务失败时停止并返回失败状态 |
|
|
83
83
|
|
|
84
|
+
工作区默认从 `pnpm-workspace.yaml` 动态发现,包含 private 应用,遵循排除 glob;嵌套包按最长目录匹配,根包不会重复作为子包运行。每个包仅执行已有的 `build`、`test`、`tsd` 脚本。
|
|
85
|
+
|
|
86
|
+
删除文件仍会触发原所属包;文件跨包重命名时检查旧、新两个目录。根配置变化、已删除且无法归属的包清单会补跑根级 `build`、`test`、`tsd`。这是按文件归属选择,不会扩展反向依赖闭包。首次推送的 ref 与空树比较,删除 ref 不增加包级任务。
|
|
87
|
+
|
|
88
|
+
程序化 API 的 `workspaces` 参数继续支持覆盖自动发现,目录相对于 `cwd`,传入空数组也会生效;无需由调用方手动按目录深度排序。
|
|
89
|
+
|
|
84
90
|
如果 CI 想要更明确地复现整仓校验,可以使用:
|
|
85
91
|
|
|
86
92
|
```bash
|
|
@@ -110,3 +116,147 @@ repo check --edit-file .git/COMMIT_EDITMSG
|
|
|
110
116
|
| 推送前完整检查 | `repo check --full` |
|
|
111
117
|
| CI 门禁 | `repo doctor --strict` 后接 `repo check --full` |
|
|
112
118
|
| 只生成计划 | `repo check --json --out reports/check-plan.json` |
|
|
119
|
+
|
|
120
|
+
## 7. Affected 校验
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
repo check --affected --base origin/main --head HEAD --json
|
|
124
|
+
repo check --affected --base HEAD~1 --filter @acme/web --dry-run
|
|
125
|
+
repo check --affected --global-input 'shared-config/**'
|
|
126
|
+
repo check --affected --base origin/main --report reports/affected.json
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
affected 模式选择变更包及其直接、传递消费者,包含 private 应用。JSON schema version `1` 记录 Git 范围、文件归属、依赖路径、回退原因、包选择和任务跳过原因。可重复的 `--filter` 接受精确包名或 workspace 相对目录,与 affected 集合取交集。交集为空或缺少脚本时会明确说明,不会执行没有过滤条件的递归命令。
|
|
130
|
+
|
|
131
|
+
默认比较 `origin/main` 与 `HEAD` 的 merge base 到 `HEAD`,并纳入当前检出的暂存、未暂存和未跟踪文件。`--head` 必须指向当前 HEAD。引用缺失、浅克隆或历史不足、非当前 head、Git 不可用,以及 workspace 位于 Git 根目录下层时,都会明确全量回退。无法安全发现 workspace 时直接失败,不返回误导性的零影响计划。删除文件和跨包重命名两侧保留归属;包清单修改、新增或删除触发全量,因为依赖关系可能已经改变。
|
|
132
|
+
|
|
133
|
+
默认全局输入包括根 package/workspace/lock/Turbo 文件、TypeScript/lint/test/commit 配置、`.npmrc`、`.pnpmfile.*`、Node 版本文件、`.github/**`、`.husky/**`、`scripts/**` 和 `patches/**`。Turbo `globalDependencies` 与可重复的 `--global-input` glob 会追加到规则中。无法归属的未知文件也触发全量。根 Markdown、`docs/**` 和许可证/notice 文档默认忽略,但全局规则优先;workspace 包内文件仍属于该包输入。存在变更时,无法读取的 Turbo 配置或未解析图诊断(包括 catalog)也会保守全量回退。可在 JSON 的 `globalInputs`、`fallback` 中审查完整规则和原因。
|
|
134
|
+
|
|
135
|
+
执行顺序为 `build → lint → typecheck → tsd → test`,缺少脚本会跳过。pnpm recursive 接收精确计划过滤条件,由 pnpm 处理依赖顺序。build 还包含 affected/过滤集合以外的依赖,记录在 `prerequisiteTargets`,以便测试使用构建产物。全量回退优先执行对应根脚本;根脚本不存在时,改为运行全部选中包的对应脚本。显式过滤始终限制检查范围,包括回退时;build 前置依赖仍可能位于过滤集合之外。根脚本自行负责调用 Turbo/pnpm。
|
|
136
|
+
|
|
137
|
+
`--json`、`--markdown`、`--dry-run`、`--out` 仍然只预览。`--report` 执行同一模型并保存为 `affectedPlan`。`--affected` 不能与 `--full`、`--staged`、`--edit-file` 组合;base/head/filter/global-input 参数必须与 affected 模式一起使用。程序化调用可使用 `resolveAffectedCheckPlan({ cwd, base, head, filters, globalInputs })` 或 `runCheckWithReport({ cwd, affected: true, ... })`。
|
|
138
|
+
|
|
139
|
+
使用 `repo check --affected --matrix` 将同一计划导出为 GitHub Actions matrix,使用 `--shards 16` 分组。空结果处理和安全的参数数组执行方式见 [CI matrix 配置](/zh/tasks/ci#生成-affected-github-actions-matrix)。
|
|
140
|
+
|
|
141
|
+
## 8. 实际执行报告
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
repo check --full --report reports/check-result.json --redact
|
|
145
|
+
repo check --full --report reports/check-result.md --report-format markdown
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`--report <file>` 会执行检查,把结果写入独立文件,终端继续显示实时日志。不能与 `--dry-run`、`--json`、`--markdown`、`--out` 混用;这四个已有选项仍然只生成计划。执行报告默认使用 JSON。
|
|
149
|
+
|
|
150
|
+
JSON 的 `schemaVersion` 为 `1`,包含模式、目录、开始与结束时间、毫秒耗时、退出码,以及逐项的实际 executable 和 args。状态固定为 `success`、`failed`、`skipped`、`interrupted`,不随语言变化。失败后停止后续任务,未执行任务的时间和退出码保留 null,并记录跳过原因。CLI 保留失败退出码;操作系统允许正常处理 SIGINT/SIGTERM 时,中断也会落盘。SIGKILL、断电或报告目录不可写时无法保证保存。
|
|
151
|
+
|
|
152
|
+
报告记录根脚本或 verify 阶段,不展开 Turbo、lint-staged 内部任务。staged 模式的类型检查由 pre-commit 中的 lint-staged 配置执行,单独的 staged-typecheck 没有显式文件参数,会标记为 skipped。报告不收集环境变量值和子进程输出;`--redact` 会替换目录及命令参数中的 workspace/home 路径前缀。
|
|
153
|
+
|
|
154
|
+
程序化 API `runCheckWithReport({ cwd, full: true, signal })` 返回同样的报告,不退出调用方进程;可传入 `AbortSignal` 取消正在执行的命令。
|
|
155
|
+
|
|
156
|
+
## 查找工作区可用任务
|
|
157
|
+
|
|
158
|
+
`repo workspace tasks` 列出 package.json 中实际存在的脚本,默认包含根级任务和 private 应用;没有脚本的包会明确标出。查询文本按名称、路径、说明和任务名进行字面匹配,`--script` 要求脚本名完全一致。发现与定位均不执行脚本、不写入文件。
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
repo workspace tasks client
|
|
162
|
+
repo workspace tasks --script test --json
|
|
163
|
+
repo workspace tasks --no-private --no-root
|
|
164
|
+
repo workspace locate @scope/client
|
|
165
|
+
repo workspace locate client --json
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`locate` 将绝对目录路径(包括目录符号链接)作为精确查询,未指向工作区根目录的绝对路径不会回退成文本搜索。其他查询优先精确匹配包名或相对 workspace 的路径,再按名称、路径和说明搜索;即使从子包调用,相对路径和 `.` 仍相对于 workspace 根目录。唯一匹配只输出绝对路径;没有匹配或存在歧义时退出码为 1,并列出候选。`--interactive` 仅在 TTY 中允许选择,提示写入 stderr;JSON 和 CI 始终返回候选。把结果传给 shell 命令时应为路径加引号。
|
|
169
|
+
|
|
170
|
+
公共 `getWorkspaceTaskCatalog(cwd, options)` 和 `locateWorkspace(cwd, query)` API 返回 `schemaVersion: 1` 数据。目录提供稳定的排除原因,以及各任务原有脚本和 pnpm executable/args 数组(`--dir`、目录、`run`、任务名)。调用方可以显式执行该参数数组,继续使用 pnpm/Turbo 的行为;搜索本身不会启动任务。
|
|
171
|
+
|
|
172
|
+
## 逐包 Manifest 健康检查
|
|
173
|
+
|
|
174
|
+
`repo doctor` 按 pnpm workspace 匹配规则发现包,包含根包与 private 包,并逐个读取清单。一个 package.json 损坏时会生成独立诊断,其他包继续检查。兼容 pnpm 的 package.yaml 和 package.json5;同一目录存在多个清单时要求核查。每次 API 调用重新读取当前文件。
|
|
175
|
+
|
|
176
|
+
清单诊断复用 doctor 的 JSON、Markdown、`--strict` 和 `--redact` 输出,包含稳定的 `id`、相对工作区的 `path` 与字段 `field`。规则覆盖缺少/非法/重复包名、无效版本、依赖分区错误、缺失/歧义 workspace 目标、自依赖及重复/冲突声明。正常 peer/dev 和 peer/runtime 配对保留,peer 兼容检查独立处理。npm 允许 optionalDependencies 覆盖 dependencies,因此该重复仅警告。
|
|
177
|
+
|
|
178
|
+
不发布的应用应声明 `private: true`。公开包的 license、repository、repository.directory 和 publishConfig 建议只发出警告,不将推荐信息设为强制发布策略;strict 模式也会阻断警告。repository.directory 以 workspace 根目录比较,嵌套于其他 Git 仓库或单独托管的包需要人工核查。非法 JSON 中的值和 registry 凭据不会进入这些诊断。Doctor 不执行包脚本、不修改清单;实际 tarball 内容和类型消费兼容性由包交付检查负责。
|
|
179
|
+
|
|
180
|
+
## 内部依赖循环与架构边界
|
|
181
|
+
|
|
182
|
+
`repo workspace boundaries --json` 复用 manifest 依赖图,包含根包与 private 包。在 repoctl.config 中配置 `boundaries` 后,`repo doctor` 的 JSON/Markdown 和既有 CI 退出策略也会检查这些规则。独立命令在 fail 时退出 1,`--strict` 同时阻断 warn。不执行任务、不扫描源码 import、不改依赖、不检查第三方准入。
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
export default {
|
|
186
|
+
boundaries: {
|
|
187
|
+
tags: { shared: { paths: ['packages/**'] }, app: { paths: ['apps/**'] } },
|
|
188
|
+
rules: [
|
|
189
|
+
{ id: 'shared-layer', from: { tags: ['shared'] }, allow: [{ tags: ['shared'] }] },
|
|
190
|
+
{ id: 'public-packages', from: { private: false }, allow: [{ private: false }] },
|
|
191
|
+
],
|
|
192
|
+
cycles: { dependencyTypes: ['dependencies', 'optionalDependencies'], severity: 'fail' },
|
|
193
|
+
exceptions: [
|
|
194
|
+
{ rule: 'shared-layer', source: 'packages/adapter', target: 'apps/web', type: 'peerDependencies', reason: 'Temporary adapter during migration' },
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
选择器的不同字段取交集,同一字段的值取并集。`packages` 精确匹配包名;`paths` 只支持精确 workspace 目录(根为 `.`)或 `directory/**` 匹配后代,`./**` 匹配整个 workspace,不支持其他 glob。tag 是可重叠的命名选择器,不能递归引用 tag。规则的 `allow` 数组取并集,空数组明确禁止所有内部依赖,所有匹配的规则都生效。边界规则默认检查四类依赖;循环默认只检查 dependencies 和 optionalDependencies,可通过 dependencyTypes 纳入开发或 peer 边,`cycles: false` 关闭循环检查。semver 边仅表示潜在本地关系,不证明 lockfile 实际安装了本地包。
|
|
201
|
+
|
|
202
|
+
报告包含稳定规则 ID、manifest 字段、端点和具体边。每个存在环的强连通分量只报告一条稳定的闭合代表路径和完整成员列表,不枚举所有环。cycle 豁免只排除指定依赖类型的精确边,其余环仍检查;报告保留理由和已豁免的边。未知字段/tag、错误路径、重复 ID 或无理由豁免视为错误。无人匹配的选择器选项、失效豁免发出警告;内部依赖图无法完整解析时失败,不把未知关系判为健康。
|
|
203
|
+
|
|
204
|
+
公开 API `checkWorkspaceBoundaries(cwd, { config? })` 返回 schemaVersion 1、findings、exceptions 和 summary,显式 config 仅替换本次调用的项目配置。相对目录和规则 ID 不随输出语言变化。可把本命令或 `repo doctor --strict` 加入现有 pnpm CI 脚本,不增加任务执行层。
|
|
205
|
+
|
|
206
|
+
## 包负责人和 CODEOWNERS
|
|
207
|
+
|
|
208
|
+
在 `repoctl.config.ts` 中使用精确包名或工作区相对路径声明负责人:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
export default {
|
|
212
|
+
codeowners: { owners: { '@acme/web': ['@acme/frontend'], 'libraries/sdk': ['@maintainer'] } },
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`repoctl workspace owners [workspace] --json` 显示公有/私有包、负责人、配置来源和缺失归属。支持 GitHub 用户、团队及邮箱;本地只做文本校验,真实成员身份、访问和 review 权限由 GitHub 管理。
|
|
217
|
+
|
|
218
|
+
```sh
|
|
219
|
+
repoctl workspace owners --file .github/CODEOWNERS --dry-run
|
|
220
|
+
repoctl workspace owners --file .github/CODEOWNERS --sync
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
必须显式选择工作区根目录下的 `.github/CODEOWNERS`、`CODEOWNERS` 或 `docs/CODEOWNERS`。根包可以通过 `.` 或根包名配置,其 `*` 默认规则先于更具体的子包规则生成。默认只读预览;即使同时传入 `--sync`,`--dry-run` 仍不写入。受管块外的规则、注释及顺序逐字保留。GitHub 使用最后匹配规则,后续可能覆盖包目录或子路径的规则(含无 owner 规则)会得到诊断;更高优先级的 CODEOWNERS 文件也会提示。无法安全表达的目录字符和非法映射会阻止同步。
|
|
224
|
+
|
|
225
|
+
公开 `planCodeowners()` / `applyCodeownersPlan()` 提供前后内容和 diff;应用时重新校验配置、工作区发现和文件内容,过期计划会被拒绝。单文件原子替换、拒绝符号链接和硬链接目标,重跑不产生额外变更。不发送消息、不请求 review、不修改权限或分支保护。
|
|
226
|
+
安装策略:参见 [pnpm 安装安全](../reference/install-security.md),检查版本冷却、信任降级和构建批准,并预览可选策略。
|
|
227
|
+
|
|
228
|
+
## 受管资产升级 PR
|
|
229
|
+
|
|
230
|
+
可信默认分支更新依赖后,运行 `repo maintenance upgrade --base <升级前完整SHA> --head <当前完整SHA> --out <仓库外空目录>`,比较 pnpm 锁文件中**根依赖** `repoctl` 的精确解析版本。支持 pnpm 12 独立的包管理器文档;无关依赖和 peer 上下文变化不会触发升级;不支持或有歧义的解析会阻断。目标版本必须已通过 frozen lockfile 安装。直接配置且精确锁定的[组织预设](../reference/organization-presets.md#维护升级-pr)变化也可触发现有受管资产维护。导出的工作流固化包名、源路径和目标路径授权;新文件须显式采用并审阅工作流更新。
|
|
231
|
+
|
|
232
|
+
准备步骤应在一次性干净 checkout 中运行:应用完整根资产计划和三方合并,由 pnpm 更新锁文件,再执行 `--frozen-lockfile --ignore-scripts` 安装,随后按 build、lint、typecheck、tsd、test 顺序执行已声明的根脚本。生成的变更保留在该 checkout。冲突、源码漂移、不支持的路径和校验失败会留下 `blocked` 报告及日志;没有资产 diff 时为 `unchanged`,这两种状态均不创建 PR。报告包含逐文件计划、跳过/冲突项、来源/目标版本、检查结果、精确文件哈希与模式、补丁摘要。
|
|
233
|
+
|
|
234
|
+
报告中的文件哈希针对精确的 Git blob 字节。准备阶段仍校验计划中的工作区文件原始字节;发布验证补丁索引及与其 Git 语义等价的工作区内容,允许 Git 内建的换行转换。隔离发布目录在检查文件前禁用 hooks、可执行的 clean/smudge/process 过滤器和文件系统监视器,并将这些设置保留至创建 PR。 预设报告同时记录原始前置字节与受限的换行配置,由 Git 内建转换关联到提交与补丁 blob;固定来源、已有所有权和计划字节检查仍须通过。 原始字节按 HEAD 属性验证,结果字节按已授权补丁的新属性验证,支持预设更新 .gitattributes。补丁与报告路径不一致会在应用前拒绝;最终计划校验也可能在临时目录应用后拒绝,仍不会获取写凭据。
|
|
235
|
+
|
|
236
|
+
自动维护支持完成内建 Changesets 迁移,并仅为它授权确切的 `.repoctl/migrations/ledger.json` 元数据路径。准备和发布共用固定迁移身份、已提交旧格式来源、执行日志与完成记录校验;目标模板版本沿已提交锁文件中的根 repoctl → monorepo → templates 依赖链确定,不能把 repoctl 版本当作模板版本。发布端将每个迁移输出关联到已验证的 Git 补丁,并根据已提交的工作区成员校验公开包预发布 lane。中断日志、有歧义的锁文件、非规范工作区模式及 YAML/JSON5 工作区清单需要先审阅并手工执行 `repo upgrade`,不会扩大其他 `.repoctl` 路径权限。采用此策略前需更新并审阅导出的可信工作流。
|
|
237
|
+
|
|
238
|
+
自动维护支持完成内建 Changesets 迁移,并仅为它授权确切的 `.repoctl/migrations/ledger.json` 元数据路径。准备和发布共用固定迁移身份、已提交旧格式来源、执行日志与完成记录校验;目标模板版本沿已提交锁文件中的根 repoctl → monorepo → templates 依赖链确定,不能把 repoctl 版本当作模板版本。发布端将每个迁移输出关联到已验证的 Git 补丁,并根据已提交的工作区成员校验公开包预发布 lane。中断日志、有歧义的锁文件、非规范工作区模式及 YAML/JSON5 工作区清单需要先审阅并手工执行 `repo upgrade`,不会扩大其他 `.repoctl` 路径权限。采用此策略前需更新并审阅导出的可信工作流。
|
|
239
|
+
|
|
240
|
+
通过 `repo maintenance workflow --out .github/workflows/repoctl-upgrade.yml` 导出需主动启用的工作流,已有文件不会被覆盖。配置仓库 GitHub App 的 `REPOCTL_APP_CLIENT_ID`、`REPOCTL_APP_PRIVATE_KEY`,授予 **Contents、Pull requests、Workflows 写权限**,随后提交工作流。Workflows 权限用于更新受管工作流;App token 也能让新 PR 正常触发 CI。不需要 registry token。
|
|
241
|
+
|
|
242
|
+
第一个 job 仅有读取权限,可以运行可信 checkout 的配置、依赖和检查脚本,上传不可变产物。第二个 job 只下载精确 artifact ID,核验摘要、本次 run/attempt/仓库、源码 SHA、根资产路径、Git 文件模式和前后哈希,然后应用已审核补丁。它不执行项目脚本或已安装依赖,校验完成后才获取 App token,通过固定 SHA 的 `create-pull-request` action 管理专用 `repoctl/managed-assets` 分支。重复事件更新同一分支和 PR,请勿在该分支维护手工修改。默认分支推进或 App 权限缺失/不足会阻止发布;完整报告仍保留在 workflow artifact 中。
|
|
243
|
+
|
|
244
|
+
仅支持默认分支上触及 `pnpm-lock.yaml` 的 push,以及在默认分支显式手工运行;重试时填写依赖升级前的完整可信祖先 SHA。并发按仓库/默认分支串行。不处理 fork PR 事件,不自动合并或发布 npm 包,也不扩展为任意依赖机器人、组织资产提供者或模板实例升级器。
|
|
245
|
+
|
|
246
|
+
## 诊断 Turbo 缓存未命中与慢任务
|
|
247
|
+
|
|
248
|
+
通过 Turbo 既有的 `pnpm exec turbo run build --summarize` 保存证据,再显式选择摘要文件分析。分析命令不启动任务、不删除缓存、不修改配置:
|
|
249
|
+
|
|
250
|
+
```sh
|
|
251
|
+
repo check cache .turbo/runs/current.json
|
|
252
|
+
repo check cache .turbo/runs/current.json .turbo/runs/previous.json --json
|
|
253
|
+
repo check cache current.json previous.json --markdown > cache-analysis.md
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
`--slowest 10` 支持 1–100 个慢任务。JSON schemaVersion 为 1,包含已知命中、未命中、未知缓存结果,以已知结果为分母计算命中率;记录实际任务耗时、耗时差异,按稳定 task ID 比较并标明新增与删除。缺失/重复 ID、缺失字段和不支持的摘要 schema 都会报告限制,不把信息缺失解释为输入已被删除。支持原生 Turbo summary schema 1,并包含真实 Turbo 2.11.6 fixture;未来 schema 仅保留可读取的粗粒度记录,比较结果标为 unknown。
|
|
257
|
+
|
|
258
|
+
共享全局差异只在 `globalEvidence` 保存一次,任务仅保留自身证据,避免报告随任务数与全局文件数相乘膨胀。比较证据覆盖文件、全局输入、依赖任务 hash、环境声明/值、命令/参数及最终任务配置。所有值(包括输入中的 hash)先转为 SHA-256 摘要再输出,标签仅保留任务 ID、文件名、环境变量名和允许的字段名;不输出原始环境值、命令或任意配置。摘要相同只表示证据相同,不足以断定未命中的唯一原因;hash 不变仍未命中、hash 变化却无细节证据时都有明确限制。报告不包含输入摘要路径。
|
|
259
|
+
|
|
260
|
+
只有任务标识唯一、依赖完整、时间有效、图无环且前置任务没有与消费者执行重叠时才计算关键路径。任务耗时之和与实测跨度分开呈现,调度空隙和竞争等开销意味着它不等于可节省的实际运行时间。输入限 20 MiB JSON 文件、嵌套深度 64。分析只读,可重定向 stdout 留档;拒绝父命令的执行和计划写入选项(`--full`、`--affected`、`--report`、`--out` 等)。`--json`、`--markdown`、`--dry-run` 可以放在 `cache` 前后;普通 `check --json` 保持计划预览语义。
|
|
261
|
+
|
|
262
|
+
公开 API `analyzeTurboRuns(currentPath, { previous?: string, slowest?: number })` 返回 `TurboRunAnalysis`,不修改文件。JSON 字段和限制代码不随语言变化。
|
|
@@ -24,7 +24,7 @@ CI 会得到稳定的计划,并可以把 JSON 或 Markdown 报告作为 artifa
|
|
|
24
24
|
|
|
25
25
|
- pull request 需要快速门禁:使用 `repo check --staged` 或仓库的 pre-commit 模式。
|
|
26
26
|
- main 分支需要完整门禁:使用 `repo check --full`。
|
|
27
|
-
- 发布 job 需要版本计划:发布前执行 `repo release --
|
|
27
|
+
- 发布 job 需要版本计划:发布前执行 `repo release plan --json`。
|
|
28
28
|
|
|
29
29
|
repoctl 的命令可以分成两类:给人用的日常入口,以及给 CI、脚本、编辑器用的可保存输出。
|
|
30
30
|
|
|
@@ -136,6 +136,98 @@ repo ws ls --json --out reports/workspaces.json
|
|
|
136
136
|
| 输出给脚本 | `--json --out <file>` |
|
|
137
137
|
| 输出给人看并脱敏 | `--markdown --redact --out <file>` |
|
|
138
138
|
|
|
139
|
+
## 生成 affected GitHub Actions matrix
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pnpm exec repo check --affected --base origin/main --matrix
|
|
143
|
+
pnpm exec repo check --affected --base origin/main --filter @scope/web --matrix
|
|
144
|
+
pnpm exec repo check --affected --base origin/main --matrix --shards 16 --out reports/matrix.json
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`--matrix` 始终以 JSON 预览,不执行检查,不创建或修改 workflow;只有显式 `--out` 会写出报告。它要求 `--affected`,复用相同的 `--base`、`--head`、可重复的 `--filter` 和 `--global-input`,不能与 `--markdown` 或执行报告选项组合。matrix 本身已经是 JSON 预览,因此 `--json`、`--dry-run` 可省略。
|
|
148
|
+
|
|
149
|
+
公共 `resolveAffectedCheckMatrix(options)` API 返回 `schemaVersion: 1`、`provider: "github-actions"`、`hasWork`、`grouping`、`summary`、`matrix: { include: [...] }` 和完整 `affectedPlan`。内嵌计划与相同输入的 `resolveAffectedCheckPlan` 一致,保留选择原因、Git 诊断和跳过阶段。**仅将 `matrix` 传给 `fromJSON`**,并在 strategy 展开之前用 `hasWork` 控制 job;无变更或没有可执行阶段时返回 `hasWork: false`、`include: []`。
|
|
150
|
+
|
|
151
|
+
每个矩阵项包含稳定 `id`、相对 workspace 的 `packages`,以及按顺序排列的 `commands`;命令保留 `executable`/`args`、`targets`、`prerequisiteTargets` 和 `skipReason`。在新 checkout 的根目录执行参数数组,展示用的 `command` 字符串不应用于 shell 求值。每个 job 内始终完整运行 **build → lint → typecheck → tsd → test**,其 build 还包含内部依赖,消费者无需等待其他矩阵 job 的构建产物。缺失脚本仍有明确原因;没有可执行命令的组列在 `summary.skippedPackages`。
|
|
152
|
+
|
|
153
|
+
默认每个选中的 workspace 对应一个 job。`--shards N`(1–256)先按包目录排序,再循环分配到最多 N 组,不丢弃任何包。超过 GitHub 的 256-job 上限时会明确报错,并提示使用 `--shards 256` 或更少。序列化后的 matrix 还会按 UTF-16 估算检查 1 MB job-output 上限,并为元数据预留少量空间。超限时明确失败,不截断目标;减少分片可以避免重复的依赖构建数据。所有全量回退都保留为**一个完整 job**,即使设置了 `--shards`,以保留根脚本并保守处理不确定的依赖图。Git 基线缺失或引用无效时,沿用 affected 的全量回退,并保留明确的诊断码,不会变成成功的空矩阵。
|
|
154
|
+
|
|
155
|
+
以下示例拉取完整 Git 历史,使用 PR 的 base SHA。每个 job 检出同一事件提交并按相同 lockfile 安装依赖,只需 `contents: read` 权限。pnpm store 缓存不会替代 job 自身的依赖构建,任务排序和缓存仍由已有 pnpm/Turbo 脚本负责。示例面向 Linux,通过环境变量传递矩阵数据,再执行参数数组,因此含空格、引号或 shell 语法的路径仍只是数据。
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
name: Affected checks
|
|
159
|
+
on: pull_request
|
|
160
|
+
permissions:
|
|
161
|
+
contents: read
|
|
162
|
+
jobs:
|
|
163
|
+
plan:
|
|
164
|
+
runs-on: ubuntu-latest
|
|
165
|
+
outputs:
|
|
166
|
+
matrix: ${{ steps.matrix.outputs.matrix }}
|
|
167
|
+
has-work: ${{ steps.matrix.outputs.has-work }}
|
|
168
|
+
steps:
|
|
169
|
+
- uses: actions/checkout@v7
|
|
170
|
+
with:
|
|
171
|
+
fetch-depth: 0
|
|
172
|
+
- uses: pnpm/action-setup@v6
|
|
173
|
+
- uses: actions/setup-node@v7
|
|
174
|
+
with:
|
|
175
|
+
node-version: 22
|
|
176
|
+
cache: pnpm
|
|
177
|
+
- run: pnpm install --frozen-lockfile
|
|
178
|
+
- id: matrix
|
|
179
|
+
env:
|
|
180
|
+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
181
|
+
run: |
|
|
182
|
+
node --input-type=module <<'JS'
|
|
183
|
+
import { appendFileSync } from 'node:fs'
|
|
184
|
+
import { resolveAffectedCheckMatrix } from 'repoctl'
|
|
185
|
+
const result = await resolveAffectedCheckMatrix({
|
|
186
|
+
cwd: process.cwd(), base: process.env.BASE_SHA, head: 'HEAD', shards: 16,
|
|
187
|
+
})
|
|
188
|
+
appendFileSync(process.env.GITHUB_OUTPUT,
|
|
189
|
+
`has-work=${result.hasWork}\nmatrix=${JSON.stringify(result.matrix)}\n`)
|
|
190
|
+
if (result.affectedPlan.fallback.length) {
|
|
191
|
+
console.error('Full fallback:', JSON.stringify(result.affectedPlan.fallback))
|
|
192
|
+
}
|
|
193
|
+
JS
|
|
194
|
+
checks:
|
|
195
|
+
needs: plan
|
|
196
|
+
if: ${{ needs.plan.outputs.has-work == 'true' }}
|
|
197
|
+
runs-on: ubuntu-latest
|
|
198
|
+
strategy:
|
|
199
|
+
fail-fast: false
|
|
200
|
+
matrix: ${{ fromJSON(needs.plan.outputs.matrix) }}
|
|
201
|
+
steps:
|
|
202
|
+
- uses: actions/checkout@v7
|
|
203
|
+
with:
|
|
204
|
+
fetch-depth: 0
|
|
205
|
+
- uses: pnpm/action-setup@v6
|
|
206
|
+
- uses: actions/setup-node@v7
|
|
207
|
+
with:
|
|
208
|
+
node-version: 22
|
|
209
|
+
cache: pnpm
|
|
210
|
+
- run: pnpm install --frozen-lockfile
|
|
211
|
+
- name: Run this job's planned stages
|
|
212
|
+
env:
|
|
213
|
+
MATRIX_JOB: ${{ toJSON(matrix) }}
|
|
214
|
+
run: |
|
|
215
|
+
node --input-type=module <<'JS'
|
|
216
|
+
import { spawnSync } from 'node:child_process'
|
|
217
|
+
const job = JSON.parse(process.env.MATRIX_JOB)
|
|
218
|
+
for (const command of job.commands) {
|
|
219
|
+
if (command.skipReason) continue
|
|
220
|
+
const result = spawnSync(command.executable, command.args, {
|
|
221
|
+
stdio: 'inherit', shell: false,
|
|
222
|
+
})
|
|
223
|
+
if (result.error) throw result.error
|
|
224
|
+
if (result.status !== 0) process.exit(result.status ?? 1)
|
|
225
|
+
}
|
|
226
|
+
JS
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
计划步骤使用 API,避免在选择前生成未跟踪的报告。使用 `--out` 时,应写入已忽略的报告目录。生成 matrix 不会修改或触发远程 workflow。参见 [GitHub matrix 语法](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/run-job-variations) 和 [Turborepo 任务执行](https://turborepo.dev/docs/reference/run)。
|
|
230
|
+
|
|
139
231
|
## 文档 Worker
|
|
140
232
|
|
|
141
233
|
repoctl 文档通过名为 `repoctl-docs` 的 Cloudflare Worker 部署。VitePress 只生成静态资产,Workers Static Assets 直接提供这些文件,因此不需要应用 handler,也不声明 `ASSETS` binding。
|
|
@@ -11,14 +11,57 @@
|
|
|
11
11
|
## 最小命令
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
repo release --
|
|
14
|
+
repo release plan --markdown
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
检查当前/目标版本、直接 intent、pnpm 原生依赖传播及固定组原因、lane、私有包、发布候选和发布说明预览。机器读取使用 `repo release plan --json`,结构版本为 `schemaVersion: 1`,状态为 `ready`、`empty` 或 `blocked`。阻断时退出码为 1,并提供稳定的 blocker ID。
|
|
18
|
+
|
|
19
|
+
版本决策委托给 pnpm 递归 dry-run(已验证 pnpm 12.8.1)。计划不消费 intents,不修改 manifest、changelog、ledger 或 Git 状态,不安装或激活 pnpm,不执行版本、发布或 pnpmfile hooks,也不写入 registry。未安装支持的 pnpm 时请先显式安装。可能改写准备输入的 hooks 不会执行;需要这些改动时先显式完成,再重新生成计划。
|
|
20
|
+
|
|
21
|
+
审查完成后使用独立入口 `repo release ci --mode=prepare` 准备版本。已有版本的发布或恢复预览使用 `repo release ci --mode=publish --dry-run`。版本计划描述待消费 intents,不检查 registry 认证,也不代表发布一定成功。
|
|
18
22
|
|
|
19
23
|
## 预期结果
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
JSON 与 Markdown 表达相同的原生版本决策。说明条目复用已有发布 renderer,并排除已消费的 intent 条目。私有包可以升级版本,但标记为非发布候选。公共 `createReleasePlan({ cwd })` API 返回同一报告,不自行写入文件。
|
|
26
|
+
|
|
27
|
+
计划、自动触发和版本准备统一识别根包与私有包的 intent,由 pnpm 在完整工作区内计算版本传播。Release PR 只为可发布的子包生成说明,并要求这些包具有对应版本的 changelog;根包或私有包缺少 changelog 不会阻断准备。根包即使未标记为 private,也不属于发布候选。不希望某个工作区包参与版本计算时,应配置 pnpm 的 `versioning.ignore`,不要只在实际写版本时改变工作区发现范围。
|
|
28
|
+
|
|
29
|
+
## 正式分支与维护版本线
|
|
30
|
+
|
|
31
|
+
在 `repoctl.config.*` 中配置 `commands.release.branches`:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
export default {
|
|
35
|
+
commands: {
|
|
36
|
+
release: {
|
|
37
|
+
branches: {
|
|
38
|
+
stable: 'master',
|
|
39
|
+
maintenance: [{ branch: '1.x', range: '1.x', tag: 'legacy-1' }],
|
|
40
|
+
prerelease: [
|
|
41
|
+
{ branch: 'preview/1.x', lane: 'beta', tag: 'legacy-beta', target: '1.x' },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
省略配置保留 `main` 和 `alpha`、`beta`、`rc`、`next`。`stable` 默认是 `main`;省略 `prerelease` 时保留这四个 lane,并指向正式分支;显式 `prerelease: []` 可禁用预发布。正式分支与维护分支都使用 pnpm 原生 `main` lane;Git 分支名和 npm 标签分别配置。
|
|
50
|
+
|
|
51
|
+
维护范围必须有有限上界,彼此不能重叠。主正式分支负责所有维护范围以外的版本。范围约束整个仓库的可发布包;各包采用独立主版本时,也需要共同满足所选发布线。私有包仍参与 pnpm 原生版本计算,但不作为发布候选。分支名、npm 标签、预发布 lane 必须唯一。`1.x` 这类 SemVer 范围不能作为 npm 标签,示例使用 `legacy-1`;`snapshot-` 前缀保留给临时包。
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
repo release plan --branch 1.x --markdown
|
|
55
|
+
repo release plan --branch master --json
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
计划增加 `branchRule`,包含 `branch`、`kind`、`lane`、`range`、`excludedRanges`、`distTag` 和 `target`。显式 `--branch` 或 API `branch` 优先,其次使用匹配的 `GITHUB_REF_NAME`;其他情况的只读计划以主正式分支为目标。执行则使用当前 Git 分支或 CI ref,未配置的分支会被拒绝。API `resolveReleaseBranches(config)` 返回同一份已校验映射。
|
|
59
|
+
|
|
60
|
+
准备前先用 pnpm 原生 dry-run 检查范围,越界时在执行发布 hooks、写版本、消费 intents 之前停止;校验 hooks 完成后再检查一次。实际写入版本及最终发布候选也会复核,hook 改写版本后仍须满足所选发布线。repoctl 无法撤销任意 hook 的外部副作用;准备或发布中断后继续使用 pnpm ledger 和现有发布检查点恢复。
|
|
61
|
+
|
|
62
|
+
Release PR 以所选分支为 base。主正式线保留 `release/pnpm-version`;维护线使用 `release/pnpm-version-<编码后的分支名>`,可同时存在。维护发布只使用自己的 dist-tag,GitHub Release 仍标记为正式版本。`repo release pre enter beta` 选择声明的 pnpm lane;`repo release pre exit` 回到目标的原生 `main` lane,并输出正式或维护目标分支,不切换 Git 分支。
|
|
63
|
+
|
|
64
|
+
修改映射后,先用 `repo upgrade --dry-run --json` 审查,再应用升级,同步受管 Release 工作流的 push 分支。保存的计划会检测配置变化;重复升级无新差异;自定义工作流仍受保护,除非显式要求替换。workflow dispatch 和原提交恢复应在目标配置分支运行,发布工作流保持串行,并保留检查点。
|
|
22
65
|
|
|
23
66
|
## 常见分支
|
|
24
67
|
|
|
@@ -47,6 +90,8 @@ repo release --dry-run
|
|
|
47
90
|
|
|
48
91
|
重跑会读取远端检查点,核对 registry 和 GitHub,只补齐缺失阶段,不重新上传已接收的版本,也不重复已完成的 hook。预发布在上传前先推送版本提交,确保新 runner 能检出原版本。新发布从完整 Git 历史确定版本来源(checkout 必须 `fetch-depth: 0`);恢复时还会核对原提交的 manifest 和 changelog。若后续提交修改了 changelog,请检出提示的原提交后恢复。
|
|
49
92
|
|
|
93
|
+
如果 `.changeset/ledger.yaml` 已记录该包版本,以记录首次进入 Git 第一父提交历史的位置确定发布来源,包括沿用初始版本号的首次发布。普通合并对应主线上的合并提交。没有账本记录的版本(例如依赖传播升级)则沿同一条第一父提交历史回退到 manifest 的版本引入提交。尚未提交的账本记录不能建立发布来源。相对来源提交新增或删除 changelog 也会被拒绝;只有来源和当前工作区都不存在该文件时才允许缺失。
|
|
94
|
+
|
|
50
95
|
旧版发布没有检查点时,可从 npm 的 `gitHead` 恢复原提交。缺失该字段时必须人工核对来源后显式设置 `REPO_RELEASE_SOURCE_SHA`,不能使用重跑 HEAD 猜测。所有目标已有 Release 的历史任务保持 no-op,不倒推重放历史 hook。无记录且缺失元数据的历史任务中,hook 结果按未知处理。
|
|
51
96
|
|
|
52
97
|
```bash
|
|
@@ -79,15 +124,36 @@ const hook = { script: 'publish:extension', idempotent: true }
|
|
|
79
124
|
已有版本尚未完成发布时,新的版本准备会在消费 intent 前失败,并给出原始提交和恢复命令。先恢复旧发布,再准备新版本:
|
|
80
125
|
|
|
81
126
|
```bash
|
|
82
|
-
repo release ci --mode publish --source-sha
|
|
83
|
-
repo release ci --mode publish --source-sha
|
|
127
|
+
repo release ci --mode publish --source-sha <完整的发布线提交-SHA> --dry-run
|
|
128
|
+
repo release ci --mode publish --source-sha <完整的发布线提交-SHA>
|
|
84
129
|
repo release ci --mode prepare
|
|
85
130
|
```
|
|
86
131
|
|
|
87
|
-
受管 Release 工作流为 `publish` 和 `publish-unpublished` 提供相同的 `source-sha` 输入。当前工具会在独立目录检出原提交,按照其锁文件安装、构建和验证,恢复该提交 manifest 或 ledger 新增的整批版本,包括依赖传播升级的包。package/version 输入只校验是否属于该批发布,不拆分原发布批次。SHA 必须属于 `origin
|
|
132
|
+
受管 Release 工作流为 `publish` 和 `publish-unpublished` 提供相同的 `source-sha` 输入。当前工具会在独立目录检出原提交,按照其锁文件安装、构建和验证,恢复该提交 manifest 或 ledger 新增的整批版本,包括依赖传播升级的包。package/version 输入只校验是否属于该批发布,不拆分原发布批次。SHA 必须属于 `origin/<所选分支>` 历史;以当前调度配置确定发布线,历史源码中的旧映射不会改变目标。dry-run 只检查源码与远端状态,不安装、不上传、不运行 hook、不写检查点。后续变更保留到下一版本;恢复过程中不修改版本号。
|
|
88
133
|
|
|
89
134
|
恢复保留 GitHub 工作流环境,供可信发布和 provenance 使用:签名身份对应运行工作流的提交;独立检出的源码、发布检查点、Git tag 和 Release 目标则对应 `source-sha`。不要通过覆盖 `GITHUB_SHA` 恢复旧源码,npm 会拒绝与工作流签名身份不一致的 provenance。
|
|
90
135
|
|
|
91
136
|
## 下一步
|
|
92
137
|
|
|
93
138
|
阅读[发包与变更日志](/zh/learn/monorepo/publish),再查看[报告与输出](/zh/tasks/reports)了解 CI 产物。
|
|
139
|
+
|
|
140
|
+
## PR 与 nightly 临时包
|
|
141
|
+
|
|
142
|
+
需要在正式发布前让下游验证时,先提交源码,再预览全部公开工作区包:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
repo release snapshot --kind pr --pr 123 --commit <完整-HEAD-SHA> --build-id <run-id>-<attempt> --dry-run --json
|
|
146
|
+
repo release snapshot --kind nightly --commit <完整-HEAD-SHA> --build-id <run-id>-<attempt> --output /tmp/repoctl-artifacts
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
候选解释与基础版本复用 pnpm 原生发布计划,全部公开包共同生成快照。临时版本包含完整源码 SHA 和 PR/nightly 构建身份的确定性摘要;目标 tag 固定为 `snapshot-pr-<编号>` 或 `snapshot-nightly`,没有指定正式 tag 的入口。只在恢复同一源码、同一产物时复用 build identity。报告提供精确版本的 `pnpm add` 安装命令。
|
|
150
|
+
|
|
151
|
+
CLI 和 API 的快照计划均不加载或执行 `repoctl.config.*`,仅根据已提交的 pnpm 元数据生成计划,独立于正式发布配置。普通发布命令仍在执行前校验配置。
|
|
152
|
+
|
|
153
|
+
不带 `--publish` 时只准备可安装 tarball。流程在仓库以外提取已提交 HEAD,使用 frozen lockfile 安装依赖,改写内部引用为精确快照版本,执行根 `build`,再通过 publint、Are the Types Wrong 与隔离消费者验证真实产物。成功、失败或中断都不回写原仓库清单、intents、ledger、changelog 或 Git refs。成功与失败均保留报告目录下的 `snapshot-report.json`、tarball 和消费者诊断。强制中断可能留下未完成的临时目录;用相同身份重跑会核验 registry 证据。当前拒绝源码符号链接、Git submodule 和 `publishConfig.directory`;要求根 build 脚本与 frozen lockfile。
|
|
154
|
+
|
|
155
|
+
仅在显式授权的 GitHub Actions job 中使用 `--publish` 并设置 `REPOCTL_SNAPSHOT_PUBLISH=1`。`GITHUB_SHA` 必须与请求提交一致,event 仓库必须匹配 `GITHUB_REPOSITORY`。PR 仅允许同仓库 `pull_request`,拒绝 fork 与 `pull_request_target`;nightly 仅允许 `schedule` 或 `workflow_dispatch`。fork job 只准备产物,凭据限定在可信发布 job。现有 stable 与 prerelease workflow 不会被修改。
|
|
156
|
+
|
|
157
|
+
默认发布到公共 npm;`--registry <https-url>` 可显式指定其他 registry(只有本地测试 registry 允许 HTTP)。上传复用现有有界重试与恢复适配,不创建 GitHub Release 或 Git tag。重复身份先比较精确版本元数据与 tarball 的 SHA-512 完整性再跳过上传;状态未知或内容冲突会停止。源码产物发生变化或构建无法复现时使用新的 `--build-id`。
|
|
158
|
+
|
|
159
|
+
公开 API 为 `createSnapshotPlan(options)` 与 `releaseSnapshot(options)`。两者均返回 `schemaVersion: 1`、原生计划、快照身份、候选、精确版本、目标 tag 与安装说明;后者追加保留产物和校验结果。准备失败返回 `status: failed` 与 `error`,CLI 以退出码 1 结束。
|