Skip to content

Regression 3.18: manual pipeline API variables not visible in workflow when.evaluate (HTTP 204 / Pipeline-Filtered) #7079

Description

@tangb

Component

server

Describe the bug

Summary

Since v3.18.0, pipeline variables passed via the manual trigger API (POST /api/repos/{id}/pipelines → JSON field variables) are no longer available during workflow-level when.evaluate. All workflows are filtered out. The API returns HTTP 204 with header Pipeline-Filtered: true and an empty body.

This worked in v3.17.0. We consider it a regression introduced by #7040.

Root cause (analysis)

In v3.17.0, server/pipeline/items.go merged manual/API variables into the evaluation environment:

maps.Copy(envs, currentPipeline.AdditionalVariables)

In v3.18.0 (#7040), this line was removed. Variables are now passed as AdditionalEnvs on PipelineBuilder and injected at step compile time via WithNonPluginEnviron, but they are not merged into environ before workflow-level When.Match() in pipeline/frontend/builder/builder.go.

Relevant flow in genItemForWorkflow:

  1. Build environ from metadata + b.Envs
  2. Call parsed.When.Match(workflowMetadata, true, environ) — custom API variables missing here in 3.18
  3. Later: toInternalRepresentation passes AdditionalEnvs to the compiler (runtime / substitution)

Note: POST /pipelines/{number}?MY_VAR=value (restart with query parameters) still works, because query params are merged into envs directly. Only the JSON variables field on create is affected.

Relation to #7077

PR #7077 merges AdditionalEnvs into environ before YAML substitution. The same environ map is used for When.Match, so that PR likely fixes this case as well — but it is currently documented only for ${VAR} substitution (e.g. clone ref: refs/tags/${TAG}), not for when.evaluate workflow routing.

Please confirm #7077 covers workflow filtering and consider adding a regression test for when.evaluate with manual API variables.

Workaround

Stay on v3.17.x until a fix is released (e.g. #7077 or equivalent).

Steps to reproduce

Multi-workflow setup (.woodpecker/ directory, one YAML file per workflow). A manual/API trigger selects the workflow via a custom variable:

.woodpecker/app-release.yml:

when:
  - event: [manual, deployment]
    evaluate: 'CLEEP_BUILD_MODE == "app-release"'

.woodpecker/app-compat.yml:

when:
  - event: [manual, deployment]
    evaluate: 'CLEEP_BUILD_MODE == "app-compat"'

API call:

curl -X POST "http://woodpecker.example/api/repos/1/pipelines" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "branch": "main",
    "variables": {
      "CLEEP_JOB_PATH": "/data/example/job.json",
      "CLEEP_BUILD_MODE": "app-compat"
    }
  }'

Expected behavior

Expected behaviour (v3.17.0)

  • HTTP 200, pipeline JSON returned
  • Only the workflow whose evaluate matches runs
  • CLEEP_BUILD_MODE from the API payload is visible during workflow filtering

Actual behaviour (v3.18.0)

  • HTTP 204, empty body
  • Response header: Pipeline-Filtered: true
  • Same result for any variable value (app-release, app-compat, etc.) — all workflows are filtered
  • Downgrading server and agents to v3.17.0 immediately restores expected behaviour

System Info

- Woodpecker server/agent: **v3.18.0** (broken) / **v3.17.0** (works)
- Forge: Gitea
- Workflows: `.woodpecker/*.yml` (multi-workflow directory)

Additional context

No response

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • Checked that the bug isn't fixed in the next version already [https://woodpecker-ci.org/versions]

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions