news 2026/9/29 7:08:11

Woodpecker 状态徽章(Status Badge)集成指南:端点、参数与渲染原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Woodpecker 状态徽章(Status Badge)集成指南:端点、参数与渲染原理
  • CI/CD
  • DevOps

【免费下载链接】woodpecker

Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.

项目地址:https://gitcode.com/gh_mirrors/wo/woodpecker
点击查看免费下载

状态徽章(Status Badge)是 Woodpecker CI/CD 内置的仓库状态展示能力,可通过一个 SVG 图片端点把默认分支上最近一次流水线的构建结果直接嵌入到网站首页或项目 README 中。本文将以 80-badges.md 为主线,结合 server/api/badge.go、server/badges/badges.go 等源码,完整讲解徽章端点的 URL 结构、branch/events/workflow/step等查询参数、状态与颜色映射规则,以及后端从取数到渲染 SVG 的完整调用链,帮助你快速把 Woodpecker 流水线状态接入任何外部页面。

什么是状态徽章

Woodpecker 为每个仓库内置了状态徽章(status badge)支持。徽章本质上是一张由服务端动态生成的 SVG 图片,展示仓库代码的流水线构建状态,可以方便地嵌入到你的网站或项目 README 文件中。与直接查看 Web UI 相比,徽章是一种轻量、可分享、可嵌入的实时状态展示方式,非常适合开源项目首页、文档站点或团队内部看板。

徽章由服务端渲染并即时返回,其内容始终反映当前仓库最近一次流水线的真实结果,而不是一张静态图片,因此无需手动更新。

徽章端点(Badge Endpoint)

状态徽章的访问端点为:

<scheme>://<hostname>/api/badges/<repo-id>/status.svg

其中<scheme>与<hostname>是你部署的 Woodpecker 服务地址,<repo-id>是仓库在 Woodpecker 中的数字 ID。例如,如果你的服务部署在https://ci.example.com,仓库 ID 为42,则徽章 URL 为:

https://ci.example.com/api/badges/42/status.svg

在 README 中通常这样嵌入:

![Woodpecker Build Status](https://ci.example.com/api/badges/42/status.svg)

值得注意的是,路由的实际注册方式支持两种形式。从 server/router/api.go 可以看到,徽章端点同时注册了按仓库 ID 和按「所有者 + 仓库名」两种路径:

badges := apiBase.Group("/badges/:repo_id_or_owner") { badges.GET("/status.svg", api.GetBadge) badges.GET("/cc.xml", api.GetCC) } _badges := apiBase.Group("/badges/:repo_id_or_owner/:repo_name") { _badges.GET("/status.svg", api.GetBadge) _badges.GET("/cc.xml", api.GetCC) }

对应到 server/api/badge.go 中的处理逻辑:如果 URL 中带有repo_name参数,则按owner/repo名称查询仓库;否则将repo_id_or_owner解析为数字仓库 ID。也就是说,除了数字 ID,你也可以用可读的仓库名形式:

<scheme>://<hostname>/api/badges/<owner>/<repo>/status.svg

例如https://ci.example.com/api/badges/woodpecker-ci/woodpecker/status.svg。需要提醒的是,数字 ID 形式要求传入合法整数,否则接口会直接返回400 Bad Request。

指定分支:branch 参数

状态徽章默认展示默认分支(例如main)上最近一次构建的状态。你可以在查询字符串中追加branch参数来指定其他分支:

-<scheme>://<hostname>/api/badges/<repo-id>/status.svg +<scheme>://<hostname>/api/badges/<repo-id>/status.svg?branch=<branch>

例如展示develop分支的状态:

https://ci.example.com/api/badges/42/status.svg?branch=develop

从源码看,branch参数的默认值取自仓库配置的默认分支。在 server/api/badge.go 中:

branch := c.Query("branch") if len(branch) == 0 { branch = repo.Branch }

也就是说:显式传入branch时使用传入值,否则回退到仓库的默认分支。查询底层落在 server/store/datastore/pipeline.go 的GetPipelineBadge:

func (s storage) GetPipelineBadge(repo *model.Repo, branch string, events []model.WebhookEvent) (*model.Pipeline, error) { pipeline := new(model.Pipeline) return pipeline, wrapGet(s.engine. Desc("number"). Where(builder.Eq{"repo_id": repo.ID, "branch": branch}). Where(builder.In("event", events)). Where(builder.Neq{"status": model.StatusBlocked}). Get(pipeline)) }

可见徽章取的是该分支上number最大的流水线,同时要求其事件类型在指定集合内、且状态不是blocked(例如因审批门控被阻塞的流水线不会被计入)。

限定事件类型:events 参数

默认情况下,状态徽章不包含拉取请求(pull request)的结果,因为 PR 的构建状态并不能准确代表仓库主干代码的真实状态。默认徽章只反映最近一次push 事件的状态。

如果你希望纳入其他或更多事件类型,可以追加events查询参数,多个事件用逗号分隔:

-<scheme>://<hostname>/api/badges/<repo-id>/status.svg +<scheme>://<hostname>/api/badges/<repo-id>/status.svg?events=manual,cron

例如同时统计push、tag与manual事件:

https://ci.example.com/api/badges/42/status.svg?events=push,tag,manual

events参数可用的合法取值定义在 server/model/const.go 中,完整枚举如下:

事件值含义
push代码推送(默认)
pull_request拉取请求
pull_request_closed拉取请求关闭
pull_request_metadata拉取请求元数据变更
tag标签推送
release发布
deployment部署
cron定时任务触发
manual手动触发

在 server/api/badge.go 中,未传events时默认使用push;传入了则按逗号切分,并逐一对事件值调用Validate()校验,遇到非法值会返回400 Bad Request:

var events []model.WebhookEvent eventsQuery := c.Query("events") // If none given, fallback to default "push" if len(eventsQuery) == 0 { events = []model.WebhookEvent{model.EventPush} } else { strEvents := strings.Split(eventsQuery, ",") events = make([]model.WebhookEvent, len(strEvents)) for i, strEvent := range strEvents { event := model.WebhookEvent(strEvent) if err := event.Validate(); err == nil { events[i] = event } else { _ = c.AbortWithError(http.StatusBadRequest, err) return } } }

更细粒度:workflow 与 step 参数

除了文档中提到的branch与events,server/api/badge.go 还支持按工作流(workflow)甚至按具体步骤(step)生成徽章,这在多工作流配置中非常实用:

  • workflow=<name>:徽章只统计指定工作流的运行状态,文案(subject)从默认的pipeline变为工作流名称;
  • 在指定workflow的基础上追加step=<name>:文案变为<workflow>: <step>,只反映该步骤的状态。

实现上,GetBadge会先取出该流水线的完整工作流树(WorkflowGetTree),再按名称匹配工作流及其子步骤,并将多个匹配结果通过pipeline.MergeStatusValues合并成一个聚合状态。多工作流配置的写法可参考 25-workflows.md。

状态标签与颜色映射

徽章右侧的状态文案与颜色由 server/badges/badges.go 中的getBadgeStatusLabelAndColor决定:

流水线状态徽章文案徽章颜色
successsuccess绿色(#44cc11)
failurefailure红色(#e05d44)
pending/runningstarted黄色(#dfb317)
error/killederror灰色(#9f9f9f)
其他 / 无记录none灰色(#9f9f9f)

值得注意的细节是:当仓库里查不到符合条件的流水线时,徽章不会报错,而是显示灰色的none。这一点在 server/api/badge.go 中有明确注释(“display the 'none' badge, instead of throwing an error response”),且ErrRecordNotExist之外的查询错误只会被记录日志而不会导致 5xx。

后端渲染链路:从请求到 SVG

一次徽章请求的完整链路如下:

  1. 路由匹配:/api/badges/:repo_id_or_owner[/:repo_name]/status.svg命中api.GetBadge(见 server/router/api.go);
  2. 仓库解析:按 ID 或owner/repo名称加载仓库(server/api/badge.go);
  3. 参数归一:解析branch、events,必要时解析workflow、step;
  4. 取最新流水线:GetPipelineBadge按repo_id、branch、事件集合查询number最大的流水线(server/store/datastore/pipeline.go);
  5. 生成 SVG:badges.Generate(name, status)根据状态映射文案与颜色,调用RenderBytes渲染出 SVG(server/badges/badges.go);
  6. 返回响应:响应头设置为Content-Type: image/svg+xml,返回 200 与 SVG 内容(server/api/badge.go)。

SVG 的绘制实现在 server/badges/drawer.go 中:它使用内置的DejaVuSans字体测量文案宽度(字号 11、DPI 72),再通过 HTML 模板(flat 风格、圆角矩形、平滑渐变)拼出最终的扁平徽章;字体资源内嵌在 server/badges/fonts 目录中,因此徽章服务不依赖外部字体或图片资源。由于渲染器内部使用互斥锁与sync.Once单例初始化(drawer.go),并发请求下依然线程安全。

验证与测试

仓库自带一组徽章渲染的单元测试,位于 server/badges/badges_test.go,其中TestGenerate覆盖了success、failure、error、killed、pending、running及未知状态共 7 种场景,并逐字节断言生成的 SVG 与预期一致;TestBadgeDrawerRender则验证了文案宽度测量与模板渲染的坐标计算结果。

你也可以直接通过命令行验证徽章端点的实际输出:

curl -s "https://<hostname>/api/badges/<repo-id>/status.svg?branch=main"

返回的即是一段image/svg+xml文本。若返回的 XML 中状态为none,说明该分支上还没有符合条件的流水线记录。

延伸:CCMenu 徽章(cc.xml)

除status.svg外,server/router/api.go 还注册了/api/badges/<repo_id>/cc.xml端点,对应 server/api/badge.go 中的GetCC。它按 CCTray v1 规范输出 XML 格式的流水线状态,供 macOS 菜单栏工具 CCMenu 订阅展示。虽然本文档未展开讲解,但它与状态徽章共用同一批路由与仓库解析逻辑,可作为需要桌面端状态通知时的补充方案。

小结

Woodpecker 的状态徽章开箱即用、无需额外配置,只需拼接/api/badges/<repo-id>/status.svg即可嵌入任意页面。核心要点可归纳为:

  • 默认展示默认分支最近一次 push 事件的流水线状态;
  • 用?branch=切换分支,用?events=纳入更多事件类型(如manual、cron、tag);
  • 进阶可用?workflow=与?step=做更细粒度的状态展示;
  • 无记录时优雅降级为灰色none,不会破坏页面布局;
  • 整个功能由 server/api/badge.go → server/store/datastore/pipeline.go → server/badges 三段代码协同完成,状态映射与 SVG 渲染均有测试用例可查。

将徽章放入 README 的第一屏,或嵌入团队文档站点,即可让所有访问者一眼看到主干代码的最新构建健康状况。

  • CI/CD
  • DevOps

【免费下载链接】woodpecker

Woodpecker is a simple, yet powerful CI/CD engine with great extensibility.

项目地址:https://gitcode.com/gh_mirrors/wo/woodpecker
点击查看免费下载

相关推荐

上一篇:AWS CLI 实战:用 describe-alarms-for-metric 按指标精准查询 CloudWatch 告警
下一篇:RuboCop v0.52.1 发布说明源码级解读:25 项缺陷修复与 4 项行为变更全解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 7:07:55

近似模型实战:别较真参数,关注误差与稳定性

先讲一个我自己踩过的坑。前几年做供应链需求预测&#xff0c;我花了一整周调一个XGBoost的参数&#xff0c;学习率从0.05换成0.03&#xff0c;树的深度从6试到9&#xff0c;恨不得每换一个参数就把网格搜索重跑一遍。结果线上效果几乎没变化&#xff0c;倒是训练时间翻了一倍。…

作者头像 李华
网站建设 2026/9/29 7:06:42

测试文件生成完整方案:普通文件、可播放视频与可显示图片

测试文件到底怎么生成&#xff0c;这里我摸索出了一套完整方案。尤其是需要"可播放的视频"或"可正常显示的图片"时&#xff0c;不能简单拿随机字节去填充&#xff0c;里面有不少细节坑。之所以想写这篇&#xff0c;是因为上周帮别人搞一个上传接口的压测&a…

作者头像 李华
网站建设 2026/9/29 7:06:37

从后见之明偏差到浏览器取证:Hindsight 工具实战解析

“hindsight”这个词&#xff0c;我第一次认真琢磨是在两个完全不同的场景里。一次是在产品复盘会上&#xff0c;同事拍着桌子说“这个风险我们早该预判到的”&#xff1b;另一次是研究浏览器取证工具时&#xff0c;看到 GitHub 上 obsidianforensics/hindsight 这个开源项目。…

作者头像 李华
网站建设 2026/9/29 7:03:51

AI搜索优化服务商 AI搜索SEO找哪家

随着AI搜索、生成式问答、智能助手逐渐成为新的流量入口&#xff0c;企业争夺的已经不只是传统搜索引擎排名&#xff0c;还有AI答案中的“被推荐权”。尤其是工厂、建材、工程类企业&#xff0c;客户决策链长、项目金额高&#xff0c;如果能在AI搜索和全网搜索中被看见、被信任…

作者头像 李华
网站建设 2026/9/29 7:03:46

支付回调验签与订单查询的四个坑排查实录

一、现象&#xff1a;收款成功了&#xff0c;订单却还挂着"未支付" 先交代来源&#xff1a;这个问题是我在做一款本地化部署的微信自动回复工具时踩到的&#xff0c;工具按坐席收年费&#xff0c;需要一个能用的在线收款通道&#xff0c;于是接了一家聚合支付的网关。…

作者头像 李华
网站建设 2026/9/29 7:03:45

手把手教小白用AI五分钟做数据可视化(附步骤拆解与Prompt)

如果你是零基础&#xff0c;又想快速做出专业的数据图表&#xff0c;这篇教程就是为你写的。 我会把每一步都拆到最细&#xff0c;你只需要照着做。先看成品&#xff1a;这篇教程能带你做出什么可交互 HTML 数据看板全程耗时约 5 分钟 &#xff5c; 代码量 0 行 &#xff5c; 工…

作者头像 李华