Skip to content

Commit 43587ae

Browse files
committed
docs: sync documentation with current behavior
1 parent 702c1c8 commit 43587ae

25 files changed

Lines changed: 465 additions & 308 deletions

.agents/skills/mcpp-contributing/SKILL.md

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ mcpp 项目的贡献流程:先创建 Issue → 切分支 → 实现改动 →
1111

1212
- 仓库:https://github.com/mcpp-community/mcpp
1313
- 构建:`mcpp build`(C++23 模块自举)
14-
- 测试:`tests/e2e/` 下的 bash 脚本
15-
- CI:GitHub Actions,base 为 `main` 的 PR 自动触发
14+
- 测试:`mcpp test` 覆盖 `tests/**/*.cpp``tests/e2e/` 提供真实二进制的端到端脚本
15+
- CI:GitHub Actions,base 为 `main` 的 PR 触发分平台构建、测试与 E2E 检查
1616

1717
## 核心原则
1818

@@ -126,20 +126,28 @@ git checkout -b <type>/<short-description>
126126
**构建验证**
127127

128128
```bash
129-
# 找到 mcpp 二进制
130-
ls target/x86_64-linux-gnu/*/bin/mcpp
131-
# 构建
132-
<mcpp-binary> build
129+
# 用现有 bootstrap mcpp 自举构建
130+
mcpp build
131+
# 选择刚生成的 target/**/bin/mcpp(Windows 为 mcpp.exe),不要硬编码宿主 triple
132+
<fresh-mcpp-binary> --version
133133
```
134134

135135
**测试**
136136

137137
```bash
138-
bash tests/e2e/01_help_and_version.sh # 基础测试
139-
bash tests/e2e/<relevant-test>.sh # 相关测试
140-
# 新功能应创建对应 E2E 测试
138+
# C++ 单元/集成测试:由刚构建的二进制发现 tests/**/*.cpp
139+
<fresh-mcpp-binary> test
140+
# 端到端测试:显式把刚构建的二进制交给脚本
141+
# 路径必须是刚构建产物的绝对路径;Windows 使用 mcpp.exe。
142+
MCPP=<absolute-path-to-fresh-mcpp-or-mcpp.exe> bash tests/e2e/01_help_and_version.sh
143+
MCPP=<absolute-path-to-fresh-mcpp-or-mcpp.exe> bash tests/e2e/<relevant-test>.sh
144+
# 新功能按变更契约补充 focused unit/integration 和/或 E2E 覆盖
141145
```
142146

147+
E2E 并不保证完全离线:部分脚本需要工具链、索引或 capability provider。
148+
按 CI 等价方式设置 `MCPP_HOME`、镜像和其他 capability 后再运行;不要让缓存命中
149+
或空 workspace 选择冒充行为覆盖。
150+
143151
### 4. 提交 PR
144152

145153
**提交信息前缀**`feat:` / `fix:` / `refactor:` / `test:` / `docs:` / `chore:`
@@ -154,8 +162,9 @@ gh pr create \
154162
Closes #<issue>
155163
156164
## Test plan
157-
- [ ] mcpp build 通过
158-
- [ ] E2E 测试通过"
165+
- [ ] 文档-only:示例与链接已按当前实现复核,无运行时行为变更
166+
- [ ] 涉及行为或测试文档时:`mcpp test`(unit/integration)通过
167+
- [ ] 涉及行为或测试文档时:相关 E2E 脚本使用 fresh `MCPP` 通过"
159168
```
160169

161170
**PR 要求**
@@ -173,14 +182,16 @@ gh pr checks <pr-number> # 查看状态
173182
gh run view <run-id> --log-failed # 查看失败日志
174183
```
175184

176-
CI 包含三个平台
185+
CI 由分平台的基础构建/单元集成检查与独立 E2E 检查组成
177186
| Workflow | 平台 | 内容 |
178187
|----------|------|------|
179-
| `ci` | Linux x86_64 | 自举构建 + E2E 测试 |
180-
| `ci-macos` | macOS ARM64 | 自举构建 + E2E 测试 |
181-
| `ci-windows` | Windows x86_64 | 自举构建 + E2E 测试 |
188+
| `ci-linux` / `ci-linux-e2e` | Linux x86_64 | 自举构建、unit/integration / 分片 E2E |
189+
| `ci-macos` / `ci-macos-e2e` | macOS ARM64 | 自举构建、unit/integration / E2E |
190+
| `ci-windows` / `ci-windows-e2e` | Windows x86_64 | 自举构建、toolchain 回归 / E2E |
191+
| `cross-build-test` | Linux/Windows cross targets | 交叉构建、产物运行与 MinGW/Wine 检查 |
192+
| `ci-aarch64-fresh-install` | Linux ARM64 native | path-filtered fresh install、原生自举与 musl `build.mcpp` host-helper 回归 |
182193

183-
**三个平台全部通过才能合入** 如果某个平台失败:
194+
**以 PR 实际 required checks 为准,所有未跳过的 required checks 必须通过** 如果某个平台失败:
184195
1. 下载日志分析原因
185196
2. 修复后 push 到同一分支,CI 自动重跑
186197
3. 如果是 flaky test,在 PR 中说明
@@ -242,7 +253,7 @@ gh pr merge <pr-number> --merge
242253
src/
243254
├── cli.cppm ← 命令行入口
244255
├── config.cppm ← 全局配置
245-
├── manifest.cppm ← mcpp.toml 解析
256+
├── manifest/ ← manifest 模型、TOML/xpkg 解析
246257
├── platform/ ← 平台抽象层(所有平台相关代码)
247258
│ ├── platform.cppm ← 统一外观模块
248259
│ ├── common.cppm ← 平台常量与检测
@@ -260,7 +271,8 @@ src/
260271
├── modgraph/ ← 模块图扫描验证
261272
├── pack/ ← 打包发布
262273
└── xlings.cppm ← xlings 抽象层
263-
tests/e2e/ ← E2E 测试脚本
274+
tests/unit/ ← C++ unit/integration tests (`mcpp test`)
275+
tests/e2e/ ← E2E 测试脚本 (`MCPP=...` + `run_all.sh`)
264276
docs/ ← 用户文档
265277
.agents/docs/ ← 设计文档
266278
.agents/skills/ ← Agent 技能文档
@@ -270,6 +282,7 @@ docs/ ← 用户文档
270282

271283
- C++23 模块项目,修改模块时注意 import 依赖顺序
272284
- 平台相关代码统一放 `src/platform/`,不在其他模块中直接使用 `#if defined`
273-
- E2E 测试应独立运行,不依赖网络
285+
- E2E 测试应声明所需 capability,并使用隔离的 `MCPP_HOME`;需要网络/索引的脚本
286+
不得被描述为完全离线
274287
- 不确定方向时先在 Issue 讨论再动手
275288
- **永远走 PR 流程,不直接 push main**

.agents/skills/mcpp-release/SKILL.md

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ description: Use when releasing a new version of mcpp — bumps version, creates
2424
2525
## Overview
2626

27-
mcpp 的版本号存在于 **四个位置**,但它们分属**两组,在发布流程的两个不同时刻更新**
28-
把四处一起 bump 是一个会让全部 CI 变红的经典错误 —— 见下面第二组的解释。
27+
mcpp 有 **三个持久化版本位置**,以及 `ci-fresh-install` 的一个运行时推导值。它们分属
28+
两组,在不同时间更新;把"正在构建的版本"与 bootstrap pin 一起前移会让 CI 尝试安装
29+
尚未发布的 mcpp。
2930

3031
**第一组:正在构建的版本**(发布时改,走 bump PR)
3132

@@ -35,31 +36,22 @@ mcpp 的版本号存在于 **四个位置**,但它们分属**两组,在发
3536
这两处必须**在同一个 commit 里**一起改:`tests/e2e/01_help_and_version.sh` 交叉比对
3637
`mcpp.toml``mcpp --version`,只改一处 CI 立刻红。
3738

38-
**第二组:bootstrap pin —— CI 用哪个 mcpp 来自举**发布并进索引之后才改
39+
**第二组:bootstrap pin —— CI 用哪个 mcpp 来自举**发布并进索引之后才可改
3940

4041
3. `.xlings.json``workspace.mcpp` — CI bootstrap 装哪个 mcpp
41-
4. `.github/workflows/ci-fresh-install.yml``MCPP_PIN` — 全新安装验证的目标版本
4242

43-
这两处指向的是一个**已经发布、且已经进了索引**的版本。在 bump PR 里把它们一起挪到新版,
44-
等于让每一个 CI job 去 `xlings install` 一个还不存在的 mcpp —— 全线红。
45-
所以它们在 bump PR 里保持**上一个已发布版本**不动,直到发布收尾那一步才前移
46-
(见「发布后的收尾」第 3 步)。`check_version_pins.sh` 正是按这个语义校验的:它只要求
47-
两处 pin **彼此相等**、且**不得新于**正在构建的版本,并不要求等于它。
43+
`.xlings.json` 必须指向一个**已经发布、镜像并进入索引**的版本。因此它在 bump PR 中
44+
保持已有的可安装版本,直到发布收尾时才可前移。
4845

49-
对照最近一次发布:`fd27314`(bump 到 2026.7.29.1)只动了第一组两个文件,第二组仍停在
50-
2026.7.28.2;`fde3b70` 才在发布、镜像、进索引之后把 pin 推到 2026.7.29.1。
46+
`ci-fresh-install.yml``MCPP_PIN` 不是持久化 pin:`wait-index` 从最新 GitHub
47+
Release 推导一次,所有安装 job 消费同一个输出。绝不能手工编辑或恢复字面量
48+
`MCPP_PIN`,否则 index guard 和实际安装版本会再次漂移。
5149

52-
**版本不一致会导致 release smoke test 失败**(CI 检查 `mcpp --version` 是否匹配 tag)。
53-
第二组历史上多次漂移(`MCPP_PIN` 曾落后五个版本),所以现在有机器校验:
54-
55-
```bash
56-
bash .github/tools/check_version_pins.sh
57-
```
58-
59-
它同时校验第二组不变量:**`.github/` 下所有 xlings pin 必须等于 `src/xlings.cppm`
60-
`pinned::kXlingsVersion`**(当前 16 个 pin 点、7 个文件,含 release.yml 里三处硬编码的
61-
aarch64 tarball 字面量)。`kXlingsVersion` 是唯一真源,也是 release 打进
62-
`<install>/registry/bin/xlings` 的那一份。改 xlings 版本只改常量,然后跑这个脚本找出其余落点。
50+
`.github/tools/check_version_pins.sh` 的目标是校验版本关系和 xlings pin;但当前版本在
51+
第 95 行有 Bash 语法错误,不能把它的执行当成有效验证。修复该实现前,手工核对
52+
`mcpp.toml``MCPP_VERSION` 相等、`.xlings.json` 不领先于正在构建的版本;也不要
53+
通过修改文档或 workflow 绕开动态 `MCPP_PIN` 设计。`src/xlings.cppm`
54+
`pinned::kXlingsVersion` 仍是 xlings 版本的唯一真源。
6355

6456
## 发布步骤
6557

@@ -71,12 +63,15 @@ git checkout main && git pull origin main
7163
gh run list --branch main --limit 3
7264
```
7365

74-
所有 CI(ci / ci-macos / ci-windows)必须为 `success`。不要在 CI 红的时候发版。
66+
以分支保护和 `gh pr checks <pr-number>` 显示的 actual required checks 为准。
67+
在 main 上监控当前运行时,检查 `ci-linux``ci-linux-e2e``ci-macos`
68+
`ci-macos-e2e``ci-windows``ci-windows-e2e``cross-build-test` 的结果;
69+
跳过或非 required 的 workflow 不是合入 gate。不要在 required CI 红的时候发版。
7570

7671
### 2. bump 版本号(第一组两处,单个 commit,走 PR)
7772

78-
**只改第一组的两个文件**,并且在同一个 commit 里。bootstrap pin(`.xlings.json`
79-
`MCPP_PIN`**不要动** —— 它们指向上一个已发布版本,见 Overview。
73+
**只改第一组的两个文件**,并且在同一个 commit 里。`.xlings.json` bootstrap pin
74+
**不要动**`MCPP_PIN` 是 workflow 运行时推导值,绝不能手工编辑,见 Overview。
8075

8176
```bash
8277
# 日期版本:当天序号从 .1 起;.0 仅用于正式/稳定版
@@ -87,8 +82,8 @@ git checkout -b "chore/bump-$NEW_VERSION"
8782
sed -i "s/^version.*=.*/version = \"$NEW_VERSION\"/" mcpp.toml
8883
sed -i "s/MCPP_VERSION = \".*\"/MCPP_VERSION = \"$NEW_VERSION\"/" src/toolchain/fingerprint.cppm
8984

90-
# 机器校验(building 是新版、bootstrap pin 仍是旧版,是预期状态)
91-
bash .github/tools/check_version_pins.sh
85+
# 当前 check_version_pins.sh 有 Bash 语法错误;在它修复前手工确认:
86+
# mcpp.toml 与 MCPP_VERSION 相等,.xlings.json 仍是已发布的 bootstrap 版本。
9287

9388
# 自查:构建产物真的报新版本。注意 target/ 目录名带指纹哈希,
9489
# 版本一变就是新目录 —— 用 `ls -dt` 取最新的那个,`head -1` 会拿到旧二进制。
@@ -154,8 +149,8 @@ gh release view "v$NEW_VERSION"
154149
- `install.sh`
155150
- `SHA256SUMS`
156151

157-
**顺带核对体积**(2026.7.29.1 起,见下方"载荷瘦身"):linux 两个 tarball 应在
158-
**5MB 上下**。如果又回到 30MB 量级,说明 strip 断言被绕过了,先查再发
152+
同时比较 Linux 资产与最近一次成功 release 的体积。若出现明显回升,先确认
153+
strip 和打包步骤的断言仍然执行,再继续发布
159154

160155
## Release CI 详解
161156

@@ -170,20 +165,18 @@ gh release view "v$NEW_VERSION"
170165
5. Linux: `mcpp self env` 中 MCPP_HOME 正确解析
171166
6. xlings 二进制已捆绑
172167

173-
### 载荷瘦身(2026.7.29.1 起)
168+
### 载荷瘦身
174169

175170
每个 linux 平台在**打包后、打 tar 前**调用 `.github/tools/slim_linux_payload.sh`
176171
strip `bin/mcpp``registry/bin/xlings`**断言结果**`file` 不得再含
177172
`not stripped`)。
178173

179-
为什么必须断言:在此之前,vendored 的 xlings 从来没被 strip 过(97.3MB,带
180-
`debug_info`),而 x86_64 那句 `strip` 跑在 `mcpp pack` **之前** —— pack 会重建
181-
二进制把它覆盖掉,于是直到 2026.7.28.2 发布的 `bin/mcpp` 一直是未 strip 的。
182-
一个不校验效果的 `strip` 等于注释。修完 linux-x86_64 tarball 从 **34.81MB 降到
183-
4.62MB(7.5×)**
174+
为什么必须断言:单独执行一次 `strip` 不足以证明最终 tarball 已变小,后续的
175+
`mcpp pack` 可能重建并覆盖二进制。检查最终 payload 的 `file` 输出和资产体积,而非
176+
依赖固定的 MB 数或历史发布大小。
184177

185-
macOS / Windows **故意不做**载荷本来就 6.1MB / 4.2MB,且 strip Mach-O 会让
186-
ad-hoc 签名失效
178+
macOS / Windows **故意不做**:strip Mach-O 会让 ad-hoc 签名失效;按各平台的
179+
release 规则验证最终资产,不要套用 Linux 的 strip 判断
187180

188181
### publish-ecosystem:镜像 + 索引(发布的后半程)
189182

@@ -216,11 +209,10 @@ gh pr merge <n> --repo openxlings/xim-pkgindex --squash --admin
216209
# 2) 真实验证(注意:不带 @版本 不会升级已装的旧版)
217210
xlings update && xlings install mcpp@$NEW_VERSION -y
218211

219-
# 3) bootstrap pin 收尾 —— 第二组两处,到这一步才前移
220-
# 新版此时已发布、已镜像、已进索引,CI 装得到,pin 才可以指向它
212+
# 3) bootstrap pin 收尾 —— 仅 .xlings.json;新版此时已发布、已镜像、已进索引
221213
sed -i "s/\"mcpp\": \"[^\"]*\"/\"mcpp\": \"$NEW_VERSION\"/" .xlings.json
222-
sed -i "s/MCPP_PIN: '[^']*'/MCPP_PIN: '$NEW_VERSION'/" .github/workflows/ci-fresh-install.yml
223-
bash .github/tools/check_version_pins.sh
214+
# 不编辑 ci-fresh-install.yml 的 MCPP_PIN:它由 wait-index 运行时推导。
215+
# 当前 check_version_pins.sh 有 Bash 语法错误;手工确认 pin 关系。
224216
git commit -am "ci: workspace mcpp bootstrap pin -> $NEW_VERSION (released, mirrored, indexed)"
225217
```
226218

@@ -254,11 +246,11 @@ gh workflow run bump-formula.yml -R mcpp-community/homebrew-mcpp
254246
| 症状 | 原因 | 修复 |
255247
|------|------|------|
256248
| `mcpp X.Y.Z-1` 但 tag 是 `vX.Y.Z` | `fingerprint.cppm` 版本未更新 | 更新 `MCPP_VERSION`,重新打 tag |
257-
| bump PR 里**所有** CI job 都红在 bootstrap,报 `package 'mcpp@X.Y.Z' not found` | 把第二组的 bootstrap pin 也一起 bump 了,CI 去装一个还没发布的版本 |`.xlings.json` / `MCPP_PIN` 回退到上一个已发布版本,发布收尾时再前移 |
249+
| bump PR 里**所有** CI job 都红在 bootstrap,报 `package 'mcpp@X.Y.Z' not found` | `.xlings.json` bootstrap pin 一起 bump 了,CI 去装一个还没发布的版本 |`.xlings.json` 回退到上一个已发布版本;不要修改运行时推导的 `MCPP_PIN` |
258250
| 自查 `--version` 显示旧版本,但源码已改 | `target/<triple>/<指纹>/` 的指纹随版本变,`ls \| head -1` 取到了上一次构建的目录 |`ls -dt … \| head -1` 取最新构建 |
259251
| Smoke test 输出旧版本 | CI 缓存了旧的 sandbox/target | 删除 GitHub Actions cache 后重跑 |
260-
| e2e `01_help_and_version.sh`| 只改了 `mcpp.toml` 没改 `fingerprint.cppm`(它把两者交叉比对) | 同步四处版本;注意这个 e2e 只在部分分片里跑,可能表现为"只有某个平台红" |
261-
| xlings bootstrap 失败 | xlings 版本不兼容 |`src/xlings.cppm::kXlingsVersion`**唯一真源**)后跑 `check_version_pins.sh` 找出其余 15 个 pin |
252+
| e2e `01_help_and_version.sh`| 只改了 `mcpp.toml` 没改 `fingerprint.cppm`(它把两者交叉比对) | 同步两处正在构建的版本;注意这个 e2e 只在部分分片里跑,可能表现为"只有某个平台红" |
253+
| xlings bootstrap 失败 | xlings 版本不兼容 |`src/xlings.cppm::kXlingsVersion`(唯一真源),再核对引用它的 workflow 与脚本;当前 pin-check 脚本修复前不能依赖它完成扫描 |
262254
| macOS/Windows 构建失败 | 需要等 Linux job 先完成 | 检查 Linux job 是否成功 |
263255
| `slim: FAIL: ... still not stripped` | strip 工具没生效/被 pack 覆盖 | 别绕过断言——它就是为了拦住 34.8MB 的 tarball 再次发出去 |
264256
| mirror leg 报 `missing/unverified` | 资产没传上去或还没传播 | 先 GET 核验(**必须 GET,`curl -I` 会骗你**),gitcode 用 `gitcode.com` 直链而非 `api.` 主机;确认缺件后本地补传再 `gh run rerun --failed`(脚本幂等,已验证的资产会跳过) |
@@ -310,9 +302,9 @@ gh workflow run release.yml --ref "v$NEW_VERSION"
310302
| `mcpp.toml` | `version = "X.Y.Z"` — 项目版本,release.yml 由它推导 tag |
311303
| `src/toolchain/fingerprint.cppm` | `MCPP_VERSION = "X.Y.Z"` — 编译期版本常量 |
312304
| `.xlings.json` | `workspace.mcpp` — CI bootstrap 装哪个 mcpp(发布****才 bump) |
313-
| `.github/workflows/ci-fresh-install.yml` | `MCPP_PIN`全新安装验证目标(发布**** bump |
314-
| `src/xlings.cppm` | `kXlingsVersion` — xlings pin 的**唯一真源**(其余 15 处由脚本校验) |
315-
| `.github/tools/check_version_pins.sh` | 机器校验上述两组不变量,别靠肉眼 |
305+
| `.github/workflows/ci-fresh-install.yml` | `MCPP_PIN``wait-index` 从最新 release 推导,**从不手工 bump** |
306+
| `src/xlings.cppm` | `kXlingsVersion` — xlings pin 的**唯一真源** |
307+
| `.github/tools/check_version_pins.sh` | 版本/pin 校验的预期 guard;当前有 Bash 语法错误,修复前须手工核对 |
316308
| `.github/tools/slim_linux_payload.sh` | linux 载荷 strip + 断言 |
317309
| `.github/tools/mirror_res.sh` | 双端镜像(并发上传 + leg deadline + 完整性 gate) |
318310
| `.github/tools/gtc` | GitCode CLI(release create/upload、PR) |
@@ -321,6 +313,7 @@ gh workflow run release.yml --ref "v$NEW_VERSION"
321313
| `CHANGELOG.md` | Release notes 来源(按 `## [X.Y.Z]` 提取) |
322314

323315
> **注意版本 bump 的两个阶段**`mcpp.toml` + `fingerprint.cppm` 在发版****
324-
> (它们定义要发什么);`.xlings.json` + `MCPP_PIN` 在发版**成功后**改(它们指向
325-
> bootstrap 用哪个已发布版本)。`check_version_pins.sh` 认得这个差异,不会因为
326-
> bootstrap pin 落后一版就报错。
316+
> (它们定义要发什么);`.xlings.json` 只在发版成功、镜像并进索引后才可更新
317+
> (它指定 bootstrap 使用的已发布版本)。`MCPP_PIN` 是被测版本的运行时推导值,
318+
> 不属于任何手工 bump 阶段。当前 `check_version_pins.sh` 的 Bash 语法错误修复前,
319+
> 这些关系须手工核对。

0 commit comments

Comments
 (0)