CI/CDDevOps【免费下载链接】woodpeckerWoodpecker is a simple, yet powerful CI/CD engine with great extensibility.项目地址https://gitcode.com/gh_mirrors/wo/woodpecker点击查看免费下载本篇技术指南基于 Woodpecker CI/CD 引擎当前仓库版本 3.16 文档体系讲解advanced-usage中四类高频进阶玩法利用 YAML 锚点anchors aliases与映射/序列合并消除流水线配置重复、在步骤之间持久化与传递环境变量、通过服务端WOODPECKER_ENVIRONMENT声明全局变量以及搭建受信任项目内的 Docker-in-DockerdindTLS 通信环境。读完本文你将能写出更精简、可维护的 Woodpecker 流水线并安全地在 CI 步骤中操作 Docker 守护进程。一、高级 YAML 语法把流水线配置当成可编程结构Woodpecker 的流水线文件.woodpecker.yml本质上是 YAML 文档。对于包含大量重复片段相同的镜像、相同的插件参数、相同的前置/后置命令的流水线YAML 本身提供的锚点、别名与合并语法就是最好的变量机制——无需学习任何新的 DSL直接用标准 YAML 特性即可减少重复。Woodpecker 在解析阶段对此有直接支持流水线解析入口 pipeline/frontend/yaml/parse.go 中的Unmarshal调用xyaml.NewParser(xyaml.WithDepth(maxMergeDepth))来完成反序列化其中maxMergeDepth被设为 15专门用于解析深层嵌套的序列合并sequence merge。也就是说只要合并嵌套深度不超过该限制Woodpecker 都能正确处理。在 pipeline/frontend/yaml/parse_test.go 中也有对应测试用例验证了锚点别名simpleYamlAnchors与variables段合并sampleVarYaml的解析结果。提示variables这一顶层字段在官方 JSON Schemapipeline/frontend/yaml/linter/schema/schema.json中被正式收录其描述为Use yaml aliases to define variables即专门用于承载 YAML 别名定义。1.1 锚点Anchors与别名Aliases为重复值起个名字锚点name给一个值打上标签别名*name在后续位置引用该值。对于多个步骤共用同一镜像这类场景这是最直接的消重手段。假设原始的流水线长这样steps: - name: test image: golang:1.18 commands: go test ./... - name: build image: golang:1.18 commands: buildgolang:1.18被重复写了两次。新增一个名为variables的段落用锚点定义镜像再用别名替换variables: - golang_image golang:1.18 steps: - name: test - image: golang:1.18 image: *golang_image commands: go test ./... - name: build - image: golang:1.18 image: *golang_image commands: build之后若需升级 Go 版本只需修改variables中的一处定义所有步骤同步生效。Woodpecker 的解析测试也覆盖了类似场景simpleYamlAnchors用vars段定义image: image plugins/slack随后步骤中image: *image引用最终被正确解析为plugins/slack见 pipeline/frontend/yaml/parse_test.go。1.2 映射合并与覆盖Map merges and overwrites组合插件参数当多个步骤使用同一插件但参数略有差异时可以使用合并键:将多份映射合并到当前映射中并允许按需覆盖或追加键值variables: - base-plugin-settings target: dist recursive: false try: true - special-setting special: true - some-plugin codeberg.org/6543/docker-images/print_env steps: - name: develop image: *some-plugin settings: : [*base-plugin-settings, *special-setting] # 将两个映射合并进一个空映射 when: branch: develop - name: main image: *some-plugin settings: : *base-plugin-settings # 合并一个映射并 ... try: false # ... 覆盖原值 ongoing: false # ... 追加新值 when: branch: main上例中develop步骤合并了基础参数与special参数main步骤则在此基础上把try从true覆盖为false并追加ongoing: false。合并后的最终效果等价于手写完整的settings映射但维护点只剩variables一处。在 pipeline/frontend/yaml/parse_test.go 的sampleVarYaml中可以看到真实可解析的合并写法variables: SLACK定义锚点后notify_fail: *SLACK直接整体引用notify_success则用 : *SLACK合并后追加when约束——这是官方测试用例验证过的合法用法可作为模板参考。1.3 序列合并Sequence merges给步骤拼接公共命令序列除了合并映射:还可以用于合并序列list。典型场景是所有步骤都需要执行相同的前置初始化命令与后置收尾命令variables: pre_cmds: pre_cmds - echo start - whoami post_cmds: post_cmds - echo stop hello_cmd: hello_cmd - echo hello steps: - name: step1 image: debian commands: - : *pre_cmds # 前置拼接一段序列 - echo exec step now do dedicated things - : *post_cmds # 后置拼接一段序列 - name: step2 image: debian commands: - : [*pre_cmds, *hello_cmd] # 前置拼接两段序列 - echo echo from second step - : *post_cmds最终step1的commands等价于echo start、whoami、专属命令、echo stop五条step2则在专属命令前插入了pre_cmds与hello_cmd共三条命令。这种公共命令序列 专属命令的组合方式非常适合统一注入日志标记、环境探测或构建产物收集等样板逻辑。1.4 参考资料YAML 1.2.2 规范Anchors and AliasesYAML cheat sheetLearn X in Y minutes二、在步骤之间持久化环境数据source 文件法容器步骤各自独立运行一个步骤中export的环境变量不会自动传递给下一个步骤。最轻量的解决方案是让某个步骤把变量写入文件后续步骤source该文件后即可读取。steps: - name: init image: bash commands: - echo FOOhello envvars - echo BARworld envvars - name: debug image: bash commands: - source ./envvars - echo $FOO要点说明init步骤把FOOhello、BARworld追加写入工作区中的envvars文件同一流水线的后续步骤默认共享工作区workspace因此debug步骤能够读取到该文件source ./envvars后即可使用$FOO、$BAR该方法仅适用于共享工作区的后端如 docker、local 等且要求步骤镜像内自带 shell 与source能力如bash、debian等镜像。这是步骤间传值的通用手法适用于无需经过服务端、也不想暴露在全局环境中的临时数据。三、声明全局变量服务端 WOODPECKER_ENVIRONMENT如果某些变量需要注入到所有流水线的所有步骤可以在 Woodpecker 服务端声明全局环境变量。用法在 全局环境变量文档 中有详细说明WOODPECKER_ENVIRONMENTfirst_var:value1,second_var:value2该配置在服务端启动参数中对应environment标志--environment定义于 cmd/server/flags.go。从源码实现看server/services/environment/parse.go 中的Parse函数使用strings.Cut(item, :)按冒号将每个key:value拆分为名称与值随后在流水线构建阶段server/pipeline/items.go 通过EnvironList拉取全部全局变量并逐项写入envs映射最终注入到每个工作流的编译选项中。也就是说服务端重启或配置变更后新流水线会携带这些全局变量。一个典型场景是统一管理多项目共用的镜像标签WOODPECKER_ENVIRONMENTGOLANG_VERSION:1.18steps: - name: build - image: golang:1.18 image: golang:${GOLANG_VERSION} commands:注意事项全局注入耦合明显该方式把服务端配置与应用使用该流水线的业务应用配置紧密耦合在一起——应用是完全独立的程序却隐式依赖服务端声明的变量名。因此它只适合真正全局、所有应用所有步骤都该有的变量不可覆盖内置变量全局环境变量不能覆盖 Woodpecker 已有的内置变量built-in variables如CI_*系列这一点在 环境变量文档 中已明确说明变量可被引用全局变量注入后可在步骤的image、commands、settings等位置通过${VAR}形式展开引用如上面的镜像标签示例。四、Docker in Dockerdind配置在步骤里操作 Docker 守护进程4.1 安全前提仅限受信任仓库:::warning 安全警告 该方案仅对受信任trusted仓库生效且出于安全原因只应在私有环境使用。 请在 项目设置 中开启 trusted 模式trusted 项目会为步骤及其底层容器授予挂载卷、提升权限等能力。 :::从实现侧看privileged标志会直接映射到容器运行参数在 docker 后端中pipeline/backend/docker/convert.go 将步骤的Privileged字段透传给容器配置。因此请在确信流水线内容可信的前提下再开启该能力。提示如果你的目标只是构建/发布 OCI 镜像而不是在 CI 中自由操作 Docker 守护进程更推荐使用 Docker Buildx 插件woodpecker-ci.org 官方插件生态提供而非 dind 方案。4.2 第一步定义以dind标签运行的 Docker 服务需要定义一个运行docker:dind镜像的 service并且该服务必须以privileged: true运行services: - name: docker image: docker:dind # 生产环境建议使用 docker:major-version-dind 之类的固定版本标签 privileged: true ports: - 23764.3 第二步用 TLS 建立客户端与守护进程的安全通信自 Docker v27 起未认证的 TCP 连接已被弃用v28 将直接报错因此必须启用 TLS。推荐做法是让 dind 守护进程自行生成 TLS 证书再通过 Agent 侧的卷挂载把证书共享给客户端步骤。给服务补充证书目录与卷挂载services: - name: docker image: docker:dind # 生产环境建议使用 docker:major-version-dind 之类的固定版本标签 privileged: true environment: DOCKER_TLS_CERTDIR: /dind-certs volumes: - /opt/woodpeckerci/dind-certs:/dind-certs ports: - 2376DOCKER_TLS_CERTDIR/dind-certs会让 dind 守护进程把生成的证书写入该目录卷挂载则把宿主机路径/opt/woodpeckerci/dind-certs与容器内路径共享供客户端步骤使用。4.4 第三步在客户端步骤中配置 DOCKER_* 环境变量在需要与守护进程通信的 docker 客户端步骤中按下表设置DOCKER_*系列环境变量这些是 Docker 生态通用的标准变量框架无关——像 TestContainers、Spring Boot Docker Compose 等框架都会遵循它们因此即使步骤内运行的不是裸dockerCLI 而是某个框架同样能连上守护进程环境变量值作用DOCKER_HOSTtcp://docker:2376指向 dind 服务的 TCP 端点服务名 端口DOCKER_CERT_PATH/dind-certs/clientTLS 客户端证书所在目录DOCKER_TLS_VERIFY1强制校验 TLS 连接把证书卷挂载到守护进程生成证书的位置本例为/opt/woodpeckerci/dind-certs。用docker version验证连接steps: - name: test image: docker:cli # 生产环境建议使用 docker:major version-cli 之类的固定版本标签 environment: DOCKER_HOST: tcp://docker:2376 DOCKER_CERT_PATH: /dind-certs/client DOCKER_TLS_VERIFY: 1 volumes: - /opt/woodpeckerci/dind-certs:/dind-certs commands: - docker version若一切配置正确该步骤应同时输出服务端server与客户端client的版本信息。4.5 完整示例steps: - name: test image: docker:cli # 生产环境建议使用 docker:major-version-cli 之类的固定版本标签 environment: DOCKER_HOST: tcp://docker:2376 DOCKER_CERT_PATH: /dind-certs/client DOCKER_TLS_VERIFY: 1 volumes: - /opt/woodpeckerci/dind-certs:/dind-certs commands: - docker version services: - name: docker image: docker:dind # 生产环境建议使用 docker:major-version-dind 之类的固定版本标签 privileged: true environment: DOCKER_TLS_CERTDIR: /dind-certs volumes: - /opt/woodpeckerci/dind-certs:/dind-certs ports: - 2376五、小结四类高级用法的选型建议需求推荐方案适用场景消除配置重复镜像、参数、命令序列YAML 锚点/别名/合并variables段所有流水线文件纯 YAML 层面解决最通用步骤间传递临时数据写入文件 source数据量小、仅本次流水线内部使用全实例全局注入WOODPECKER_ENVIRONMENT需要跨项目、跨应用统一注入的场景步骤内操作 Docker 守护进程dind service TLS受信任仓库、私有环境中的容器构建/测试实际项目中这四类技巧可以组合使用例如用variables段统一管理镜像与插件参数用全局变量管控版本标签在需要动态容器的环节再引入 dind。掌握它们就能在保持配置可读性的同时把 Woodpecker 流水线的表达能力用到极致。相关源码与文档延伸阅读解析实现pipeline/frontend/yaml/parse.go解析测试锚点/合并用例pipeline/frontend/yaml/parse_test.goSchema 定义variables字段见 pipeline/frontend/yaml/linter/schema/schema.json服务端全局变量标志cmd/server/flags.go全局变量解析与注入server/services/environment/parse.go、server/pipeline/items.godocker 后端 privileged 透传pipeline/backend/docker/convert.go环境变量与项目设置文档50-environment.md、75-project-settings.md赞分享CI/CDDevOps【免费下载链接】woodpeckerWoodpecker is a simple, yet powerful CI/CD engine with great extensibility.项目地址https://gitcode.com/gh_mirrors/wo/woodpecker点击查看免费下载相关推荐Woodpecker 高级用法实战指南YAML 复用、跨步骤数据传递与 Docker-in-Docker 配置Woodpecker 高级用法实战指南YAML 复用、跨步骤数据传递与 Docker in Docker 配置 本指南以 Woodpecker v2.8 的「CI/CDDevOpsSuckIT 终极指南10个常见问题解决方案快速上手SuckIT 终极指南10个常见问题解决方案快速上手 SuckIT 是一款强大的网站递归下载工具能够帮助用户将整个网站内容下载到本地磁盘支持离线浏览。无论CI/CDDevOps告别环境配置噩梦macOS in Docker 环境变量实战指南告别环境配置噩梦macOS in Docker 环境变量实战指南 你是否还在为 macOS 开发环境配置耗费数小时是否因不同项目需要不同系统版本而头疼本文虚拟化上一篇ParlAI 中的 AQuA 任务代数文字推理数据集及其逐步 Rationale 教师的完整指南下一篇M9A重返未来1999自动化助手3步快速配置的智能游戏辅助工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考