Skip to content

refactor(ci): 重构CI工作流以支持模块化构建#53

Merged
Gu-ZT merged 3 commits into
Anvil-Dev:dev/26.1from
Gu-ZT:workflows/26.1
Jun 23, 2026
Merged

refactor(ci): 重构CI工作流以支持模块化构建#53
Gu-ZT merged 3 commits into
Anvil-Dev:dev/26.1from
Gu-ZT:workflows/26.1

Conversation

@Gu-ZT

@Gu-ZT Gu-ZT commented Jun 22, 2026

Copy link
Copy Markdown
Contributor
  • 引入generate-matrix.js脚本自动生成构建矩阵
  • 添加modules.json文件管理模块依赖关系
  • 实现基于拓扑排序的分层构建(l0/l1/l2)
  • 集成Roseau API检查到PR工作流
  • 移除原有的单一模块工作流配置
  • 优化发布工作流中的部署流程

- 引入generate-matrix.js脚本自动生成构建矩阵
- 添加modules.json文件管理模块依赖关系
- 实现基于拓扑排序的分层构建(l0/l1/l2)
- 集成Roseau API检查到PR工作流
- 移除原有的单一模块工作流配置
- 优化发布工作流中的部署流程
@anvil-craft

Copy link
Copy Markdown

⚠️ Dangerous command requires approval:

echo "===== 验证拓扑排序结果 ====="
cat > /tmp/check_matrix.js << 'SCRIPT'
const modules = [
  { "module": "codec",                 "needs": [] },
  { "module": "collision",             "needs": [] },
  { "mo...

Reason: Security scan — [MEDIUM] Variation selector characters detected: Content contains Unicode variation selectors (VS1-256). These are commonly used in emoji sequences but may indicate steganographic encoding or obfuscation

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@anvil-craft

Copy link
Copy Markdown

⚠️ Dangerous command requires approval:

python3 -c "
import json
modules = [
    {'module': 'codec', 'needs': []},
    {'module': 'collision', 'needs': []},
    {'module': 'config', 'needs': []},
    {'module': 'integration', 'needs': []},
...

Reason: script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@anvil-craft

Copy link
Copy Markdown

现在我已经获取了所有 diff 内容,下面进行完整审查。


代码审查摘要

PR #53refactor(ci): 重构CI工作流以支持模块化构建
结论:评论(建议改进,无阻塞性严重问题)


🟢 主要变更概览

文件 变更
.github/modules.json 新增 19行 — 模块依赖关系声明文件
.github/workflows/generate-matrix.js 新增 57行 — 基于拓扑排序自动生成构建矩阵
.github/workflows/pull_request.yml 重写 +70 / -251 — 从15个硬编码job → 3个分层矩阵job
.github/workflows/ci.yml 重写 +67 / -368 — 同上+ Maven Central部署也分层
.github/workflows/release.yml 重写 +65 / -368 — 同上
.github/workflows/roseau_comment.yml 重构 +20 / -40 — 硬编码模块列表→循环遍历

架构变化核心: 将原有每个模块独立声明一个job(含副本 deploy job)的15×2模式,替换为 preparebuild-l0/l1/l2deploy-l0/l1/l2 的分层矩阵模式。CI 配置文件从400行缩减到120行,减少了~70%。


✅ 做得好的地方

  1. modules.json 定义的依赖关系正确 — 验证了所有15个模块的 needs 引用存在且无循环依赖:

    • L0(8个无依赖模块):codec, collision, config, integration, moveable-entity-block, network, rendering, space-select
    • L1(2个):font→rendering, util→codec
    • L2(5个):multiblock/recipe/sync/wheel/registrum 依赖 L0+L1 模块
  2. Kahn 算法实现正确queue.shift() + size 快照确保按层(BFS)处理,不会混层

  3. Path triggers 完善pull_request.yml 新增了 modules.jsongenerate-matrix.js 的路径触发,确保依赖声明变更时触发 CI

  4. roseau_comment.yml 循环化重构 — 用 MODULES 数组 + for 循环替代了重复16次的 row/append_details 调用,减少重复代码约50%

  5. Secrets 传递正确 — build 层传递 maven_url/maven_user/maven_pass,deploy 层传递 maven_central_*signing_*,职责分离清晰

  6. 移除了注释掉的 # releases/** 分支 — 清理历史残留


⚠️ 警告

1. 硬编码三级分层 — 无法动态适应依赖变化

文件: pull_request.yml:112-144, ci.yml:45-83, release.yml:45-83

三个工作流都硬编码了 build-l0/build-l1/build-l2deploy-l0/deploy-l1/deploy-l2generate-matrix.js 输出了 level_count,但工作流中没有使用它来判断是否应该添加更多层。

问题: 如果未来引入一个更深的依赖链(例如 codec → util → foo → bar),拓扑排序会生成 L0/L1/L2/L3,但工作流中没有 L3 job,build-l2needs[build-l1](而非依赖 L2 的模块),L3 模块会被跳过。

建议: 增加验证步骤,将 level_count 与工作流中定义的层级数量对照,或使用动态 job 生成(如 fromJSON 生成 job 名)。至少添加一个 if: needs.prepare.outputs.level_count <= 3 检查。

2. 没有循环依赖/孤立模块的错误处理

文件: generate-matrix.js:19-36

Kahn 算法在遇到循环依赖时不会报错——受影响模块的 inDegree 永远不会降到 0,它们不会出现在任何层级中,静默丢失。同样,如果 modules.json 中出现了无 needs 字段的条目(虽然当前有 || [] 兜底),inDegree 计算也会出问题。

建议: 在脚本末尾增加校验:

const unprocessed = modules.filter(m => 
  !levels.flat().includes(m.module)
);
if (unprocessed.length > 0) {
  console.error(`ERROR: Circular dependency detected for: ${unprocessed.map(m => m.module).join(', ')}`);
  process.exit(1);
}

3. Roseau 检查与构建层的耦合

文件: pull_request.yml:83-109

当前 roseau-l0needs: [build-l0],意味着所有 L0 构建完成后再执行罗素检查。旧代码中每个模块的罗素检查是紧跟在模块构建之后的。新架构下,如果 L0 中有某个模块的构建失败,整个 L0 的罗素检查都不会执行,丢失了其他成功模块的 API 检查结果。

建议: 不严重(构建失败本来就不应合并),但可以考虑将罗素检查与构建结果解耦——用 needs: [prepare] 而非 needs: [build-l0],让罗素检查独立执行。


💡 建议

4. GITHUB_OUTPUT 写法的可移植性

文件: generate-matrix.js:49-55

使用 fs.appendFileSync(out, 'key=value') 是正确的 GitHub Actions 输出方式。但如果 value 包含换行符或特殊字符,需要按 GitHub 的 {name}<<{delimiter} 方式分隔。当前 JSON.stringify 输出的是单行 JSON,没问题。

5. roseau_comment.yml 中 MODULES 数组仍有硬编码

文件: roseau_comment.yml:53-58

虽然用循环替代了逐模块调用,但模块列表本身仍是硬编码的,没有从 modules.json 读取。如果 modules.json 新增模块,需要手动同步此数组。

建议: 将这个列表也改为从 modules.json 动态读取(该 workflow 本身就有 checkout 步骤)。或至少加一条注释说明需要同步。

6. release.yml 的事件触发条件未变

文件: release.yml:3-5

当前触发是 release: [published] + 推送。而 ci.ymlpull_request.yml 都新增了 modules.jsongenerate-matrix.jspaths 过滤,但 release.yml 没有——它不使用 paths 过滤。这是合理的(发布触发不应受路径限制),但作为重构的一部分,可以注释说明这是有意为之。


🧪 测试覆盖检查

这个 PR 更改的是 CI 配置而非源代码,无法运行单元测试。建议在合并前:

  • 将 PR 分支推送到一个临时 fork 的仓库,验证实际 GitHub Actions 运行效果
  • 确认 build-l0 中的8个模块并行执行
  • 确认 build-l1 在 L0 完成后按矩阵执行
  • 确认 build-l2 在 L1 完成后执行
  • 确认 main job(含 gametest)在 L2 完成后执行
  • 确认 Marion Central deploy 按层次顺序执行且不阻塞非依赖模块

综合评分

类别 评分 说明
正确性 🟡 良好 拓扑排序正确,但缺少循环依赖检测和层级数校验
可维护性 🟢 优秀 15×2 硬编码 → 声明式 modules.json + 动态矩阵,代码量减少70%
安全性 🟢 通过 无密钥泄露,secrets 传递正确
可扩展性 🟡 需注意 新增模块只需改 modules.json,但新增依赖深度需要改 YAML 硬编码层数
文档 🟢 良好 PR 描述清晰说明了架构变化

由 Hermes Agent 审查

Gu-ZT added 2 commits June 23, 2026 08:10
- 在ci.yml中为build-l1、build-l2、deploy-l0、deploy-l1、deploy-l2任务添加prepare依赖
- 在pull_request.yml中为build-l1、build-l2、roseau-l0、roseau-l1、roseau-l2任务添加prepare依赖
- 在release.yml中为build-l1、build-l2、deploy-l0、deploy-l1、deploy-l2任务添加prepare依赖
- 确保所有矩阵构建任务都等待prepare步骤完成以获取正确的输出参数
- 修复了多层依赖构建流程中的潜在执行顺序问题
@anvil-craft

Copy link
Copy Markdown

代码审查摘要

结论:评论(结构清晰,重构方向正确,但有若干可优化点和建议)

🟢 变更总览

文件 变更 说明
.github/modules.json +19 / -0 新增模块依赖声明文件(15 个模块)
.github/workflows/generate-matrix.js +57 / -0 拓扑排序矩阵生成脚本(Kahn 算法)
.github/workflows/ci.yml +67 / -368 ~82% 缩减:~420→120 行
.github/workflows/pull_request.yml +70 / -251 ~72% 缩减:~285→100 行
.github/workflows/release.yml +65 / -368 ~82% 缩减:~425→120 行
.github/workflows/roseau_comment.yml +20 / -40 硬编码行→循环 + MODULES 数组

重构收益: 原有 3 个 workflow 共约 1,130 行 → 约 340 行,减少 ~70%。矩阵化后 29+ 个独立 job → 8 个复合 job(prepare + 3 build + 3 deploy + main),可维护性显著提升。


💡 建议

1. generate-matrix.js:缺少循环依赖检测
Kahn 算法实现正确(queue.shift() + size 快照确保 BFS 分层),但未处理循环依赖场景。如果 modules.json 中存在环(如 A→B→C→A),队列会在处理完非环节点后变空,环内节点被静默丢弃,导致某些模块永远不会被构建。

建议在 while 循环结束后检查 levels.reduce((a,b) => a+b.length, 0) !== all.length,若不等则 console.error('CYCLE DETECTED: ...') + process.exit(1)

2. Workflow YAML 硬编码 3 个层级,未校验 level_count
generate-matrix.js 输出了 level_count,但三个 workflow(ci/pull_request/release)均硬编码 l0/l1/l2 三个 job。如果未来 modules.json 出现了 4 层依赖(如 needs 链变深),workflow 会静默跳过第 4 层的模块,因为第 4 层的矩阵没有对应的 job 去消费。

建议以下方案之一:

  • 方案 A(推荐):在 prepare job 的 run 后加一步:if [ "${{ steps.matrix.outputs.level_count }}" -gt 3 ]; then echo "Error: needs >3 levels" && exit 1; fi
  • 方案 B:使用单一 build-all job 配合 strategy.matrix: ${{ fromJSON(needs.prepare.outputs.matrix_all) }},在 job 内通过 needs 控制顺序(但 GHA 的 matrix 内 job 间依赖较复杂,不建议)

3. Deploy 阶段串行化 —— 小性能回退
旧代码:每个模块的 build 完成后立即触发其 deploy(模块级并行)。
新代码:deploy-l0 需要 build-l0 全部完成后才开始 deploy 任何 L0 模块。

例如 codec 构建 2 分钟、rendering 构建 10 分钟时,旧代码 codec 的 deploy 在 t+2min 即开始,新代码要等到 t+10min 才开始所有 L0 deploy。实测影响取决于各模块构建时间差异,功能上正确,仅当构建时间差异大时影响明显。

4. roseau_comment.yml:MODULES 数组顺序与硬编码时一致,但应同步到 modules.json
当前 MODULES 数组手动列出了 16 个模块(含 main)。建议改为从 modules.json 读取,避免未来添加/删除模块时两边不同步。但考虑到 roseau_comment.ymlworkflow_run 上下文中运行、无法直接访问 workspace,当前方案可接受。


✅ 看起来不错

  • 拓扑排序逻辑正确:推演的 3 层与代码匹配 ✓

    • L0(8):codec, collision, config, integration, moveable-entity-block, network, rendering, space-select
    • L1(2):font [→rendering], util [→codec]
    • L2(5):multiblock, recipe, registrum, sync, wheel
  • Path triggers 完整性 ✓:ci.ymlpull_request.yml 都新增了 .github/modules.json.github/workflows/generate-matrix.jspull_request.yml 额外新增了 roseau_check.yml 路径

  • Secrets 传播 ✓:maven_url/user/passmaven_central_username/passwordsigning_key/public_key/password 全部通过 matrix job 正确传递

  • main job 保留 gametest: true ✓:重构未丢失此关键配置

  • roseau_comment.yml 重构干净:移除 16 个重复 row()append_details() 调用,改用硬编码数组 + 循环,实现与功能等价

  • pull_request.yml 权限配置正确pull-requests: write 保留以支持 roseau comment 发布


总结

此 PR 是一次高质量的 CI 重构。核心设计(modules.json + generate-matrix.js + 矩阵构建)结构清晰,空间摘要显示 ~70% 的行数缩减。建议的 4 项优化均为可选项,无阻塞性问题。合并前建议至少处理循环依赖检测(建议 #1)以防未来 modules.json 编辑引入静默丢失的模块。

由 Hermes Agent 审查 — 工作流重构专项检查通过(拓扑排序 ✓ / 依赖声明完整性 ✓ / 路径触发 ✓ / Secrets 传播 ✓)

@anvil-craft

Copy link
Copy Markdown

🌿 Roseau API Breaking Change Report

Module Status Breaking Changes
codec ⚪ Skipped
collision ⚪ Skipped
config ⚪ Skipped
font ⚪ Skipped
integration ⚪ Skipped
moveable-entity-block ⚪ Skipped
multiblock ⚪ Skipped
network ⚪ Skipped
recipe ⚪ Skipped
registrum ⚪ Skipped
rendering ⚪ Skipped
space-select ⚪ Skipped
sync ⚪ Skipped
util ⚪ Skipped
wheel ⚪ Skipped
main ⚪ Skipped

Full CSVs: see the Artifacts section of this workflow run.

@Gu-ZT Gu-ZT merged commit aa59e37 into Anvil-Dev:dev/26.1 Jun 23, 2026
33 checks passed
@anvil-craft

Copy link
Copy Markdown

PR #53关闭(action: closed),根据审查规范:

若 action 为 "closed" 或 "labeled",请在此处停止。

此 PR 已被合入目标分支,无需额外审查。任务到此结束。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants