ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Woodpecker 配置扩展(Configuration Extension)完全指南:通过 HTTP 端点按需修改与生成流水线配置

Woodpecker 配置扩展(Configuration Extension)完全指南:通过 HTTP 端点按需修改与生成流水线配置 CI/CDDevOps【免费下载链接】woodpeckerWoodpecker is a simple, yet powerful CI/CD engine with great extensibility.项目地址https://gitcode.com/gh_mirrors/wo/woodpecker点击查看免费下载配置扩展Configuration Extension是 Woodpecker 提供的一种扩展机制它允许你注册一个 HTTP 端点在每次流水线触发时接管或改造流水线配置——可以预处理 YAML、为配置补全默认步骤、把 GitLab CI / Starlark / Jsonnet 等其他格式转换为 Woodpecker 官方格式甚至把多个仓库的流水线配置集中到一个中心服务统一管理。阅读本文后你将掌握配置扩展的请求/响应协议、全局与仓库级两种配置方式、exclusive独占模式以及请求签名验证等安全要点并能基于仓库源码理解其底层调用链。什么是 Configuration Extension在 Woodpecker 中配置扩展用于修改或生成流水线配置。你可以在仓库设置的 Extensions 标签页中配置一个 HTTP 端点当流水线被触发时Woodpecker 会调用该端点并执行其返回的配置。使用配置扩展的典型场景包括预处理原始配置文件例如先用 Go 模板Go templating渲染后再执行将自定义属性转换为 Woodpecker 属性为配置补充默认值例如注入默认步骤将完全不同的格式如 GitLab CI config、Starlark、Jsonnet 等转换为 Woodpecker 配置集中管理多个仓库的配置将配置逻辑统一维护在一处。在编写自己的配置扩展之前建议先阅读 Extensions 总览了解 Woodpecker 的三种扩展类型配置扩展、Registry 扩展、Secret 扩展及其共同的配置与安全基础。安全为什么必须校验请求签名:::warning Woodpecker 会向扩展传递令牌等私有信息并且会执行扩展返回的配置因此保护外部扩展的安全极其重要。 :::Woodpecker 使用 HTTP SignaturesHTTP 签名对发往扩展的每一个请求签名签名基于一对ed25519 公钥/私钥。扩展端必须使用公钥验证所有请求的签名才能确认请求确实来自你的 Woodpecker 服务而非伪造请求否则攻击者可诱导扩展返回恶意流水线配置。更多细节见 Extensions 总览中的安全小节。获取 Woodpecker 的公钥有两种方式访问接口http://my-woodpecker.tld/api/signature/public-key对应源码 signature_public_key.go 中的GetSignaturePublicKey路由注册见 api.go在 Woodpecker UI 中进入仓库设置打开 Extensions 页面查看。从源码看服务端在启动时会通过setupSignatureKeys见 setup.go生成或从存储加载 ed25519 密钥对并以signature-private-key为键持久化因此服务重启后签名公钥保持稳定。发往扩展的 HTTP 客户端由 http.go 构建它使用httpsign库以 ed25519 私钥对request-target和自动生成的content-digest头签名签名标识keyId为woodpecker-ci-extensions扩展端验签时应使用相同的头部集合与 keyId。全局配置除了在每个仓库中单独配置扩展你还可以在 Woodpecker服务器配置中设置一个全局端点让所有仓库共用同一个配置扩展。需要特别注意的是如果你与他人共享同一个 Woodpecker 服务器其他用户也会使用你的配置扩展务必确认可以信任。全局配置通过如下环境变量设置WOODPECKER_CONFIG_EXTENSION_ENDPOINThttps://example.com/ciconfig对应的 CLI 标志定义见 flags.go。与全局配置扩展相关的三个环境变量如下环境变量对应 CLI 标志说明WOODPECKER_CONFIG_EXTENSION_ENDPOINTconfig-extension-endpoint全局配置服务端点 URL为空时不启用全局扩展历史别名WOODPECKER_CONFIG_SERVICE_ENDPOINT/config-service-endpoint仍可用计划在 v4.0.0 移除WOODPECKER_CONFIG_EXTENSION_EXCLUSIVEconfig-extension-exclusive是否让全局扩展独占exclusive为true时跳过 forge 直接只调用扩展WOODPECKER_CONFIG_EXTENSION_NETRCconfig-extension-netrc是否向全局扩展发送 netrc 凭据默认false调用顺序如果全局与仓库级扩展都配置了并且仓库未启用 exclusive 设置那么全局扩展会先被调用仓库级扩展随后被调用。这一链路在源码中由setupConfigServicesetup.go和combined服务combined.go实现全局扩展配置存在时先用 forge 获取仓库原始配置config.NewForge再追加 HTTP 扩展通过config.NewCombined(configFetcher, httpFetcher)依次链式调用后一个服务的输出作为前一个服务的输入。工作原理当流水线被触发时Woodpecker 首先从仓库forge获取流水线配置然后向配置的扩展端点发送一个HTTP POST 请求请求体为 JSON 负载包含仓库信息、流水线信息以及从仓库获取到的当前配置文件。扩展可以返回修改后的、甚至是全新的流水线配置但必须遵循 Woodpecker 官方的 YAML 格式。你可以启用exclusive独占设置全局和仓库级均可此时 Woodpecker只调用你的扩展不再做其他任何事也就是说可以完全跳过 forge——请求中也不会附带任何配置文件configuration字段为空。结合源码看具体行为manager.go若仓库设置了ConfigExtensionEndpoint且ConfigExtensionExclusive为true只使用config.NewHTTP(...)完全跳过 forge若仓库设置了端点但非独占使用config.NewCombined(m.config, config.NewHTTP(...))即先走全局配置链路再调用仓库级扩展两个布尔开关与端点均持久化在仓库模型上见 repo.go 中的config_extension_endpoint、config_extension_exclusive、config_extension_netrc字段。请求Request扩展收到的是一个 HTTP POST 请求JSON 负载结构如下TypeScript 描述class Request { repo: Repo; pipeline: Pipeline; netrc?: Netrc; // only included when netrc sending is enabled (see above) configuration?: { // list of configurations. Not send if there was none. name: string; // filename of the configuration file data: string; // content of the configuration file }[]; }字段说明repo仓库信息对应 仓库模型pipeline本次流水线信息对应 流水线模型netrc仅在开启 netrc 发送时包含。全局开关为WOODPECKER_CONFIG_EXTENSION_NETRCtrue默认false仓库级则勾选仓库设置中的 Send netrc credentials对应config_extension_netrc字段。netrc 数据对应 netrc 模型包含machine、login、password与type字段configuration从仓库取到的配置文件列表文件名 内容。若仓库没有配置文件则该字段不发送。:::tipnetrc数据非常强大因为它包含访问仓库的凭据。你可以用它克隆仓库甚至可以调用 forgeGitHub、GitLab 等的 API 获取关于仓库的更多信息。 :::一个完整的请求示例{ repo: { id: 100, uid: , user_id: 0, namespace: , name: woodpecker-test-pipeline, slug: , scm: git, git_http_url: , git_ssh_url: , link: , default_branch: , private: true, visibility: private, active: true, config: , trusted: false, protected: false, ignore_forks: false, ignore_pulls: false, cancel_pulls: false, timeout: 60, counter: 0, synced: 0, created: 0, updated: 0, version: 0 }, pipeline: { author: myUser, author_avatar: https://myforge.com/avatars/d6b3f7787a685fcdf2a44e2c685c7e03, author_email: myemail.com, branch: main, changed_files: [some-filename.txt], commit: 2fff90f8d288a4640e90f05049fe30e61a14fd50, created_at: 0, deploy_to: , enqueued_at: 0, error: , event: push, finished_at: 0, id: 0, link_url: https://myforge.com/myUser/woodpecker-testpipe/commit/2fff90f8d288a4640e90f05049fe30e61a14fd50, message: test old config\n, number: 0, parent: 0, ref: refs/heads/main, refspec: , clone_url: , reviewed_at: 0, reviewed_by: , sender: myUser, signed: false, started_at: 0, status: , timestamp: 1645962783, title: , updated_at: 0, verified: false }, configuration: [ { name: .woodpecker.yaml, data: steps:\n - name: backend\n image: alpine\n commands:\n - echo \Hello there from Repo (.woodpecker.yaml)\\n } ], netrc: { machine: myforge.com, login: myUser, password: forge-access-token } }这个结构与源码 http.go 中的requestStructure完全对应repo、pipeline、netrc、configuration带omitempty无配置时不发送。注意请求中configuration里的data是字符串源码中先经string(oldConfig.Data)转换YAML 换行会以\n字面形式编码在 JSON 字符串中。响应Response扩展应以 JSON 负载响应返回新的配置文件列表格式为 Woodpecker 官方 YAMLclass Response { configs: { name: string; // filename of the configuration file data: string; // content of the configuration file }[]; }如果扩展希望保留现有配置文件不做任何修改可以直接返回 HTTP 状态码204 No Content此时 Woodpecker 会沿用原来的配置继续执行而不会报错。一个响应示例{ configs: [ { name: central-override, data: steps:\n - name: backend\n image: alpine\n commands:\n - echo \Hello there from ConfigAPI\\n } ] }从 http.go 的responseStructure可以看出Woodpecker 只解析configs字段并将其转换为内部FileMeta列表namedata字节交给后续流程解析执行。同时源码对状态码的处理非常明确http.go200 OK解析响应体中的configs作为新配置204 No Content返回原始配置视为未修改其他状态码返回错误流水线配置获取失败。网络访问限制WOODPECKER_EXTENSIONS_ALLOWED_HOSTS为防止扩展被用于调用本地服务SSRF 风险默认情况下扩展请求只允许访问外部主机/公网 IP。可以通过WOODPECKER_EXTENSIONS_ALLOWED_HOSTS环境变量改变这一行为使用逗号分隔的列表支持以下取值内置网络类别loopbackIPv4 的 127.0.0.0/8 与 IPv6 的 ::1/128包含 localhostprivateRFC 191810.0.0.0/8、172.16.0.0/12、192.168.0.0/16与 RFC 4193FC00::/7即 LAN/内网地址external合法的非私有单播 IP即可以访问公网上的所有主机*允许所有主机。CIDR 列表如 IPv4 的1.2.3.0/8、IPv6 的2001:db8::/32通配主机名如example.com、*.example.com、192.168.100.*。该配置对应的 CLI 标志为extensions-allowed-hosts默认值为内置的external见 flags.go。底层实现中客户端通过hostmatcher.NewDialContext对每次拨号进行主机匹配拦截见 http.go未在允许列表中的主机将无法建立连接。源码级实现要点调用链仓库级扩展组装位于 manager.go全局扩展组装位于 setupConfigServicecombined服务按顺序把上一个服务产出的文件列表传给下一个服务combined.go。forge 侧配置获取config.NewForgeforge.go负责按默认配置路径顺序从仓库拉取文件。默认查找顺序定义在 constant.go.woodpecker/、.woodpecker.yaml、.woodpecker.yml可通过WOODPECKER_DEFAULT_PIPELINE_CONFIGS覆盖扫描配置目录时默认只识别.yaml、.yml扩展名WOODPECKER_DEFAULT_PIPELINE_CONFIG_EXTENSIONS见 flags.go。HTTP 客户端行为扩展请求的超时时间为 10 秒并内置指数退避重试最大重试 3 次仅对网络错误、超时和 5xx 状态码重试4xx 客户端错误不重试http.go。因此在实现扩展时保证端点在 10 秒内响应、并对重复请求保持幂等是更稳妥的做法。测试验证配置扩展的端到端行为签名校验、204 保底、配置覆盖在 combined_test.go 中有完整测试测试服务端用httpsign.NewEd25519Verifier校验woodpecker-ci-extensions签名对Use old config场景返回204 No Content以验证沿用旧配置对其他场景返回覆盖后的configs列表。实战建议从零实现一个配置扩展只需暴露一个 POST 端点先读取并验签请求使用 ed25519 公钥校验request-target与content-digest头再按需转换request.configuration最后返回{configs: [...]}或204。集中式配置中心可以忽略请求中的configuration直接根据repo与pipeline字段如repo.name、pipeline.branch、pipeline.event从中心仓库/数据库生成配置配合全局端点 exclusive 模式即可完全脱离仓库内的配置文件。逐步改造迁移如果不启用 exclusiveWoodpecker 会先取仓库配置再交给扩展扩展可在configuration中读取原始内容做增量修改未命中规则时返回204 No Content即可优雅降级不影响未配置的仓库。安全底线始终校验签名、只接受受信任的调用方并注意返回的配置会被实际执行若与外部共享服务器慎重启用全局扩展。相关文档可继续阅读 Extensions 总览、Registry 扩展 与 Secret 扩展。赞分享CI/CDDevOps【免费下载链接】woodpeckerWoodpecker is a simple, yet powerful CI/CD engine with great extensibility.项目地址https://gitcode.com/gh_mirrors/wo/woodpecker点击查看免费下载相关推荐Woodpecker 插件体系完全指南从流水线配置到自定义插件开发Woodpecker 插件体系完全指南从流水线配置到自定义插件开发 Woodpecker 的插件Plugin本质上是执行预定义任务的流水线步骤pipelCI/CDDevOpsNuxt 模块系统完全指南扩展核心、配置加载与按需禁用Nuxt 模块系统完全指南扩展核心、配置加载与按需禁用 Nuxt 定位为 full stack Vue framework而模块Modules正是它前端后端Web框架SSRKubero CI/CD流水线完全配置指南从零到精通Kubero CI/CD流水线完全配置指南从零到精通 Kubero是一款免费的自托管PaaS平台可作为Heroku、Netlify、Coolify、Verc云原生后端运维上一篇ELLA项目贡献指南如何提交PR与参与社区讨论下一篇OfficeCLI未来路线图AI原生Office工具的发展趋势与规划创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表