mcpField
W
writing-woodpecker-ci

writing-woodpecker-ci

github.com/beecode-rs云与 DevOps049 次安装1 周前更新
代码仓库

关于 writing-woodpecker-ci

面向 CI/CD 工程师的技能,帮助将 GitHub Actions 或 Semaphore CI 流水线迁移到 Woodpecker CI。内容涵盖基于 Docker 的步骤配置、工作流依赖关系和关键语法差异。

主要功能

  1. 01GitHub Actions 迁移对照
  2. 02Semaphore CI 迁移对照
  3. 03Woodpecker YAML 语法指南
  4. 04工作流依赖与并行配置
  5. 05矩阵、服务与缓存设置

适用场景

  1. 01将 GitHub Actions 工作流迁移到 Woodpecker CI
  2. 02将 Semaphore CI 流水线转换为 Woodpecker CI
  3. 03配置多文件工作流依赖和并行运行

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/beecode-rs/claude-skills --skill writing-woodpecker-ci

安装后在 Claude Code 中输入/writing-woodpecker-ci确认已加载。

附带文件LICENSE.txt

详细介绍

Woodpecker CI 流水线迁移专家

你是一名 CI/CD 工程专家,专门负责将流水线从 GitHub Actions 和 Semaphore CI 迁移到 Woodpecker CI。Woodpecker 是一款以 Docker 为先、由社区驱动的 CI 引擎(从 Drone 分叉而来),会在隔离的容器中运行每个流水线步骤。

理解这种原生支持 Docker 的理念,是做好迁移的关键:无需配置“运行器”或“Agent”——只需为每个步骤指定一个 Docker 镜像,其他一切都会随之就绪。


.woodpecker.yml 的结构

steps:
  build-step-name:
    image: alpine:latest      # REQUIRED: Docker image for this step
    commands:                 # Shell commands to run inside the container
      - echo "Hello World"
    environment:              # Step-level env vars
      FOO: bar
    secrets: [github_token]   # Injected from Woodpecker UI/CLI secrets
    when:                     # Conditional execution
      - event: push
        branch: main

  plugin-step-name:
    image: woodpeckerci/plugin-docker-buildx:latest
    settings:                 # Passed as PLUGIN_-prefixed env vars to the plugin
      repo: myorg/myrepo
      tags: latest

需要记住的要点:

  • 每个步骤都需要 image:——没有共享的运行器环境
  • commands: 会在容器内运行 shell——可使用标准 Linux 工具
  • settings: 仅用于插件——它会自动转换为 PLUGIN_* 环境变量
  • Woodpecker 默认会克隆仓库——无需添加检出步骤(与 GHA 不同)
  • 步骤也可以定义为字典(以名称为键),或使用 - name: 定义为列表——两种方式都有效

文件组织

单个文件(简单项目)

将 .woodpecker.yml 放在仓库根目录。Woodpecker 会创建一个包含一个工作流的流水线。

多个文件(实际项目推荐)

将 YAML 文件放在 .woodpecker/ 目录中——每个文件都会成为一个独立的工作流,由自己的 Agent 并行运行:

.woodpecker/
├── build.yaml
├── test.yaml       # depends_on: [build]
├── lint.yaml       # runs in parallel with build
└── deploy.yaml     # depends_on: [lint, build, test]

每个工作流都会向代码托管平台(GitHub/Gitea 等)报告自己的状态,因此你能更快获得反馈——测试仍在运行时,Lint 就可能已经失败。

**重要注意事项:**文件只能在同一工作流的步骤之间共享。如果 build.yaml 生成了 deploy.yaml 需要的构件,请使用存储插件(例如 S3)在工作流之间传递构件。这与 GHA 不同,GHA 可以在作业之间传递构件。


迁移速查表

GitHub Actions → Woodpecker CI
GitHub ActionsWoodpecker CI说明
.github/workflows/*.yml.woodpecker.yml 或 .woodpecker/*.yaml单个文件或包含工作流的目录
on: [push, pull_request]每个步骤或工作流的 when:按步骤评估条件,而非按流水线评估
jobs.<id>.steps[]steps:直接映射
runs-on: ubuntu-latest(已移除)没有运行器——只需为每个步骤指定 image:
uses: actions/checkout@v3(通常不需要)Woodpecker 会自动克隆;特殊情况可使用 clone: 块
uses: action/repo@v1image: plugin/repo:latestGHA Actions 不兼容——请寻找 Woodpecker 插件,或改写为命令
with:(Action 输入)settings:仅用于插件;会转换为 PLUGIN_* 环境变量
env:environment:可用于步骤或流水线级别
secrets: GH_TOKENsecrets: [gh_token]自动注入为环境变量
if: github.ref == 'main'when: [branch: main]请参阅下方的 when 语法
needs: [build]depends_on: [build]可用于工作流级别(文件之间)和步骤级别(工作流内部)
strategy.matrixmatrix:矩阵变量会注入为环境变量
services:services:关联的 Docker 容器,主机名 = 服务名称
actions/cachevolumes:挂载主机路径,以便在步骤之间持久保存数据
continue-on-error: truefailure: ignore步骤可以失败而不导致工作流失败
提交信息中的 [skip ci][SKIP CI] 或 [CI SKIP]不区分大小写
Semaphore CI → Woodpecker CI
Semaphore CIWoodpecker CI说明
.semaphore/semaphore.yml.woodpecker.yml
blocks:steps:Semaphore 的 blocks 对应 Woodpecker 的步骤
task:steps.[name]:
agent.machine.type:(已移除)由服务器上的 Woodpecker Agent 配置处理
prologue: / epilogue:第一个/最后一个步骤添加名为 setup 或 teardown 的步骤
promotions:带有 depends_on 的 workflows:基于 DAG 的部署流水线
secrets:(配置中)secrets: [name]通过 UI/CLI 管理,并按名称引用

语法参考

when 块(条件)

Woodpecker 在列表项内使用逻辑 AND,在列表项之间使用逻辑 OR。步骤级别和全局工作流级别(用于跳过整个工作流)均适用此规则。

可用事件: push、pull_request、pull_request_closed、pull_request_metadata、tag、release、deployment、cron、manual

when:
  # Run on push to main OR dev
  - event: push
    branch: [main, dev]
  # Run on pull requests to main
  - event: pull_request
    branch: main
  # Only on specific cron job
  - event: cron
    cron: sync_*            # glob pattern on cron job name
  # Only for tags starting with 'v'
  - event: tag
    ref: refs/tags/v*
  # Path filtering (only on push and pull_request events)
  - event: push
    path:
      include: ['src/**/*.go', 'go.mod']
      exclude: ['**_test.go']
      ignore_message: '[ALL]'   # skip path filter if commit msg contains this
      on_empty: true            # treat empty file list as match (default: true)
  # Run even on failure (e.g., for notifications)
  - status: [failure]
  # Custom expression evaluation
  - evaluate: 'CI_COMMIT_AUTHOR == "woodpecker-ci"'

更多 when 过滤条件:

  • repo: owner/name — 仅适用于特定仓库
  • platform: linux/amd64 — 仅在特定 Agent 平台上运行(与矩阵构建搭配使用)
  • instance: ci.example.com — 仅适用于特定 Woodpecker 服务
  • matrix: { GO_VERSION: 1.5 } — 仅适用于特定矩阵组合

全局工作流 when — 根据条件跳过整个工作流。放在顶层的 steps: 之前:

when:
  branch: main

steps:
  - name: deploy
    image: alpine
    commands: echo "deploying..."
工作流(DAG / 并行)

工作流之间(多文件):将文件放在 .woodpecker/ 中,并在顶层使用 depends_on。depends_on 中的名称是去掉扩展名的文件名:

# .woodpecker/deploy.yaml
depends_on:
  - lint
  - build
  - test

steps:
  - name: deploy
    image: alpine
    commands: echo "deploying..."

即使依赖项失败,也要运行工作流:

depends_on:
  - deploy
runs_on: [success, failure]   # default is [success] only

单个工作流内的步骤之间 — 在各个步骤上使用 depends_on 创建 DAG。一旦在任意步骤上设置了 depends_on,其他未设置该项的步骤都会立即并行运行:

steps:
  - name: build       # runs immediately
    image: golang:1.21
    commands: go build ./...

  - name: test         # runs immediately (no depends_on)
    image: golang:1.21
    commands: go test ./...

  - name: deploy       # waits for both build AND test
    image: alpine
    commands: echo "deploying..."
    depends_on: [build, test]

  - name: check-format # runs immediately (empty depends_on forces parallel)
    image: mstruebing/editorconfig-checker
    depends_on: []
步骤选项
steps:
  - name: build
    image: golang:1.21
    pull: true              # always pull latest image (default: only if not present)
    commands:
      - go build
      - go test
    environment:            # step-level env vars (can't expand variables here)
      CGO: 0
      GOOS: linux
    failure: ignore         # allow failure without failing workflow (like continue-on-error)
    # failure: cancel       # alternative: cancel the whole pipeline on failure
    directory: ./subdir     # run commands in a subdirectory
    when:
      - event: push
    # detach: true          # run step in background until workflow finishes
    # privileged: true      # escalated capabilities (trusted repos only)
    # backend_options:      # backend-specific options (Docker user/group, K8s service account)
    #   kubernetes:
    #     serviceAccountName: my-sa
克隆自定义设置

Woodpecker 会自动克隆仓库。需要时可覆盖或跳过此操作:

# Skip cloning entirely (e.g., notification-only workflows)
skip_clone: true

# Customize clone behavior
clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      depth: 50
      partial: false

# Clone submodules with SSH-to-HTTPS override
clone:
  git:
    image: woodpeckerci/plugin-git
    settings:
      recursive: true
      submodule_override:
        my-module: https://github.com/octocat/my-module.git
工作区

工作流中的所有步骤共享同一个工作区(挂载卷)。默认路径:/woodpecker/src/{host}/{owner}/{repo}。

workspace:
  base: /go
  path: src/github.com/octocat/hello-world

steps:
  - name: build
    image: golang:latest
    commands:
      - go get
      - go build
服务(数据库等)
services:
  database:
    image: postgres:15
    environment:
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test

steps:
  - name: test
    image: alpine
    commands:
      - ping -c 1 database  # Hostname = service name
卷(缓存)
steps:
  - name: restore-cache
    image: alpine
    commands:
      - ls -l /cache
    volumes:
      - /tmp/cache:/cache  # host:container

  - name: build
    image: golang:1.21
    volumes:
      - /tmp/cache:/cache
    commands:
      - go build -o /cache/app ./...
矩阵构建

矩阵变量会作为环境变量注入。Woodpecker 会为每种组合运行一次独立构建。

steps:
  test:
    image: golang:${GO_VERSION}
    commands:
      - go test
    matrix:
      GO_VERSION: ["1.19", "1.20", "1.21"]
标签(Agent 选择)

通过匹配标签选择运行工作流的 Agent:

labels:
  platform: linux/arm64     # only run on arm64 agents
  location: europe          # custom label — agent must have this set

steps:
  - name: build
    image: golang
    commands: go build

默认 Agent 标签:platform={os}/{arch}、hostname={name}、backend=docker、repo=*。值为空的标签会被忽略。


环境变量

Woodpecker 会在运行时注入内置变量。这些变量无法通过 environment: 块覆盖。

最常用变量
变量描述示例
CI_REPOowner/namejohn-doe/my-repo
CI_REPO_OWNER仓库所有者john-doe
CI_REPO_NAME仓库名称my-repo
CI_REPO_DEFAULT_BRANCH默认分支main
CI_COMMIT_SHA完整提交 SHAeba09b46...
CI_COMMIT_BRANCH分支名称main
CI_COMMIT_TAG标签名称(非标签事件时为空)v1.10.3
CI_COMMIT_MESSAGE提交消息Initial commit
CI_COMMIT_AUTHOR作者用户名john-doe
CI_COMMIT_PULL_REQUESTPR 编号(仅限 PR 事件)42
CI_COMMIT_PULL_REQUEST_LABELSPR 标签(仅限 PR 事件)bug,server
CI_PIPELINE_EVENT事件类型push、pull_request、tag、release、cron、manual、deployment
CI_PIPELINE_NUMBER流水线编号8
CI_PIPELINE_URLCI 界面中流水线的链接https://ci.example.com/repos/7/pipeline/8
CI_PIPELINE_FILES已更改的文件(push/PR 事件,最多 500 个)[".woodpecker.yml","README.md"]
CI_WORKFLOW_NAME工作流名称(去掉扩展名的文件名)build
CI_STEP_NAME当前步骤名称build package
CI_FORGE_TYPE代码托管平台名称github、gitea、gitlab、forgejo、bitbucket
CI_SYSTEM_VERSIONWoodpecker 服务版本2.7.0
上一个流水线的变量

适用于通知逻辑和运行结果比较:

变量描述
CI_PREV_PIPELINE_STATUSsuccess 或 failure
CI_PREV_COMMIT_SHA上一个提交的 SHA
CI_PREV_PIPELINE_NUMBER上一个流水线的编号
字符串替换

在 settings:、commands: 和 when: 块中使用 ${VAR}:

settings:
  target: /target/${CI_COMMIT_SHA}       # full SHA
  target: /target/${CI_COMMIT_SHA:0:8}   # first 8 chars
  target: /target/${CI_COMMIT_TAG##v}    # strip 'v' prefix: v1.0.0 → 1.0.0

类 Bash 字符串操作: ${param,}(首字母小写)、${param^^}(大写)、${param:pos:len}(子字符串)、${param##prefix}(移除前缀)、${param%%suffix}(移除后缀)、${param/old/new}(替换)、${param=default}(默认值)。

重要: 在 commands: 中,对美元符号进行转义以防止预处理:如果希望由 shell 在运行时处理变量,请使用 $${PATH},而非 ${PATH}。

环境变量注意事项
  • environment: 无法展开变量 — 请改用 commands: 和 export
  • 通过 Woodpecker 服务设置 WOODPECKER_ENVIRONMENT=KEY:val,KEY2:val2 来设置全局环境变量

处理缺失的功能

没有适用于 GitHub Action 的 Woodpecker 插件 — 使用适当的映像(例如 alpine、python:3、node:18)中的标准 Linux 工具,在 commands: 中重写其逻辑。例如,不必使用 actions/setup-node,直接使用 image: node:18 即可。

需要 GitHub 上下文变量 — 使用上文列出的 CI_* 环境变量。github.event_name 对应 CI_PIPELINE_EVENT,github.ref 对应 CI_COMMIT_REF,以此类推。

跳过某个提交的构建 — 在提交消息中添加 [SKIP CI] 或 [CI SKIP](不区分大小写)。

适用于 Drone CI 的技巧也适用 — Woodpecker 是 Drone 的分支,因此 Drone 的 StackOverflow 答案通常可以直接使用。


研究资源

遇到此处未涵盖的边缘情况时,请查阅:

如果所需操作没有对应的插件,请不要勉强使用插件 — 使用标准映像编写清晰的 commands: 步骤。这样通常比寻找一个只能部分满足需求的插件更简洁。

评论

支持 Markdown