From 7c11c6b9aad3e2f8777c6a551d7d438d8e6ea55b Mon Sep 17 00:00:00 2001 From: cfdaily Date: Sat, 20 Jun 2026 23:10:00 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[moz]=20impl(=C2=A721):=20toolchain-templat?= =?UTF-8?q?es.yaml=20+=20Issue=20=E6=A8=A1=E6=9D=BF=E8=A1=A5=E5=85=A8=20+?= =?UTF-8?q?=20G1=20=E4=BF=AE=E5=A4=8D=20+=20=C2=A720=20superseded?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config/toolchain-templates.yaml: §4 steps 模板化(7 种 business_type + ci_failure + review_result) - src/daemon/toolchain_templates.py: 加 get_steps()/get_output_template() YAML 加载 - .gitea/ISSUE_TEMPLATE/: 补 impl.yml + docs.yml + refactor.yml - src/daemon/toolchain_handler.py: G1 弯引号修复 - docs/design/20-issue-centric-orchestration.md: status 改为 superseded by §21 Closes #106 --- .gitea/ISSUE_TEMPLATE/docs.yml | 27 +++ .gitea/ISSUE_TEMPLATE/impl.yml | 33 ++++ .gitea/ISSUE_TEMPLATE/refactor.yml | 27 +++ config/toolchain-templates.yaml | 171 ++++++++++++++++++ docs/design/20-issue-centric-orchestration.md | 2 +- src/daemon/toolchain_handler.py | 2 +- src/daemon/toolchain_templates.py | 64 ++++++- 7 files changed, 323 insertions(+), 3 deletions(-) create mode 100644 .gitea/ISSUE_TEMPLATE/docs.yml create mode 100644 .gitea/ISSUE_TEMPLATE/impl.yml create mode 100644 .gitea/ISSUE_TEMPLATE/refactor.yml create mode 100644 config/toolchain-templates.yaml diff --git a/.gitea/ISSUE_TEMPLATE/docs.yml b/.gitea/ISSUE_TEMPLATE/docs.yml new file mode 100644 index 0000000..beaec6f --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/docs.yml @@ -0,0 +1,27 @@ +name: 文档任务 +about: 编写或更新文档 +title: "[moz] docs: " +labels: + - type/docs +body: + - type: textarea + id: description + attributes: + label: 文档目标 + description: 要写什么文档,解决什么问题 + validations: + required: true + - type: textarea + id: path + attributes: + label: 文档路径 + description: 目标文件路径(如 docs/design/xxx.md) + validations: + required: true + - type: textarea + id: outline + attributes: + label: 大纲 + description: 文档结构和要点 + validations: + required: true diff --git a/.gitea/ISSUE_TEMPLATE/impl.yml b/.gitea/ISSUE_TEMPLATE/impl.yml new file mode 100644 index 0000000..f985e10 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/impl.yml @@ -0,0 +1,33 @@ +name: 实现任务 +about: 按设计文档实现功能 +title: "[moz] impl: " +labels: + - type/feature +body: + - type: textarea + id: description + attributes: + label: 实现目标 + description: 清晰描述要实现什么 + validations: + required: true + - type: textarea + id: design_doc + attributes: + label: 设计文档 + description: 关联的设计文档路径(如 docs/design/xxx.md) + validations: + required: true + - type: textarea + id: scope + attributes: + label: 实现范围 + description: 涉及哪些文件/模块 + validations: + required: true + - type: textarea + id: acceptance + attributes: + label: 验收标准 + validations: + required: true diff --git a/.gitea/ISSUE_TEMPLATE/refactor.yml b/.gitea/ISSUE_TEMPLATE/refactor.yml new file mode 100644 index 0000000..09f26ad --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/refactor.yml @@ -0,0 +1,27 @@ +name: 重构任务 +about: 重构现有代码 +title: "[moz] refactor: " +labels: + - type/refactor +body: + - type: textarea + id: description + attributes: + label: 重构目标 + description: 为什么重构,期望改善什么 + validations: + required: true + - type: textarea + id: scope + attributes: + label: 影响范围 + description: 涉及哪些文件/模块,是否有 breaking change + validations: + required: true + - type: textarea + id: tests + attributes: + label: 测试保障 + description: 重构前哪些测试必须通过 + validations: + required: true diff --git a/config/toolchain-templates.yaml b/config/toolchain-templates.yaml new file mode 100644 index 0000000..8798382 --- /dev/null +++ b/config/toolchain-templates.yaml @@ -0,0 +1,171 @@ +# toolchain-templates.yaml +# §21 §4 steps 模板化 — 按 action_type + business_type 查找 +# 占位符 {issue_number}/{brief}/{title}/{pr_number} 等运行时渲染 + +# --------------------------------------------------------------------------- +# issue_assigned(按 Issue label 分 6 路 + infrastructure) +# --------------------------------------------------------------------------- +issue_assigned: + feature: + steps: + - "理解需求(Issue body)→ 如有不明确在 Issue comment 追问" + - "git checkout main && git pull origin main" + - "git checkout -b feat/{issue_number}-{brief}" + - "编码实现 + 写 UT" + - "文档同步:如果本次改动涉及设计变更或接口变更,在同一分支更新 docs/design/ 对应文档。如无需更新,在 action report 中说明「文档无需更新」" + - "git add -A && git commit -m '[moz] feat: {title}' && git push origin feat/{issue_number}-{brief}" + - "CI 通过后创建 PR(body 含 Closes #{issue_number})" + - "等 Review" + output_template: | + [Action Report] + **分支**:feat/{issue_number}-{brief} + **PR**:#{pr_number} + **改动文件**:{files} + **CI**:{ci_status} + **文档同步**:{doc_status} + + impl: + steps: + - "读设计文档(Issue body 中的路径)→ 理解实现范围" + - "git checkout main && git pull origin main" + - "git checkout -b impl/{issue_number}-{brief}" + - "按设计编码实现 + 写 UT" + - "文档同步:如果本次改动涉及设计变更或接口变更,在同一分支更新 docs/design/ 对应文档。如无需更新,在 action report 中说明「文档无需更新」" + - "git add -A && git commit -m '[moz] impl: {title}' && git push origin impl/{issue_number}-{brief}" + - "CI 通过后创建 PR(body 含 Closes #{issue_number} + 设计文档路径)" + - "等 Review" + output_template: | + [Action Report] + **设计文档**:{design_doc} + **分支**:impl/{issue_number}-{brief} + **PR**:#{pr_number} + **改动文件**:{files} + **CI**:{ci_status} + **文档同步**:{doc_status} + + bug: + steps: + - "读 Bug 描述 + 复现步骤(Issue body)" + - "定位根因(读代码/日志,不要猜测)" + - "git checkout main && git pull origin main" + - "git checkout -b fix/{issue_number}-{brief}" + - "修复 + 写回归测试" + - "文档同步:如修复涉及设计/接口变更,同步更新 docs/design/ 对应文档" + - "git add -A && git commit -m '[moz] fix: {title}' && git push origin fix/{issue_number}-{brief}" + - "CI 通过后创建 PR(body 含 Closes #{issue_number} + 根因和修复方式)" + - "等 Review" + output_template: | + [Action Report] + **根因**:{root_cause} + **修复方式**:{fix_approach} + **分支**:fix/{issue_number}-{brief} + **PR**:#{pr_number} + **CI**:{ci_status} + **文档同步**:{doc_status} + + docs: + steps: + - "读文档目标(Issue body)" + - "git checkout main && git pull origin main" + - "git checkout -b docs/{issue_number}-{brief}" + - "编写文档到 docs/ 对应目录" + - "git add -A && git commit -m '[moz] docs: {title}' && git push origin docs/{issue_number}-{brief}" + - "创建 PR(body 含 Closes #{issue_number})" + - "等 Review" + output_template: | + [Action Report] + **文档路径**:{doc_path} + **分支**:docs/{issue_number}-{brief} + **PR**:#{pr_number} + + refactor: + steps: + - "读重构目标 + 影响范围(Issue body)" + - "git checkout main && git pull origin main" + - "git checkout -b refactor/{issue_number}-{brief}" + - "重构 + 确保现有测试不 break(python3 -m pytest tests/unit/ -q)" + - "文档同步:如重构涉及架构变更,同步更新 docs/design/ 对应文档" + - "git add -A && git commit -m '[moz] refactor: {title}' && git push origin refactor/{issue_number}-{brief}" + - "CI 通过后创建 PR(body 含 Closes #{issue_number} + 重构内容和影响范围)" + - "等 Review" + output_template: | + [Action Report] + **重构范围**:{scope} + **测试结果**:{test_result} passed + **分支**:refactor/{issue_number}-{brief} + **PR**:#{pr_number} + **CI**:{ci_status} + **文档同步**:{doc_status} + + test: + steps: + - "读测试目标(Issue body)" + - "git checkout main && git pull origin main" + - "git checkout -b test/{issue_number}-{brief}" + - "编写测试脚本到 tests/ 对应目录" + - "运行测试验证(python3 -m pytest {test_file} -v)" + - "git add -A && git commit -m '[moz] test: {title}' && git push origin test/{issue_number}-{brief}" + - "创建 PR(body 含 Closes #{issue_number})" + - "等 Review" + output_template: | + [Action Report] + **测试文件**:{test_file} + **测试结果**:{test_result} + **分支**:test/{issue_number}-{brief} + **PR**:#{pr_number} + + infrastructure: + steps: + - "根据 Issue body 中的错误来源和日志片段排查问题" + - "修复基础设施问题(CI runner/网络/Gitea/磁盘等)" + - "修复后在 Issue 上 comment 说明修复方式和结果" + - "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)" + output_template: | + [Action Report] + **问题**:{problem} + **根因**:{root_cause} + **修复方式**:{fix} + **验证**:{verification} + +# --------------------------------------------------------------------------- +# ci_failure +# --------------------------------------------------------------------------- +ci_failure: + steps: + - "查看完整 CI 日志(PR 页面或 Gitea Actions 页面)" + - "根据 CI 日志判断失败原因类型:\n a. 代码问题(lint/test 失败)→ 修复失败的测试 → push 到原分支 → CI 自动重跑\n b. 基础设施问题(runner 环境/Python/venv/Gitea/网络故障)→ 在该仓库创建 Issue 指派 jiangwei-infra(label 必须包含 type/infrastructure)" + - "文档同步:如修复涉及设计/接口变更,同步更新 docs/design/ 对应文档" + - "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)— 报告中说明判断的原因类型和执行的操作,以及文档是否需要更新" + output_template: | + [Action Report] + **原因类型**:{cause_type} + **操作**:{action} + **CI 重跑**:{ci_status} + **文档同步**:{doc_status} + +# --------------------------------------------------------------------------- +# review_result — APPROVED +# --------------------------------------------------------------------------- +review_result_approved: + steps: + - "合并 PR(Gitea API: POST /repos/{repo}/pulls/{pr_number}/merge)" + - "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)" + output_template: | + [Action Report] + **PR #{pr_number}**:merged + +# --------------------------------------------------------------------------- +# review_result — REQUEST_CHANGES +# --------------------------------------------------------------------------- +review_result_request_changes: + steps: + - "按审查意见逐条修改代码" + - "文档同步:如审查涉及设计/接口变更,同步更新 docs/design/ 对应文档" + - "push 到原分支 → CI 自动跑" + - "CI 通过后等重新 Review" + - "提交 action report(POST http://localhost:8083/api/projects/_toolchain/tasks//comments,comment_type=action_report)— 报告中必须说明文档是否需要更新及处理结果" + output_template: | + [Action Report] + **修改内容**:{changes} + **CI**:{ci_status} + **文档同步**:{doc_status} diff --git a/docs/design/20-issue-centric-orchestration.md b/docs/design/20-issue-centric-orchestration.md index 86e10af..ad9c6c5 100644 --- a/docs/design/20-issue-centric-orchestration.md +++ b/docs/design/20-issue-centric-orchestration.md @@ -2,7 +2,7 @@ title: "Issue-Centric Orchestration — Gitea Issue 替代黑板 DB 协作面" created: 2026-06-19 version: v2.1 draft -status: draft +status: superseded by §21 (toolchain 部分) changelog: v2.1 修正 M1(dispatcher 直接 SQL 声明)+ M2(Phase 格式)+ S1/S2(TaskAdapter 残留清理) v2.0 纳入姜维+司马懿 Review 反馈 + 庞统 Repository 模式修正 v1.1 纳入姜维 Review 反馈 diff --git a/src/daemon/toolchain_handler.py b/src/daemon/toolchain_handler.py index 2a0cb6a..368ed15 100644 --- a/src/daemon/toolchain_handler.py +++ b/src/daemon/toolchain_handler.py @@ -264,7 +264,7 @@ class ToolchainConstraintsSection: '| “步骤太多了,选几个做就行” | ❌ 错!必须逐条执行,不可跳过 |', '| “这个步骤不适用于当前情况” | ❌ 如果确实不适用,在 action report 中说明原因,但其他步骤必须执行 |', '| “CI/部署失败不是我代码的问题,我什么也不用做” | ❌ 错!即使是基础设施问题,你也必须创建 Issue 指派 jiangwei-infra(body 含错误来源链接 + 日志 + 判断依据),并在 action report 中说明。不能只报告“不是我的问题”就完事 |', - '| "文档以后再说" | ❌ 错!文档同步和代码改动在同一 PR 中完成,action report 中必须说明文档处理情况 |', + '| “文档以后再说” | ❌ 错!文档同步和代码改动在同一 PR 中完成,action report 中必须说明文档处理情况 |', "", ] return "\n".join(lines) diff --git a/src/daemon/toolchain_templates.py b/src/daemon/toolchain_templates.py index 44ab599..a58c32b 100644 --- a/src/daemon/toolchain_templates.py +++ b/src/daemon/toolchain_templates.py @@ -5,10 +5,11 @@ from __future__ import annotations +import json import logging from collections import defaultdict from pathlib import Path -from typing import Dict +from typing import Dict, List, Optional logger = logging.getLogger(__name__) @@ -87,3 +88,64 @@ def render_template(name: str, variables: Dict[str, str]) -> str: def clear_cache() -> None: """清空模板缓存(用于测试或热更新)""" _template_cache.clear() + _steps_cache.clear() + + +# --------------------------------------------------------------------------- +# §21 §4.2 YAML steps 模板加载 +# --------------------------------------------------------------------------- + +STEPS_YAML_PATH = Path(__file__).parent.parent.parent / "config" / "toolchain-templates.yaml" + +_steps_cache: Optional[dict] = None + + +def _load_steps_yaml() -> dict: + """加载并缓存 toolchain-templates.yaml。""" + global _steps_cache + if _steps_cache is not None: + return _steps_cache + try: + import yaml + with open(STEPS_YAML_PATH, encoding="utf-8") as f: + _steps_cache = yaml.safe_load(f) or {} + logger.debug("Loaded steps YAML: %d action_types", len(_steps_cache)) + except FileNotFoundError: + logger.warning("Steps YAML not found: %s", STEPS_YAML_PATH) + _steps_cache = {} + except Exception as e: + logger.error("Failed to load steps YAML: %s", e) + _steps_cache = {} + return _steps_cache + + +def get_steps(action_type: str, business_type: str = "") -> List[str]: + """从 YAML 模板配置获取 steps。 + + Args: + action_type: 动作类型(issue_assigned / ci_failure / ...) + business_type: 业务子类型(feature/impl/bug/docs/refactor/test/infrastructure) + + Returns: + steps 列表,找不到返回空列表 + """ + templates = _load_steps_yaml() + section = templates.get(action_type, {}) + if isinstance(section, dict) and business_type: + subsection = section.get(business_type, {}) + return subsection.get("steps", []) + if isinstance(section, dict): + return section.get("steps", []) + return [] + + +def get_output_template(action_type: str, business_type: str = "") -> str: + """从 YAML 模板配置获取 output_template。""" + templates = _load_steps_yaml() + section = templates.get(action_type, {}) + if isinstance(section, dict) and business_type: + subsection = section.get(business_type, {}) + return subsection.get("output_template", "") + if isinstance(section, dict): + return section.get("output_template", "") + return "" -- 2.45.4 From 37b811548591ee8ef3b0a9f0a599f9d4d314aa7f Mon Sep 17 00:00:00 2001 From: cfdaily Date: Sat, 20 Jun 2026 23:29:00 +0800 Subject: [PATCH 2/2] [moz] fix(lint): remove unused json import in toolchain_templates.py --- src/daemon/toolchain_templates.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/daemon/toolchain_templates.py b/src/daemon/toolchain_templates.py index a58c32b..e767188 100644 --- a/src/daemon/toolchain_templates.py +++ b/src/daemon/toolchain_templates.py @@ -5,7 +5,6 @@ from __future__ import annotations -import json import logging from collections import defaultdict from pathlib import Path -- 2.45.4