Skip to content

Commit dbcbe7a

Browse files
authored
feat(observability+resilience): MCPP_VERBOSE in all CI + cold index-update retry (#182)
* feat(observability+resilience): MCPP_VERBOSE env + cold index-update retry Two changes prompted by an opaque, repeatedly-reproducing CI failure in 75_index_status_offline.sh (a cold `mcpp self env` in a fresh MCPP_HOME whose index/sandbox bootstrap fails fast — root cause swallowed in non-verbose logs; verified NOT related to the feature/capability work, it fails identically on main): 1. MCPP_VERBOSE env override (src/cli.cppm): MCPP_VERBOSE=<non-empty,!=0> turns on verbose logging for EVERY mcpp invocation, including those nested inside e2e test scripts that call $MCPP without flags. An explicit --quiet still wins. Set MCPP_VERBOSE: "1" in all CI workflows (ci-linux, ci-linux-e2e, ci-macos, ci-windows, cross-build-test, ci-fresh-install, ci-aarch64-fresh-install) so failures carry full diagnostics. Complements the existing MCPP_LOG_LEVEL (which only sets the FILE log level, not stderr). 2. update_index retry (src/xlings.cppm): the index sync is a network git op; a single transient blip otherwise fails cold init outright. Bounded retry with linear backoff (3 attempts, 2s/4s). Success returns on the first attempt — zero added latency in steady state; only a real failure pays the backoff. Retry notices go through mcpp::log::verbose (file always, stderr under MCPP_VERBOSE). This PR's own e2e CI run carries MCPP_VERBOSE=1, so it surfaces the real cause of the 75 bootstrap failure for a targeted follow-up. * feat(resilience): auto-detect best index mirror at first init (the real stability fix) Implements TODO(mirror-default) option (b). The first-init seed used a hardcoded "CN" mirror, which strands overseas users and GitHub-hosted CI behind a slow/unreachable gitcode mirror — the actual root cause behind the repeated 75_index_status_offline.sh cold-bootstrap failures (a US runner seeding CN can't reach gitcode, so the index clone fails fast and the index reports 'missing'). detect_best_mirror() runs a short, tight-timeout HEAD probe to github.com (GLOBAL) and gitcode.com (CN), and pins the lower-latency reachable one into .xlings.json. Priority matches the intended design: explicit --mirror (config) > lower-latency auto-probe > GLOBAL fallback An explicit `mcpp self config --mirror CN|GLOBAL` always wins; the probe only runs on a fresh init with no explicit choice. Falls back to GLOBAL (reachable nearly everywhere) if neither host answers. Verified locally: on a CN host the probe picks CN (gitcode 150ms < github 380ms) and logs 'mirror: probe github=380ms gitcode=150ms -> CN' under MCPP_VERBOSE; a US CI runner will symmetrically pick GLOBAL. e2e 75/80/81 green. * fix(mirror): seed "auto" so xlings' own region detection runs (remove curl probe) Replaces the curl-based mcpp-side probe (per review: don't reinvent in mcpp; mirror selection is xlings' job, and it already does it via tinyhttps). Root cause of the repeated 75_index_status_offline.sh CI failures, now proven: mcpp seeded a hardcoded "CN" into a fresh .xlings.json. xlings' normalize_mirror_ accepts only "GLOBAL"/"CN" as valid, so "CN" was used DIRECTLY (gitcode) — bypassing xlings' own detect_install_mirror_(), which probes github vs gitcode latency (tinyhttps::probe_latency) and picks the reachable/faster region. On a GitHub-hosted (US) runner gitcode is slow/unreachable, so the cold index/sandbox bootstrap failed and the index reported 'missing'. Fix: seed "auto". normalize_mirror_("auto") -> nullopt (invalid) -> xlings treats the mirror as unset -> runs detect_install_mirror_() -> picks GLOBAL on a US runner, CN on a China link. mcpp no longer overrides xlings' region choice. The existing-config guard (config.cppm: only seed when .xlings.json is absent) already means an explicit `mcpp self config --mirror CN|GLOBAL` is never clobbered. Empirically confirmed via the curl-probe build's verbose CI run: on the US runner 'probe github=70ms gitcode=1060ms -> GLOBAL' then patchelf/ninja bootstrap succeeded and 75 PASSED — proving the mirror region is the cause. This commit hands that region choice back to xlings instead of doing it in mcpp. * fix(ci): adjust for mirror=auto default; don't force verbose in e2e-suite jobs Follow-up to the mirror=auto fix and MCPP_VERBOSE rollout, fixing 3 e2e regressions surfaced by the previous CI run (75 itself now PASSES): - 38_self_config_mirror.sh: the default seed is now "auto" (defer to xlings' region detection), not "CN". Updated the assertion; explicit --mirror GLOBAL/cn/BAD checks unchanged. - 48_build_error_output.sh / 53_namespaced_cache_label.sh assert mcpp's DEFAULT (quiet) output. Forcing MCPP_VERBOSE=1 in CI broke them. Removed MCPP_VERBOSE from the workflows that run the e2e suite (ci-linux-e2e, ci-macos, ci-windows); kept it where it's diagnostic and safe (ci-fresh-install, ci-aarch64-fresh-install — the cold bootstrap path — plus ci-linux unit tests and cross-build). A test that needs verbose passes --verbose itself. Verified locally: 38/48/53 green. * release: v0.0.70 — cold-init mirror auto-detection + observability Bump mcpp.toml + MCPP_VERSION to 0.0.70. CHANGELOG: seed "auto" so xlings' region detection runs (fixes overseas/CI cold bootstrap), MCPP_VERBOSE env, update_index retry.
1 parent dea776e commit dbcbe7a

14 files changed

Lines changed: 100 additions & 24 deletions

.github/workflows/ci-aarch64-fresh-install.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ jobs:
3030
name: fresh install + native build (aarch64 / glibc)
3131
runs-on: ubuntu-24.04-arm
3232
timeout-minutes: 60
33+
env:
34+
# Verbose every mcpp invocation — cold bootstrap path (src/cli.cppm).
35+
MCPP_VERBOSE: "1"
3336
steps:
3437
- name: System info
3538
run: |

.github/workflows/ci-fresh-install.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ jobs:
3030
name: Linux fresh install
3131
runs-on: ubuntu-24.04
3232
timeout-minutes: 60
33+
env:
34+
# Verbose every mcpp invocation — fresh-install is the cold index/sandbox
35+
# bootstrap path, exactly where extra diagnostics matter (src/cli.cppm).
36+
MCPP_VERBOSE: "1"
3337
steps:
3438
- uses: actions/checkout@v4
3539

.github/workflows/ci-linux-e2e.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ jobs:
2828
timeout-minutes: 45
2929
env:
3030
MCPP_HOME: /home/runner/.mcpp
31+
# NOTE: do NOT force MCPP_VERBOSE here. The e2e suite includes tests that
32+
# assert mcpp's DEFAULT (quiet) output — e.g. 48_build_error_output and
33+
# 53_namespaced_cache_label — which forced verbose would break. Verbose is
34+
# set only in the fresh-install workflows (cold bootstrap, no such asserts).
35+
# A specific test that needs verbose passes `--verbose` itself.
3136
steps:
3237
- uses: actions/checkout@v4
3338

.github/workflows/ci-linux.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ jobs:
3232
# MCPP_HOME pinned so the cache key below restores into the
3333
# same path mcpp resolves at runtime.
3434
MCPP_HOME: /home/runner/.mcpp
35+
# Verbose every mcpp invocation for richer CI diagnostics (src/cli.cppm).
36+
MCPP_VERBOSE: "1"
3537
steps:
3638
- uses: actions/checkout@v4
3739

.github/workflows/ci-macos.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ jobs:
1919
name: macOS ARM64 — xlings LLVM end-to-end
2020
runs-on: macos-15
2121
timeout-minutes: 30
22+
# NOTE: no MCPP_VERBOSE here — this job runs the e2e suite, which includes
23+
# tests asserting mcpp's default quiet output (48/53). Verbose is forced only
24+
# in the fresh-install workflows.
2225
steps:
2326
- uses: actions/checkout@v4
2427

.github/workflows/ci-windows.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ jobs:
2121
timeout-minutes: 45
2222
env:
2323
MCPP_HOME: C:\Users\runneradmin\.mcpp
24+
# NOTE: no MCPP_VERBOSE — this job runs the e2e suite, which asserts mcpp's
25+
# default quiet output (48/53). Verbose is forced only in fresh-install.
2426
steps:
2527
- uses: actions/checkout@v4
2628

.github/workflows/cross-build-test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ jobs:
5757
qemu_bin: qemu-aarch64-static
5858
env:
5959
MCPP_HOME: /home/runner/.mcpp
60+
# Verbose every mcpp invocation for richer CI diagnostics (src/cli.cppm).
61+
MCPP_VERBOSE: "1"
6062
steps:
6163
- uses: actions/checkout@v4
6264

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,31 @@
33
> 本文件追踪 `mcpp-community/mcpp` 公开仓的版本演进。
44
> 格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)
55
6+
## [0.0.70] — 2026-06-29
7+
8+
### 修复
9+
10+
- **首次初始化在海外网络与 GitHub 托管 CI 上的冷启动失败(`index missing`;patchelf / ninja
11+
bootstrap 失败)**:`mcpp self env` 为新建的 `MCPP_HOME` 播种 `.xlings.json` 时,将 `mirror` 字段
12+
硬编码为 `"CN"`。xlings 的 `normalize_mirror_` 仅接受 `GLOBAL``CN` 两个合法取值,故 `"CN"`
13+
被直接采用并解析至 gitcode,致使 xlings 内置的区域探测 `detect_install_mirror_()` 被跳过——该例程
14+
`tinyhttps::probe_latency` 测量 github 与 gitcode 的连接延迟,择可达且更低延迟者。在美国区域的
15+
runner 上,gitcode 不可达或显著较慢(实测 github 70 ms、gitcode 1060 ms),由此索引与沙箱的冷
16+
bootstrap 失败。本版将播种值改为 `"auto"`:`normalize_mirror_("auto")` 判定为非法取值,xlings 视其
17+
为未设置并执行自身探测,在美国区域解析至 GLOBAL、在中国大陆解析至 CN。镜像选择的职责由此归还
18+
xlings(其已基于 tinyhttps 实现该机制),mcpp 不再代为决策。播种仅在 `.xlings.json` 不存在时发生,
19+
显式的 `mcpp self config --mirror CN|GLOBAL` 配置不会被覆盖。
20+
21+
### 新增
22+
23+
- **`MCPP_VERBOSE` 环境变量**:取非空且非 `"0"` 的值时,为每一次 mcpp 调用启用 verbose 日志,涵盖
24+
e2e 脚本中未携带 flag 的 `$MCPP` 调用,便于 CI 诊断。该变量与既有的 `MCPP_LOG_LEVEL`(仅控制文件
25+
日志级别)互补;显式 `--quiet` 仍具有更高优先级。该变量已在 fresh-install 等 workflow 中启用,但
26+
不含运行「默认静默」输出断言的 e2e 套件。
27+
- **`update_index` 冷启动重试**:索引同步为网络 git 操作,单次瞬时故障原会直接导致冷启动失败。本版
28+
改为有界退避重试(至多 3 次,退避 2 s / 4 s);成功路径于首次尝试即返回,稳态无额外延迟,仅失败
29+
时方触发退避。
30+
631
## [0.0.69] — 2026-06-29
732

833
### 新增

mcpp.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mcpp"
3-
version = "0.0.69"
3+
version = "0.0.70"
44
description = "Modern C++ build & package management tool"
55
license = "Apache-2.0"
66
authors = ["mcpp-community"]

src/cli.cppm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ int run(int argc, char** argv) {
101101
else if (a == "--no-color") mcpp::ui::disable_color();
102102
else if (a == "--verbose" || a == "-v") mcpp::log::set_verbose(true);
103103
}
104+
// Env override (observability, esp. CI): MCPP_VERBOSE=<non-empty, not "0">
105+
// turns on verbose logging for EVERY mcpp invocation — including the ones
106+
// nested inside e2e test scripts that call $MCPP without flags. Lets a
107+
// workflow flip on diagnostics globally with one env var. An explicit
108+
// --quiet still wins (it is processed above and gates the verbose sinks).
109+
if (const char* v = std::getenv("MCPP_VERBOSE");
110+
v && *v && std::string_view(v) != "0")
111+
mcpp::log::set_verbose(true);
104112

105113
// ─── top-level --help / -h / --version intercept ────────────────────
106114
// cmdline auto-handles these but its formatter doesn't match the

0 commit comments

Comments
 (0)