ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Gitea 开发规则手册:CLAUDE.md 与 AGENTS.md 中的 Agent 协作开发规范全解

2026/9/7 16:55:36 拓冰建站 浏览量
Gitea 开发规则手册:CLAUDE.md 与 AGENTS.md 中的 Agent 协作开发规范全解 Gitea 开发规则手册CLAUDE.md 与 AGENTS.md 中的 Agent 协作开发规范全解【免费下载链接】giteaGit with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD项目地址: https://gitcode.com/GitHub_Trending/gi/giteaGitea 仓库根目录下的CLAUDE.md通过单行AGENTS.md引用把一份 20 条开发规则集中交给 AI Agent 与人类贡献者共同遵守。本篇以 AGENTS.md 规则为骨架逐条展开结合 Makefile、tools/test-e2e.sh 等真实实现给出可直接复制执行的验证、构建、Lint 与测试命令帮助你在 Gitea 代码库中以符合上游惯例的方式完成从提交信息到测试落地的全流程工作。一、CLAUDE.md一行引用背后的“单一事实来源”CLAUDE.md 的全部内容只有一行AGENTS.md这是 Agent 工具的文件引用语法——它不定义任何规则而是把规则实体指向 AGENTS.md。从源码结构看这种组织方式意味着无论使用哪类 Agent 工具链真正的行为约束都收敛在同一份文件中维护避免了“每个 Agent 一份规则”的碎片化。AGENTS.md 共 20 条规则可归为六类验证优先的工作方式、PR 与提交规范、AI 归属声明、代码风格、构建与 Lint 命令链、测试哲学。下文逐一拆解并给出对应的仓库内实现证据。二、验证优先make help与 docs 目录前两条规则确立了基本的信息获取纪律Never assume, verify before claiming绝不假设断言前先验证List development targets withmake help用make help列出开发目标Read relevant developer documentation in thedocsfolder阅读docs目录下相关开发者文档make help的实际实现位于 Makefile#L183-L187它用 awk 解析 Makefile 中形如target: ## 说明的注释生成目标清单并额外手工补印了三个带#参数的动态目标——test-e2e、test-backend[#TestSpecificName]、test-integration[#TestSpecificName]。这说明 Gitea 的 Makefile 把“帮助文档即目标清单”作为约定任何新增开发目标都应带上## 说明注释以便被make help发现。规则指向的开发者文档在当前仓库中确实齐备docs/development.md开发入门docs/testing.md测试指南docs/guidelines-backend.md后端规范docs/guidelines-frontend.md前端规范docs/guidelines-refactoring.md重构规范docs/release-management.md发布管理三、PR 描述与 Issue 引用风格PR descriptions: minimal, only what and why, no task or file listings. Include screenshots for UI changes, before and after when modifying existing UI. Aim for less than 1000 charactersReference issues and PRs by full URL, not by number两条规则都服务于可检索性PR 描述只写“做了什么、为什么”不罗列任务清单或文件列表控制在 1000 字符以内UI 变更必须附截图修改既有 UI 时须给出前后对比。引用 issue 或 PR 时要求完整 URL 而非裸编号——这样跨平台含非 GitHub 托管环境阅读时链接依然有效也方便自动化工具解析。四、提交规范与 AI 归属声明这是与 Agent 协作最相关的一组规则Use Conventional Commits for commit messages and PR titles, plus Giteasenhancetype for user-facing enhancementsAdd anAssisted-by: AGENT_NAME:MODEL_VERSIONtrailer to commit messages, neverCo-Authored-ByorSigned-off-byAttribute agent authorship on one trailing line in issue and PR comments, never as a PR description sectionNever rewrite git history unless asked, update PRs with new commits and normal push从当前仓库最近的提交历史可以直接看到 Conventional Commits 的落地形态且确实大量使用 Gitea 自定义的enhance类型区别于通用规范中的feat用于“面向用户的增强”enhance(actions): make workflow dispatch choice dropdown support search (#39154) fix(web): populate the reason for cannot commit to branch in web editor commit form (#39155) refactor(automerge): fix error handling, populate recent automerge tasks on restart (#39001) chore(frontend): avoid loading CSS twice in vite dev mode (#39160) fix(packages): preserve SemVer prerelease identifiers in Swift Registry (#39156) feat: add deploy tokens (#37306) ci(snap): pack snaps without an LXD container (#39152)可见type(scope): subject是硬约束enhance、fix、refactor、chore、feat、ci等类型均真实出现。关于 AI 归属Agent 辅助的提交必须追加 trailerAssisted-by: AGENT_NAME:MODEL_VERSION例如Assisted-by: Claude:claude-sonnet形式且明确禁止使用Co-Authored-By或Signed-off-by表达 Agent 参与——这让人类署名与机器署名在git log --format输出中可被严格区分。在 issue/PR 评论中Agent 身份只允许以“末尾一行”出现不能占用 PR 描述正文的段落。最后一条强调除非被要求绝不重写 git 历史PR 通过追加新 commit 加普通 push 更新从而保住评审线程的连续性。五、代码风格注释、TypeScript、Go 模板与 i18n五条风格规则覆盖了注释密度、前端语法、Go 语言特性、CSS 工具类与文件头1. 注释要“近乎没有”。Comments: write almost none, short and preferably same-line, explaining why for a future reader. Never narrate code, the change or the prompt. Preserve existing ones that still apply. If you need to write a paragraph-long comment, rethink your implementation, it is likely too complicated注释只解释“为什么”禁止复述代码在做什么、改动是什么、提示词是什么既有的仍然成立的注释要保留。需要写段落级注释时应回退反思实现本身是否过于复杂——这是把“可理解性预算”压回实现逻辑而非文档侧。2. 新增.go文件的版权头要带当前年份。3. i18n 只改英文源文件。Inoptions/locale, only editlocale_en-US.json, other locales are synced automatically当前仓库 options/locale/ 下有 29 个语言文件规则要求贡献者含 Agent只编辑locale_en-US.json其余语言由同步机制自动处理避免多语言文件手改造成漂移。4. TypeScript 用!表达“必然存在”。In TS, use!instead of?./??when a value always exists当某个值在语义上必然存在时应使用非空断言!而不是防御性地写?./??——后者会掩盖真实的不变量让类型系统失去对“此处不可能为空”这一事实的表达。5. Go 优先使用现代语言特性CSS 优先tw-*工具类。In Go, prefer to use modern language features wherever possiblePrefertw-*utilities over inlinestyleandflex-*helpers over per-childtw-ml-*/tw-mr-*margins, falling back totw-*where specificity requires!important前端侧禁止内联style优先 Tailwind 的tw-*工具类布局间距优先用flex-*的 gap 系列而非对子元素逐一设置tw-ml-*/tw-mr-*边距确需提升优先级时才回落到!important写法。六、构建与 Lint 命令链fmt、tidy、generate-swagger 及四类 lintRunmake fmtafter.goedits,make tidyaftergo.modedits,make generate-swaggerafter API changes, and lint what changed withmake lint-go,lint-js,lint-cssorlint-templates这条“编辑类型 → 必跑命令”的映射是规则的心脏。逐条对照 Makefile 的实现可以看到每条命令的真实工作量make fmtMakefile#L198-L207做两件事用golangci-lint fmt格式化 Go 代码再用 sed 对templates/下全部.tmpl文件做模板空白规整——去除{{后与}}前的多余空白、(后的多余空白保留纯缩进行。所以 Gitea 中“改 Go 文件”触发的格式化同时覆盖 Go 与模板两种语法。对应的 CI 门禁是 Makefile#L209-L216 的fmt-check重跑 fmt 后对git diff判空有差异即失败。make tidyMakefile#L419-L428不只是go mod tidy它先从go.mod解析出最低 Go 版本与 toolchain执行go mod tidy -compat$(MIN_GO_VERSION)若 tidy 丢掉了toolchain指令则用go mod edit -toolchain恢复注释标明这是针对 Go 上游问题的 workaround最后重新生成go-licenses文件。配套的tidy-checkMakefile#L434-L441对go.mod、go.sum与许可证清单做 diff 校验。make generate-swaggerMakefile#L227-L242用go-swagger generate spec从代码注释重新生成 Swagger 与 OpenAPI 3 规范swagger-check同样通过 diff 判定是否遗漏了重新生成——这正是规则要求“API 变更后必须跑”的原因规范文件是生成物必须与路由注释保持零漂移。四个 lint 目标分别对应四类资产目标实现覆盖范围lint-goMakefile#L331-L333 调用 tools/lint-go-all.goGo 源码lint-go-fix加--fixlint-jsMakefile#L293-L296pnpm exec eslintpnpm exec vue-tscJS/TS 与 Vue 类型检查lint-cssMakefile#L303-L305pnpm exec stylelint --max-warnings0CSS零警告容忍lint-templatesMakefile#L353-L356tools/lint-templates-svg.tsdjlint模板中的 SVG 与模板语法规则强调“lint what changed”——只对本轮修改涉及的类别跑对应目标避免全量 lint 的等待成本。所有目标还聚合在checks-backend/checks-frontend之下Makefile#L266-L273checks-backend串起tidy-check、swagger-check、openapi3-check、fmt-check、swagger-validate、security-check构成与规则一一对应的自动门禁。七、“修复根因”原则禁止禁用 linter 或弱化测试Fix the cause rather than disabling a linter or weakening a test. Where unavoidable, use the narrowest scope with a trailing comment giving the reason规则把“消掉报错”与“消除问题”区分开默认路径是修改代码本身只有不可避免时才允许在最窄作用域内豁免且必须在行尾注释写明原因。这条约束直接约束了 Agent 面对 lint 报错时的行为模式——不允许生成//nolint或降低断言这类“以妥协换绿”的补丁。八、单测怎么跑Go、TS、e2e 三类命令Run single tests withgo test -run ^TestName$ ./modulepath/for Go,pnpm exec vitest path-filterfor TS andGITEA_TEST_E2E_FLAGSfilepath make test-e2efor e2e三类命令在仓库中各有精确落点Go 单测。规则给出的go test -run ^TestName$ ./modulepath/是标准裸命令Makefile 额外提供了带参数的目标test-backend#%Makefile#L403-L406把.替换为/后作为-run模式执行且默认携带-tags如 sqlite 等 CGO 标签。TS 前端测试。pnpm exec vitest path-filter与 Makefile#L387-L389 的test-frontend目标一致pnpm exec vitest传路径过滤参数即可缩到单个文件。e2e 测试。GITEA_TEST_E2E_FLAGSfilepath make test-e2e的链路是Makefile#L485-L487 的test-e2e目标依赖playwright frontend backend三个前置先装浏览器、构建前端、构建后端然后执行./tools/test-e2e.sh $(GITEA_TEST_E2E_FLAGS)tools/test-e2e.sh 的最后一行pnpm exec playwright test $把该参数原样透传给 Playwright 作为文件过滤tools/test-e2e.sh#L194。脚本还揭示了 e2e 环境的完整搭建方式用mktemp -d建隔离工作目录、随机空闲端口、sqlite 数据库、INSTALL_LOCK true跳过安装向导、关闭验证码最后通过gitea admin user create命令创建带--admin的测试管理员tools/test-e2e.sh#L167-L172。集成测试则有对等的test-integration#%目标Makefile#L461-L463按GITEA_TEST_DATABASEsqlite/mysql/pgsql/mssql编译运行。九、测试哲学最少、最快、确定性Write the fewest, fastest tests covering the behavior, extending an existing one where possible. Prefer unit tests where logic is testable in isolationAim for sub-2s per integration test and sub-4s per e2e test. Wait on a deterministic condition rather thansleep, and prefer semantic locators in e2e tests四条要求可归纳为数量上能扩展既有测试就不新建能单元隔离就不写集成/端到端速度上集成测试单条 2 秒内、e2e 单条 4 秒内确定性上等待条件应基于可观察状态如服务可访问、元素出现而非固定sleep定位上e2e 优先语义定位器role、label 等而非脆弱的选择器。仓库实现对这套哲学有直接呼应。tools/test-e2e.sh#L174-L182 中的超时系数逻辑本地机器取系数 1CI 环境自动放大为 4 倍——即 e2e 用例的“4 秒预算”是按本机标准计时CI 慢机器才乘以冗余。同一脚本中的服务就绪等待tools/test-e2e.sh#L140-L157也是“轮询 curl 直到可达 进程存活检查”的确定性等待模式与sleep式等待形成对照。测试代码应遵循同样的原则。十、速查表规则到命令的映射场景规则要求可执行命令查看开发目标以make help为准make help修改 Go 代码后格式化make fmt修改go.mod后依赖整理make tidy修改 API 后重新生成规范make generate-swaggerLint 变更文件按资产类别选择make lint-go/lint-js/lint-css/lint-templates跑单个 Go 测试精确-rungo test -run ^TestName$ ./modulepath/或make test-backend#TestName跑单个前端测试路径过滤pnpm exec vitest path-filter跑单条 e2e文件过滤GITEA_TEST_E2E_FLAGSfilepath make test-e2e提交信息Conventional Commits enhance类型enhance(scope): subjectAssisted-by: AGENT:MODELtrailer更新 PR追加 commit不重写历史新 commit 普通 pushCLAUDE.md 到 AGENTS.md 的这套规则本质是把 Gitea 上游评审中最常驳回的问题——规范漂移、lint 妥协、测试拖慢、Agent 归属不清——前置为可执行的约束清单并让每一条都能落到 Makefile 目标或 tools/ 脚本中验证。遵循它Agent 与人类贡献者在同一代码库中产出的提交在格式、风格与质量门槛上保持同一水准。【免费下载链接】giteaGit with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD项目地址: https://gitcode.com/GitHub_Trending/gi/gitea创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考