新闻详情

新闻详情

首页 / 资讯中心 / 详情

Grafana Tempo 提交前检查清单(Pre-Commit Checklist)实战指南:从本地验证到 PR 全流程

发布时间:2026/9/17 10:11:07来源:尧图网络
Grafana Tempo 提交前检查清单(Pre-Commit Checklist)实战指南:从本地验证到 PR 全流程
Grafana Tempo 提交前检查清单Pre-Commit Checklist实战指南从本地验证到 PR 全流程【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo本文是 Grafana Tempo 仓库内.agents/guidance/precommit.md的深度实战解读。它完整梳理了向 Tempo 提交代码前必须执行的本地检查格式化、lint、单元测试、E2E 测试、changelog 校验并给出了 PR 描述与评审期推送的协作规范。读完本文你将能在本地用make命令复现与 CI 完全一致的质量门槛理解gofumpt/golangci-lint/四路测试拆分等工具链的底层原理并掌握大型 Go 仓库中不破坏评审流程的协作姿势。为什么需要一份 Pre-Commit ChecklistGrafana Tempo 是一个高吞吐、低依赖的分布式链路追踪后端仓库规模庞大pkg/、tempodb/、modules/、cmd/、integration/等目录下分布着数千个 Go 源文件仓库根目录的Makefile中对源码文件做了tools、vendor、integration的排除后才计算测试包。在这样的仓库中一次提交如果只依赖 CI 兜底往往会因「工作区 dirty 导致检查失败」「lint 在全量代码上误报」「竞态检测超时」等问题浪费大量迭代时间。因此 Tempo 在.agents/guidance/precommit.md中固化了「push 之前先跑本地检查」的流程。它的核心原则是本地优先make fmt、make lint、make test覆盖最常见的检查项CI 还会额外执行jsonnetfmt、集成测试等见.github/workflows/ci.yml与 CI 对齐本地命令的参数如 lint 的 diff 范围、测试的四路拆分与 CI Job 保持一一对应保证「本地能过、CI 大概率也能过」。第一步格式化Formattingmake fmtmake fmt使用gofumpt和goimports两个工具对代码库做格式化。对应 Makefile 中的实现fmt: tools-image ## Format codebase with gofumpt and goimports $(TOOLS_CMD) gofumpt -w $(FILES_TO_FMT) $(TOOLS_CMD) goimports -w $(FILES_TO_FMT)两个工具通过TOOLS_CMD在 Tempo 的 CI 工具镜像中执行。需要注意FILES_TO_FMT的过滤规则Makefile排除vendor、tools/vendor、opentelemetry-proto、vendor-fix、.claude目录排除*.pb.goprotobuf 生成代码、*.y.gogoyacc 生成代码、*.gen.go代码生成产物。也就是说生成代码不属于格式化范围手工格式化它们反而会制造无意义的 diff。CI 侧的检查目标make check-fmt等价于先执行make fmt再用git diff --exit-code校验工作树是否被改动过check-fmt: fmt git diff --exit-code -- $(FILES_TO_FMT)这解释了清单中「CI 会在 tree dirty 时直接 fail」的说法如果你没先跑make fmt就推送CI 的check-fmtJob见.github/workflows/ci.yml中 lint job 的第一步会把未格式化的差异判为失败。所以清单建议把它放在所有检查的第一步。第二步Lint静态检查make lintmake lint运行golangci-lint配置文件为仓库根目录的.golangci.yml两种模式见 Makefilelint: ## Lint codebase with golangci-lint ifneq ($(base),) $(LINT_CMD) $(LINT) run --config .golangci.yml --new-from-rev$(base) else $(LINT_CMD) $(LINT) run --config .golangci.yml endif关键差异在于是否传入base参数命令检查范围适用场景make lint全量代码小改动或首次清理make lint baseorigin/main仅 base 之后的新增 diff与大仓库 CI 完全一致CI 实际执行的就是 diff 版本在.github/workflows/ci.yml的 lint Job 中运行make lint baseorigin/${BASE_REF}BASE_REF即 PR 的目标分支。这样评审者只看「这次改动引入的新问题」而非历史遗留问题。因此文档特别强调在大型仓库上开发时本地应使用make lint baseorigin/main以精确复现 CI 结果同时注意先执行git fetch保持本地origin/main引用较新。另外 CI 会对 golangci-lint 的缓存目录做缓存key 中包含go.mod与.golangci.yml的哈希本地反复跑 lint 时也可参考这一思路避免冷缓存开销。第三步单元测试Unit Tests# 全部包 make test # 带竞态检测与覆盖率对齐 CI 拆分方式 make test-with-cover先理解底层测试驱动MakefileGOTEST_OPT? -race -timeout 25m -count1 -v GOTESTgotestsum --formattestname ---race开启 Go 竞态检测器这解释了后面「no races in changed packages」的最低门槛-timeout 25m -count1 -v单包 25 分钟超时、禁用缓存、输出详细日志gotestsum对go test输出做结构化汇总。CI 的四路测试拆分Tempo 的 CI 将测试拆成四个 Job——pkg、tempodb、tempodb/wal、others各自的本地命令为Makefilemake test-with-cover-pkg # ./pkg 下所有包 make test-with-cover-tempodb # ./tempodb 下除 wal 外的所有包GOMEMLIMIT6GiB make test-with-cover-tempodb-wal # 仅 ./tempodb/wal make test-with-cover-others # 除 pkg、tempodb 外的其余包含 modules/、cmd/ 等四个目标分别产出.coverage/pkg.out、.coverage/tempodb.out、.coverage/tempodb-wal.out、.coverage/others.out覆盖率文件。几点实现细节test-with-cover-tempodb为tempodb设置了GOMEMLIMIT6GiB因为该目录涉及 Parquet 存储引擎见 tempodb 下的encoding/vparquet3、vparquet4、vparquet5等内存敏感拆分依据正是源文件路径find . -name *.go -path ./pkg*/*等与 CI 矩阵中的test-with-cover-pkg, test-with-cover-tempodb, ...一一对应make test-with-cover本身未在 CI 使用仅是本地一次性跑全部包并生成单一all.out的便利入口Makefile 注释已注明。实践建议本地改动集中在pkg/时只跑make test-with-cover-pkg即可快速反馈改动涉及存储引擎如tempodb/encoding/vparquet5时再单独跑make test-with-cover-tempodb。第四步E2E 测试需要 DockerE2E 测试是 Tempo 质量体系的另一支柱其特点是必须先构建本地 Tempo 镜像再运行测试# 全量套件 make test-e2e # 单套件 make test-e2e-api make test-e2e-operations make test-e2e-limits make test-e2e-metrics-generator make test-e2e-storage从 Makefile 可以看到test-e2e的依赖链test-e2e: tools docker-tempo docker-tempo-query test-e2e-operations test-e2e-api \ test-e2e-limits test-e2e-metrics-generator test-e2e-storage test-e2e-util即全量套件会先构建docker-tempo、docker-tempo-query两个镜像对应cmd/tempo与cmd/tempo-query的 Dockerfile再依次执行各套件每个单套件目标同样以docker-tempo部分还有docker-tempo-query为前置依赖。文档中提到的测试目录为integration/e2e/实际在当前仓库中各套件对应 integration 下的子目录make 目标测试目录覆盖内容test-e2e-apiintegration/api查询 API、查询范围、MCP 等见 integration/api/api_test.gotest-e2e-operationsintegration/operations运维特性HTTPS、KV 存储、接收器、单二进制刷新等test-e2e-limitsintegration/limits摄入限流、查询限流test-e2e-metrics-generatorintegration/metrics-generatormetrics-generator 远程写、目标信息test-e2e-storageintegration/storage后端调度器、编码、轮询test-e2e-utilintegration/utilE2E 测试脚手架harness自身的单元测试CI 会遍历integration/下的目录并校验每个目录都有对应的test-e2e-folder-name目标见.github/workflows/ci.yml中的相关检查逻辑因此新增集成测试目录时必须在 Makefile 中同步注册目标。运行后的清理E2E 测试产物由「宿主进程创建目录、Tempo 容器以 UID 10001 写入内容」普通rm -rf会遇到权限问题。make test-e2e-clean分两步清理Makefiledocker run --rm -u 10001 -v $(shell pwd)/integration:/integration:z alpine \ find /integration -maxdepth 3 -name e2e_integration_test* -type d \ -exec sh -c find $$1 -mindepth 1 -delete _ {} \; find $(shell pwd)/integration -maxdepth 3 -name e2e_integration_test* -type d -prune -exec rm -rf {} 第一步以容器 UID 10001 清空目录内容第二步由宿主用户删除空目录。每次跑完 E2E 后都应执行make test-e2e-clean避免脏目录残留影响下次运行或污染git status。第五步开 PR 前的最低门槛Minimum Bar文档给出了开 PR 前的 5 项硬性检查任何一项不满足都不应推送make fmt——工作树不得有格式化残留CI 的check-fmt会直接 failmake lint baseorigin/main——不得引入新的 lint 错误与 CI 的--new-from-rev逻辑一致make test——全部单元测试通过go test -race ./...或make test-with-cover——改动包无竞态问题因为make test本身已带-race此条相当于在关键路径上再次确认make chlog-validate——对用户可见的改动必须存在.chloggen/条目且严禁直接编辑CHANGELOG.md。理解 Changelog 工作流chloggenTempo 使用内置于 tools/chloggen 的chloggen工具管理CHANGELOG.md完整说明见.chloggen/README.md。其设计动机是多人同时编辑一个共享的CHANGELOG.md会产生大量合并冲突因此改为「每个 PR 在.chloggen/下添加一个 YAML 小文件发布时统一汇总」。创建条目make chlog-new # 从 TEMPLATE.yaml 生成 .chloggen/当前分支名.yaml make chlog-new FILENAMEmy-change # 显式指定文件名main 分支或 detached HEAD 时必须生成的文件模板见.chloggen/TEMPLATE.yaml填写内容示例change_type: enhancement # breaking | change | feature | enhancement | bug_fix | security component: metrics-generator # 必须在 .chloggen/config.yaml 的 allowlist 中 note: A brief description of the change. issues: [] # 可选留空则发布时自动回填 PR 号 subtext: # 可选补充细节 user: your-github-handle三个关键约束change_type决定条目渲染到CHANGELOG.md的哪个小节如breaking→ Breaking changes、enhancement→ Enhancements、bug_fix→ Bug fixes完整映射见.chloggen/README.mdcomponent必须命中.chloggen/config.yaml中的 allowlist否则make chlog-validate直接拒绝新增组件需要同 PR 修改该 allowlistnote写作原则聚焦用户收益一两句话为宜。例如对 Parquet 迭代器的谓词下推优化✅Improve read performance by pushing down predicates to the parquet iterators.❌Add support for pushdown predicates in the parquet iterators.内部实现细节应放入subtext而非note。发布阶段仅维护者make chlog-update VERSIONv2.x.y会将.chloggen/下待发布条目汇总进CHANGELOG.md并删除源文件issues留空时工具从提交信息中解析 PR 号Tempo 采用 squash merge格式为... (#1234)自动回填。第六步PR 描述开 PR 时必须阅读.github/pull_request_template.md并以其结构组织 PR 正文。当前模板包含What this PR does本 PR 做了什么Which issue(s) this PR fixes修复的问题格式Fixes #issue numberChecklistTests updated、Documentation added、Changelog entry added under .chloggen/并提示用make chlog-new或make chlog-new FILENAMEname生成参见.chloggen/README.md。模板顶部还提示两点提交前阅读CONTRIBUTING.md与 main 不同步时先 rebase。一个值得注意的工程细节文档特别标注了For non-interactive tooling通过gh pr create --body / --body-file显式传 body 时会绕过 GitHub 的模板自动填充因此必须手动套用模板结构逐节填写每一项。自动化脚本或 Agent 提 PR 时这一点尤其容易踩坑。第七步评审进行中的推送规范Pushing to a PR Under Review一旦 PR 已收到评审意见不要重写评审者已经看过的历史。这是大型开源协作的黄金法则Tempo 清单将其固化为三条纪律用新提交回应评审——不要对已评审的提交执行amend、squash或rebase。新提交让评审者能精确定位「自上次评审以来发生了什么」不要对活跃评审中的分支 force push——包括git push --force-with-lease。虽然--force-with-lease能防止覆盖他人新推送的提交但它仍然改写了历史会破坏 GitHub 的「changes since your last review」视图唯一例外基于 main 的 rebase——例如为解决冲突而 rebase。如果必须做应当单独一次推送完成 rebase不混入任何其他改动并在 PR 评论中明确说明。这套规范保证了评审双方始终面对「增量」而不是反复重新 diff 已被认可的代码。完整流程速查把清单串成一次可复现的提交流水线# 1. 格式化最先做避免 CI 的 check-fmt 失败 make fmt # 2. 与 CI 完全一致的 diff 范围 lint git fetch origin make lint baseorigin/main # 3. 按改动范围跑对应单元测试拆分或全量 make test-with-cover-pkg # make test-with-cover-tempodb / make test-with-cover-tempodb-wal / make test-with-cover-others # 4. 涉及集成行为时跑 E2E需 Docker自动构建本地镜像 make test-e2e-api # ... 其他套件 make test-e2e-clean # 必做清理 Docker 容器 UID 写入的测试目录 # 5. 用户可见改动补 changelog 条目 make chlog-new # 编辑 .chloggen/分支名.yaml 后 make chlog-validate # 6. 按 .github/pull_request_template.md 组织 PR 描述 # 7. 评审期间只追加新提交不 amend/squash/rebase/force-push这七步覆盖了「提交前验证 → 提 PR → 评审迭代」的完整生命周期。它们不是 Tempo 独有的花架子格式化与 lint 的 CI 对齐、测试拆分与竞态检测、changelog 解耦、评审历史保护每一环都对应了大型 Go 分布式系统仓库的真实痛点直接复用到任何中大型 Go 项目同样成立。【免费下载链接】tempoGrafana Tempo is a high volume, minimal dependency distributed tracing backend.项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

制造业产研数据中台:元数据驱动的数字神经中枢 2026/9/17 10:59:26

制造业产研数据中台:元数据驱动的数字神经中枢

简介:本资源是一份面向制造业数字化转型从业者、数据架构师与IT系统规划人员的产研数据中台建设实战方案,聚焦解决产品研制过程中数据孤岛、标准不一、服务割裂等核心痛点。方案以32页专业PPTX形式呈现,完整覆盖数据中台建设总体架构、产品研…

阅读更多 →
彻底移除Win11右键菜单的“在记事本中编辑”选项 2026/9/17 10:59:26

彻底移除Win11右键菜单的“在记事本中编辑”选项

前些天帮朋友清理一台Win11笔记本,发现右键任意文件,菜单最上方都会冒出“在记事本中编辑”这个选项,点一下就直接用记事本打开了,而原来的“打开方式”反而被挤到后面。朋友说他没装过右键工具,系统也是自动更新上来的…

阅读更多 →
Android 13/14/15默认授权指南:从pm grant到系统源码级方案 2026/9/17 10:59:26

Android 13/14/15默认授权指南:从pm grant到系统源码级方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
知识图谱落地全指南:从本体设计到图计算应用与踩坑 2026/9/17 10:59:26

知识图谱落地全指南:从本体设计到图计算应用与踩坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
边缘端轻量级深度学习框架内存复用(Memory Arena)设计与实现 2026/9/17 10:59:26

边缘端轻量级深度学习框架内存复用(Memory Arena)设计与实现

边缘端轻量级深度学习框架内存复用(Memory Arena)设计与实现在嵌入式微控制器(如 Cortex-M4/M7)或轻量 Linux 边缘设备上运行深度学习推理时,系统面临的最严苛物理约束不是算力,而是 RAM 内存容量&#xff…

阅读更多 →
InoProShop下PLC的Modbus TCP从站配置与实战解析 2026/9/17 10:56:18

InoProShop下PLC的Modbus TCP从站配置与实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞