@icebreakers/monorepo-templates 2.0.5 → 2.0.7
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/.github/workflows/release.yml +6 -0
- package/assets/gitignore +2 -0
- package/assets/package.json +1 -1
- package/package.json +1 -1
- package/templates/cli/dev/index.ts +0 -0
- package/templates/vitepress/tasks/release.md +42 -1
- package/templates/vitepress/zh/learn/monorepo/publish.md +1 -1
- package/templates/vitepress/zh/learn/tools/changeset.md +1 -1
- package/templates/vitepress/zh/tasks/release.md +48 -1
|
@@ -35,6 +35,10 @@ on:
|
|
|
35
35
|
required: false
|
|
36
36
|
default: false
|
|
37
37
|
type: boolean
|
|
38
|
+
source-sha:
|
|
39
|
+
description: Original main commit to recover (publish modes only)
|
|
40
|
+
required: false
|
|
41
|
+
type: string
|
|
38
42
|
|
|
39
43
|
env:
|
|
40
44
|
HUSKY: 0
|
|
@@ -104,6 +108,7 @@ jobs:
|
|
|
104
108
|
REPO_RELEASE_PACKAGE: ${{ inputs.package }}
|
|
105
109
|
REPO_RELEASE_VERSION: ${{ inputs.version }}
|
|
106
110
|
REPO_RELEASE_DRY_RUN: ${{ inputs.dry-run }}
|
|
111
|
+
REPO_RELEASE_RECOVERY_SOURCE_SHA: ${{ inputs.source-sha }}
|
|
107
112
|
run: pnpm exec repo release ci
|
|
108
113
|
|
|
109
114
|
- name: Preserve npm publish progress
|
|
@@ -114,5 +119,6 @@ jobs:
|
|
|
114
119
|
path: |
|
|
115
120
|
pnpm-publish-summary.json
|
|
116
121
|
repoctl-publish-progress.json
|
|
122
|
+
repoctl-release-progress.json
|
|
117
123
|
if-no-files-found: ignore
|
|
118
124
|
retention-days: 14
|
package/assets/gitignore
CHANGED
package/assets/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"type": "module",
|
|
4
4
|
"version": "0.0.0",
|
|
5
5
|
"private": true,
|
|
6
|
-
"packageManager": "pnpm@12.
|
|
6
|
+
"packageManager": "pnpm@12.8.1",
|
|
7
7
|
"description": "Source workspace for repoctl and Icebreaker's shared development packages",
|
|
8
8
|
"author": "ice breaker <hi@sonofmagic.top>",
|
|
9
9
|
"license": "MIT",
|
package/package.json
CHANGED
|
File without changes
|
|
@@ -39,7 +39,48 @@ Two files remain in the workspace root:
|
|
|
39
39
|
|
|
40
40
|
The managed Release workflow uploads both files as `npm-publish-progress-<run_id>-<run_attempt>` on success or failure, retained for 14 days. Missing reports are ignored. After upgrading repoctl, run `repo upgrade` to refresh managed workflows; custom workflows can add the same upload step.
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
## Recovery across runners
|
|
43
|
+
|
|
44
|
+
`repo release ci --mode=publish` tracks release targets separately from new npm uploads. Before uploading, the built-in GitHub client writes exact versions, original commits, accepted-upload evidence, metadata progress, and individual hook states to the repository's `repoctl-release-state` branch. The key includes repository, dist-tag, and candidate versions. Writes compare the file SHA to reject concurrent changes. Keep this branch, grant `contents: write`, and serialize all workflows that publish the same packages.
|
|
45
|
+
|
|
46
|
+
`repoctl-release-progress.json` is an archived diagnostic copy. Its `complete: true` requires npm version/dist-tag visibility, tags pointing to the original commits, published GitHub Releases, and all required hooks. The older npm progress file only describes the npm stage.
|
|
47
|
+
|
|
48
|
+
Reruns query the registry and GitHub and finish missing stages without reuploading accepted versions or repeating completed hooks. Prereleases push the version commit before uploading. Source discovery requires complete Git history (`fetch-depth: 0`), and recovery checks the original manifest and changelog. If a later commit changed the changelog, check out the reported original commit before recovery.
|
|
49
|
+
|
|
50
|
+
Legacy releases without a checkpoint use npm `gitHead`; if absent, verify the source manually and set `REPO_RELEASE_SOURCE_SHA`. Never substitute the rerun HEAD. Historical targets with existing Releases remain no-ops. Hooks for legacy targets with missing metadata have unknown outcomes.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
repo release ci --mode=publish --dry-run
|
|
54
|
+
repo release ci --mode=publish
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Dry-run queries remote state and shows versions, original commits, npm stage, missing tags/Releases, and hook states without uploads, hooks, or checkpoint writes. Unknown registry states fail after bounded retries. Tag conflicts and unknown source commits fail without moving tags. GitHub requests have a 30-second timeout and bounded backoff.
|
|
58
|
+
|
|
59
|
+
### Hook outcomes
|
|
60
|
+
|
|
61
|
+
Hook script names must be unique; retain the original script set when recovering. Each hook is checkpointed as `running` before execution and `complete` after success. Optional failures become `ignored`. Unknown non-idempotent outcomes require manual review. Set `idempotent: true` on an `afterPublish` hook only when repeated execution is safe. After verifying external completion, `REPO_RELEASE_ACKNOWLEDGE_HOOKS=script-name` acknowledges it without execution (comma-separated for multiple scripts).
|
|
62
|
+
|
|
63
|
+
If a runner disappears during upload before responses are persisted, recovery performs read-only visibility confirmation for up to five minutes. It fails with evidence if versions remain unknown, rather than blindly uploading again. After manually verifying that a version was never uploaded, use the existing exact `publish-unpublished` entry, then rerun the original target set to finish its hooks. Arbitrary external hooks cannot be guaranteed exactly-once.
|
|
64
|
+
|
|
65
|
+
Legacy injected `GitHubOperations` adapters retain their previous behavior. Recovery-capable adapters must implement `readReleaseState`, `writeReleaseState`, `listReleases`, and `ensureTag`; `readTagTarget` is recommended. Enforce revision comparison on writes and throw on query errors. A local summary is not a remote checkpoint.
|
|
66
|
+
|
|
67
|
+
## No-release intents and original-source recovery
|
|
68
|
+
|
|
69
|
+
An intent containing only `none` (or empty frontmatter) records that no release is needed. It does not open a version PR or block publishing an already prepared release. Consumed intents resurrected by a merge are not versioned twice. pnpm cleans these files during the next effective version operation.
|
|
70
|
+
|
|
71
|
+
Release PRs use the applied package list returned by pnpm, not arbitrary Git changes. A new package can keep its initial version; it still appears in the release notes. Cleanup alone never opens a release PR.
|
|
72
|
+
|
|
73
|
+
If an existing prepared version has not completed publication, new version preparation stops before consuming intents and prints its source commit and recovery command. Finish that release first, then run preparation again:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
repo release ci --mode publish --source-sha <full-main-commit-sha> --dry-run
|
|
77
|
+
repo release ci --mode publish --source-sha <full-main-commit-sha>
|
|
78
|
+
repo release ci --mode prepare
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The managed Release workflow exposes the same `source-sha` input for `publish` and `publish-unpublished`. Current tooling checks out the original commit into an isolated directory, installs its locked dependencies, builds and verifies that source, and recovers the full set of versions introduced by its manifests or ledger, including dependency propagation. Package/version inputs validate membership; they do not split the original release. The SHA must belong to `origin/main`. Dry-run only inspects the source and remote release state; it does not install, upload, run hooks, or write checkpoints. Later changes stay pending for a new version. The original source must already include all intended version changes; no versions are changed during recovery.
|
|
82
|
+
|
|
83
|
+
Recovery preserves GitHub's workflow environment for trusted publishing and provenance: its signed identity refers to the workflow run's commit. The isolated checkout, release checkpoint, Git tags, and Release targets refer to `source-sha`. Do not overwrite `GITHUB_SHA` to recover an older source; npm rejects provenance that disagrees with the signed workflow identity.
|
|
43
84
|
|
|
44
85
|
## Next
|
|
45
86
|
|
|
@@ -33,7 +33,7 @@ CI 将版本号、各包 `CHANGELOG.md` 和 `.changeset/ledger.yaml` 提交到 R
|
|
|
33
33
|
pnpm publish -r --report-summary --provenance --no-git-checks
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
pnpm
|
|
36
|
+
pnpm 会跳过 registry 已有版本;CI 根据精确目标版本和远端生命周期检查点恢复 Git tag、GitHub Release 与后置 hook,不再只依赖本轮上传 summary。查询未知、标签冲突或非幂等 hook 结果未知时明确失败;详见[发布任务](/zh/tasks/release)。
|
|
37
37
|
|
|
38
38
|
## Workspace versioning 配置
|
|
39
39
|
|
|
@@ -38,7 +38,7 @@ pnpm version -r
|
|
|
38
38
|
pnpm publish -r --report-summary --provenance --no-git-checks
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
pnpm 会跳过 registry
|
|
41
|
+
pnpm 会跳过 registry 已有版本;CI 根据精确目标版本和远端生命周期检查点恢复 Git tag、GitHub Release 与后置 hook,不再只依赖本轮上传 summary。查询未知、标签冲突或非幂等 hook 结果未知时明确失败;详见[发布任务](/zh/tasks/release)。
|
|
42
42
|
|
|
43
43
|
本地推荐使用 repoctl 包装命令:
|
|
44
44
|
|
|
@@ -39,7 +39,54 @@ repo release --dry-run
|
|
|
39
39
|
|
|
40
40
|
受管 Release 工作流会在发布成功或失败后上传 `npm-publish-progress-<run_id>-<run_attempt>` artifact,保留 14 天;没有清单时跳过上传。现有项目升级 repoctl 后运行 `repo upgrade` 更新受管工作流;自定义工作流可自行添加相同上传步骤。
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
## 跨 runner 恢复与完成判定
|
|
43
|
+
|
|
44
|
+
`repo release ci --mode=publish` 不再把本轮 npm 上传列表当作发布目标。内置 GitHub 客户端在首次上传前,将精确包版本、原提交、npm 接收证据、元数据和逐个 hook 状态写入同仓库的 `repoctl-release-state` 分支。记录键包含仓库、dist-tag 和候选版本集合,写入采用文件 SHA 比较并交换。分支需要 `contents: write` 权限,并应保留;不要删除或手动修改检查点。受管工作流仍须保持发布串行,其他自定义工作流也应避免重叠发布。
|
|
45
|
+
|
|
46
|
+
根目录的 `repoctl-release-progress.json` 是该记录的诊断副本,会与 npm 进度一起归档。只有 npm 精确版本和 dist-tag、指向原提交的标签、已发布的 GitHub Release、所有必要 hook 都完成后,生命周期记录才有 `complete: true`。`repoctl-publish-progress.json` 的 `complete` 仅表示 npm 阶段。
|
|
47
|
+
|
|
48
|
+
重跑会读取远端检查点,核对 registry 和 GitHub,只补齐缺失阶段,不重新上传已接收的版本,也不重复已完成的 hook。预发布在上传前先推送版本提交,确保新 runner 能检出原版本。新发布从完整 Git 历史确定版本来源(checkout 必须 `fetch-depth: 0`);恢复时还会核对原提交的 manifest 和 changelog。若后续提交修改了 changelog,请检出提示的原提交后恢复。
|
|
49
|
+
|
|
50
|
+
旧版发布没有检查点时,可从 npm 的 `gitHead` 恢复原提交。缺失该字段时必须人工核对来源后显式设置 `REPO_RELEASE_SOURCE_SHA`,不能使用重跑 HEAD 猜测。所有目标已有 Release 的历史任务保持 no-op,不倒推重放历史 hook。无记录且缺失元数据的历史任务中,hook 结果按未知处理。
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
repo release ci --mode=publish --dry-run
|
|
54
|
+
repo release ci --mode=publish
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
预演会查询远端并展示目标版本、原提交、npm 阶段、缺失标签/Release 和 hook 状态,不执行上传、hook 或检查点写入。查询超时、TLS 错误、鉴权失败、限流和服务端错误不当成版本不存在;原提交未知或标签冲突明确失败,绝不强制移动标签。GitHub 请求有 30 秒超时和有界退避。
|
|
58
|
+
|
|
59
|
+
### Hook 恢复策略
|
|
60
|
+
|
|
61
|
+
`afterPublish` 脚本名必须唯一,重跑时须保留原脚本集合。每个脚本执行前写入 `running`,成功后写入 `complete`;允许忽略的失败记为 `ignored`。未知结果的非幂等脚本不会自动重试。只有重复执行不会增加副作用时,才声明:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const hook = { script: 'publish:extension', idempotent: true }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
如果外部系统已确认脚本成功,可显式设置 `REPO_RELEASE_ACKNOWLEDGE_HOOKS=publish:extension` 后恢复;多个脚本用逗号分隔。该操作表示人工确认完成,不会再次执行脚本。确认失败或未知时,不应使用此开关。
|
|
68
|
+
|
|
69
|
+
如果 runner 在上传期间消失,检查点可能只有 `running`,而响应尚未持久化。恢复会先进行最多 5 分钟的只读可见性确认;仍不能确认时失败,保留证据,不盲目重传。真正未上传的版本经人工核实后,可用已有 `publish-unpublished` 精确恢复入口,再重跑原发布目标完成其 hook。对任意外部 hook 不承诺 exactly-once。
|
|
70
|
+
|
|
71
|
+
程序化注入的旧 `GitHubOperations` adapter 保留原行为;要启用跨 runner 恢复,需要实现 `readReleaseState`、`writeReleaseState`、`listReleases`、`ensureTag`,并建议提供 `readTagTarget`。写入必须校验 revision,查询错误必须抛出。仅有本地 summary 不能代替远端检查点。
|
|
72
|
+
|
|
73
|
+
## 无需发布的记录与原提交恢复
|
|
74
|
+
|
|
75
|
+
仅包含 `none` 或空 frontmatter 的 intent 表示无需发布。它不会创建版本 PR,也不阻断已经准备好的版本发布。合并后重新出现、但 ledger 已记录消费的 intent 不会再次升级版本;pnpm 会在下一次有效版本操作中清理这些文件。
|
|
76
|
+
|
|
77
|
+
版本 PR 以 pnpm 返回的实际发布包列表为依据,不再把任意 Git 改动视为版本变化。新包首次发布可以保留初始版本号,但仍会列入发布说明。仅清理记录不会创建发布 PR。
|
|
78
|
+
|
|
79
|
+
已有版本尚未完成发布时,新的版本准备会在消费 intent 前失败,并给出原始提交和恢复命令。先恢复旧发布,再准备新版本:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
repo release ci --mode publish --source-sha <完整的-main-提交-SHA> --dry-run
|
|
83
|
+
repo release ci --mode publish --source-sha <完整的-main-提交-SHA>
|
|
84
|
+
repo release ci --mode prepare
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
受管 Release 工作流为 `publish` 和 `publish-unpublished` 提供相同的 `source-sha` 输入。当前工具会在独立目录检出原提交,按照其锁文件安装、构建和验证,恢复该提交 manifest 或 ledger 新增的整批版本,包括依赖传播升级的包。package/version 输入只校验是否属于该批发布,不拆分原发布批次。SHA 必须属于 `origin/main` 历史。dry-run 只检查源码与远端状态,不安装、不上传、不运行 hook、不写检查点。后续变更保留到下一版本;恢复过程中不修改版本号。
|
|
88
|
+
|
|
89
|
+
恢复保留 GitHub 工作流环境,供可信发布和 provenance 使用:签名身份对应运行工作流的提交;独立检出的源码、发布检查点、Git tag 和 Release 目标则对应 `source-sha`。不要通过覆盖 `GITHUB_SHA` 恢复旧源码,npm 会拒绝与工作流签名身份不一致的 provenance。
|
|
43
90
|
|
|
44
91
|
## 下一步
|
|
45
92
|
|