Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli/exec/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func metadataFromContext(_ context.Context, c *cli.Command, axis matrix.Axis, w
metadataFileAndOverrideOrDefault(c, "pipeline-started", func(i int64) { m.Curr.Started = i }, c.Int64)
metadataFileAndOverrideOrDefault(c, "pipeline-finished", func(i int64) { m.Curr.Finished = i }, c.Int64)
metadataFileAndOverrideOrDefault(c, "pipeline-status", func(s string) { m.Curr.Status = s }, c.String)
metadataFileAndOverrideOrDefault(c, "pipeline-event", func(s string) { m.Curr.Event = s }, c.String)
metadataFileAndOverrideOrDefault(c, "pipeline-event", func(s string) { m.Curr.Event = metadata.Event(s) }, c.String)
metadataFileAndOverrideOrDefault(c, "pipeline-url", func(s string) { m.Curr.ForgeURL = s }, c.String)
metadataFileAndOverrideOrDefault(c, "pipeline-deploy-to", func(s string) { m.Curr.DeployTo = s }, c.String)
metadataFileAndOverrideOrDefault(c, "pipeline-deploy-task", func(s string) { m.Curr.DeployTask = s }, c.String)
Expand All @@ -123,7 +123,7 @@ func metadataFromContext(_ context.Context, c *cli.Command, axis matrix.Axis, w
metadataFileAndOverrideOrDefault(c, "prev-pipeline-started", func(i int64) { m.Prev.Started = i }, c.Int64)
metadataFileAndOverrideOrDefault(c, "prev-pipeline-finished", func(i int64) { m.Prev.Finished = i }, c.Int64)
metadataFileAndOverrideOrDefault(c, "prev-pipeline-status", func(s string) { m.Prev.Status = s }, c.String)
metadataFileAndOverrideOrDefault(c, "prev-pipeline-event", func(s string) { m.Prev.Event = s }, c.String)
metadataFileAndOverrideOrDefault(c, "prev-pipeline-event", func(s string) { m.Prev.Event = metadata.Event(s) }, c.String)
metadataFileAndOverrideOrDefault(c, "prev-pipeline-url", func(s string) { m.Prev.ForgeURL = s }, c.String)

// Previous Pipeline Commit
Expand Down
27 changes: 26 additions & 1 deletion cmd/server/openapi/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5891,6 +5891,31 @@ const docTemplate = `{
}
}
},
"metadata.Event": {
"type": "string",
"enum": [
"push",
"pull_request",
"pull_request_closed",
"pull_request_metadata",
"tag",
"release",
"deployment",
"cron",
"manual"
],
"x-enum-varnames": [
"EventPush",
"EventPull",
"EventPullClosed",
"EventPullMetadata",
"EventTag",
"EventRelease",
"EventDeploy",
"EventCron",
"EventManual"
]
},
"metadata.Forge": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -5950,7 +5975,7 @@ const docTemplate = `{
"type": "string"
},
"event": {
"type": "string"
"$ref": "#/definitions/metadata.Event"
},
"event_reason": {
"type": "array",
Expand Down
32 changes: 17 additions & 15 deletions pipeline/frontend/metadata/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@

package metadata

type Event string

// Event types corresponding to forge hooks.
const (
EventPush = "push"
EventPull = "pull_request"
EventPullClosed = "pull_request_closed"
EventPullMetadata = "pull_request_metadata"
EventTag = "tag"
EventRelease = "release"
EventDeploy = "deployment"
EventCron = "cron"
EventManual = "manual"
EventPush Event = "push"
EventPull Event = "pull_request"
EventPullClosed Event = "pull_request_closed"
EventPullMetadata Event = "pull_request_metadata"
EventTag Event = "tag"
EventRelease Event = "release"
EventDeploy Event = "deployment"
EventCron Event = "cron"
EventManual Event = "manual"
)

func EventIsPull(event string) bool {
func (event Event) IsPull() bool {
switch event {
case EventPull,
EventPullClosed,
Expand All @@ -37,11 +39,11 @@ func EventIsPull(event string) bool {
return false
}

type Failure string

// Different ways to handle failure states.
const (
FailureIgnore = "ignore"
FailureFail = "fail"
//nolint:godot
// TODO: Not implemented yet.
// FailureCancel = "cancel"
FailureIgnore Failure = "ignore"
FailureFail Failure = "fail"
FailureCancel Failure = "cancel"
)
8 changes: 4 additions & 4 deletions pipeline/frontend/metadata/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (m *Metadata) Environ() map[string]string {
pipeline := m.Curr
setNonEmptyEnvVar(params, "CI_PIPELINE_NUMBER", strconv.FormatInt(pipeline.Number, 10))
setNonEmptyEnvVar(params, "CI_PIPELINE_PARENT", strconv.FormatInt(pipeline.Parent, 10))
setNonEmptyEnvVar(params, "CI_PIPELINE_EVENT", pipeline.Event)
setNonEmptyEnvVar(params, "CI_PIPELINE_EVENT", string(pipeline.Event))
setNonEmptyEnvVar(params, "CI_PIPELINE_EVENT_REASON", strings.Join(pipeline.EventReason, ","))
setNonEmptyEnvVar(params, "CI_PIPELINE_URL", m.getPipelineWebURL(pipeline, 0))
setNonEmptyEnvVar(params, "CI_PIPELINE_FORGE_URL", pipeline.ForgeURL)
Expand Down Expand Up @@ -102,7 +102,7 @@ func (m *Metadata) Environ() map[string]string {
if pipeline.Event == EventRelease {
setNonEmptyEnvVar(params, "CI_COMMIT_PRERELEASE", strconv.FormatBool(pipeline.Commit.IsPrerelease))
}
if EventIsPull(pipeline.Event) {
if pipeline.Event.IsPull() {
sourceBranch, targetBranch := getSourceTargetBranches(commit.Refspec)
setNonEmptyEnvVar(params, "CI_COMMIT_SOURCE_BRANCH", sourceBranch)
setNonEmptyEnvVar(params, "CI_COMMIT_TARGET_BRANCH", targetBranch)
Expand All @@ -127,7 +127,7 @@ func (m *Metadata) Environ() map[string]string {
prevPipeline := m.Prev
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_NUMBER", strconv.FormatInt(prevPipeline.Number, 10))
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_PARENT", strconv.FormatInt(prevPipeline.Parent, 10))
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_EVENT", prevPipeline.Event)
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_EVENT", string(prevPipeline.Event))
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_EVENT_REASON", strings.Join(prevPipeline.EventReason, ","))
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_URL", m.getPipelineWebURL(prevPipeline, 0))
setNonEmptyEnvVar(params, "CI_PREV_PIPELINE_FORGE_URL", prevPipeline.ForgeURL)
Expand All @@ -149,7 +149,7 @@ func (m *Metadata) Environ() map[string]string {
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_BRANCH", prevCommit.Branch)
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_AUTHOR", prevCommit.Author.Name)
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_AUTHOR_EMAIL", prevCommit.Author.Email)
if EventIsPull(prevPipeline.Event) {
if prevPipeline.Event.IsPull() {
prevSourceBranch, prevTargetBranch := getSourceTargetBranches(prevCommit.Refspec)
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_SOURCE_BRANCH", prevSourceBranch)
setNonEmptyEnvVar(params, "CI_PREV_COMMIT_TARGET_BRANCH", prevTargetBranch)
Expand Down
2 changes: 1 addition & 1 deletion pipeline/frontend/metadata/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type (
Started int64 `json:"started,omitempty"`
Finished int64 `json:"finished,omitempty"`
Status string `json:"status,omitempty"`
Event string `json:"event,omitempty"`
Event Event `json:"event,omitempty"`
EventReason []string `json:"event_reason,omitempty"`
ForgeURL string `json:"forge_url,omitempty"`
DeployTo string `json:"target,omitempty"`
Expand Down
8 changes: 4 additions & 4 deletions pipeline/frontend/yaml/compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ type Secret struct {
Name string
Value string
AllowedPlugins []string
Events []string
Events []metadata.Event
}

func (s *Secret) Available(event string, container *yaml_types.Container) error {
func (s *Secret) Available(event metadata.Event, container *yaml_types.Container) error {
onlyAllowSecretForPlugins := len(s.AllowedPlugins) > 0
if onlyAllowSecretForPlugins && !container.IsPlugin() {
return fmt.Errorf("secret %q is only allowed to be used by plugins (a filter has been set on the secret). Note: Image filters do not work for normal steps", s.Name)
Expand All @@ -64,13 +64,13 @@ func (s *Secret) Available(event string, container *yaml_types.Container) error

// Match returns true if an image and event match the restricted list.
// Note that EventPullClosed are treated as EventPull.
func (s *Secret) Match(event string) bool {
func (s *Secret) Match(event metadata.Event) bool {
// if there is no filter set secret matches all webhook events
if len(s.Events) == 0 {
return true
}
// treat all pull events the same way
if metadata.EventIsPull(event) {
if event.IsPull() {
event = metadata.EventPull
}
// one match is enough
Expand Down
14 changes: 7 additions & 7 deletions pipeline/frontend/yaml/compiler/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
func TestSecretAvailable(t *testing.T) {
secret := Secret{
AllowedPlugins: []string{},
Events: []string{"push"},
Events: []metadata.Event{"push"},
}
assert.NoError(t, secret.Available("push", &yaml_types.Container{
Image: "golang",
Expand All @@ -40,7 +40,7 @@ func TestSecretAvailable(t *testing.T) {
secret = Secret{
Name: "foo",
AllowedPlugins: []string{"golang"},
Events: []string{"push"},
Events: []metadata.Event{"push"},
}
assert.NoError(t, secret.Available("push", &yaml_types.Container{
Name: "step",
Expand Down Expand Up @@ -440,18 +440,18 @@ func TestSecretMatch(t *testing.T) {
tcl := []*struct {
name string
secret Secret
event string
event metadata.Event
match bool
}{
{
name: "should match event",
secret: Secret{Events: []string{"pull_request"}},
secret: Secret{Events: []metadata.Event{"pull_request"}},
event: "pull_request",
match: true,
},
{
name: "should not match event",
secret: Secret{Events: []string{"pull_request"}},
secret: Secret{Events: []metadata.Event{"pull_request"}},
event: "push",
match: false,
},
Expand All @@ -463,13 +463,13 @@ func TestSecretMatch(t *testing.T) {
},
{
name: "pull close should match pull",
secret: Secret{Events: []string{"pull_request"}},
secret: Secret{Events: []metadata.Event{"pull_request"}},
event: "pull_request_closed",
match: true,
},
{
name: "pull metadata change should match pull",
secret: Secret{Events: []string{"pull_request"}},
secret: Secret{Events: []metadata.Event{"pull_request"}},
event: "pull_request_metadata",
match: true,
},
Expand Down
2 changes: 1 addition & 1 deletion pipeline/frontend/yaml/compiler/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (c *Compiler) createProcess(container *yaml_types.Container, workflow *yaml

failure := container.Failure
if container.Failure == "" {
failure = metadata.FailureFail
failure = string(metadata.FailureFail)
}

return &backend_types.Step{
Expand Down
4 changes: 2 additions & 2 deletions pipeline/frontend/yaml/constraint/constraint.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,13 @@ func (c *Constraint) Match(m metadata.Metadata, global bool, env map[string]stri
}

match = match && c.Platform.Match(m.Sys.Platform) &&
(len(c.Event) == 0 || slices.Contains(c.Event, m.Curr.Event)) &&
(len(c.Event) == 0 || slices.Contains(c.Event, string(m.Curr.Event))) &&
c.Repo.Match(path.Join(m.Repo.Owner, m.Repo.Name)) &&
c.Ref.Match(m.Curr.Commit.Ref) &&
c.Instance.Match(m.Sys.Host)

// changed files filter apply only for pull-request and push events
if metadata.EventIsPull(m.Curr.Event) || m.Curr.Event == metadata.EventPush {
if m.Curr.Event.IsPull() || m.Curr.Event == metadata.EventPush {
match = match && c.Path.Match(m.Curr.Commit.ChangedFiles, m.Curr.Commit.Message)
}

Expand Down
33 changes: 33 additions & 0 deletions pipeline/frontend/yaml/constraint/skip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2026 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package constraint

import (
"regexp"

"go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/metadata"
)

var skipPipelineRegex = regexp.MustCompile(`\[(?i:ci *skip|skip *ci)\]`)

func IsSkipCommitMessage(event metadata.Event, commitMessage string) bool {
if event == metadata.EventPush || event.IsPull() {
skipMatch := skipPipelineRegex.FindString(commitMessage)
if len(skipMatch) > 0 {
return true
}
}
return false
}
2 changes: 1 addition & 1 deletion pipeline/runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func withExitCode(code int) func(*backend_types.Step) {
}

func withIgnoreFailure() func(*backend_types.Step) {
return func(s *backend_types.Step) { s.Failure = metadata.FailureIgnore }
return func(s *backend_types.Step) { s.Failure = string(metadata.FailureIgnore) }
}

func withOnFailure() func(*backend_types.Step) {
Expand Down
2 changes: 1 addition & 1 deletion pipeline/runtime/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (r *Runtime) runBlockingStep(runnerCtx context.Context, step *backend_types
}

err = r.traceStep(processState, err, step)
if err != nil && step.Failure == metadata.FailureIgnore {
if err != nil && metadata.Failure(step.Failure) == metadata.FailureIgnore {
return nil
}
return err
Expand Down
2 changes: 1 addition & 1 deletion pipeline/runtime/step_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ func TestRunBlockingStep(t *testing.T) {
t.Parallel()
r := newDummyRuntime(t, newTestTracer(t))
step := dummyStep("s1")
step.Failure = metadata.FailureIgnore
step.Failure = string(metadata.FailureIgnore)
step.Environment[dummy.EnvKeyStepExitCode] = "1"

err := r.runBlockingStep(t.Context(), step)
Expand Down
3 changes: 2 additions & 1 deletion server/model/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package model

import (
"go.woodpecker-ci.org/woodpecker/v3/pipeline/errors"
"go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/metadata"
)

type Pipeline struct {
Expand Down Expand Up @@ -100,7 +101,7 @@ func (p Pipeline) IsMultiPipeline() bool {

// IsPullRequest checks if it's a PR event.
func (p Pipeline) IsPullRequest() bool {
return p.Event == EventPull || p.Event == EventPullClosed || p.Event == EventPullMetadata
return metadata.Event(p.Event).IsPull()
}

type PipelineOptions struct {
Expand Down
20 changes: 8 additions & 12 deletions server/pipeline/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ import (
"context"
"errors"
"fmt"
"regexp"

"github.com/rs/zerolog/log"

pipeline_errors "go.woodpecker-ci.org/woodpecker/v3/pipeline/errors"
"go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/metadata"
"go.woodpecker-ci.org/woodpecker/v3/pipeline/frontend/yaml/constraint"
"go.woodpecker-ci.org/woodpecker/v3/server"
"go.woodpecker-ci.org/woodpecker/v3/server/forge"
forge_types "go.woodpecker-ci.org/woodpecker/v3/server/forge/types"
Expand All @@ -31,8 +32,6 @@ import (
"go.woodpecker-ci.org/woodpecker/v3/version"
)

var skipPipelineRegex = regexp.MustCompile(`\[(?i:ci *skip|skip *ci)\]`)

// Create a new pipeline and start it.
func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline *model.Pipeline) (*model.Pipeline, error) {
repoUser, err := _store.GetUser(repo.UserID)
Expand All @@ -42,16 +41,13 @@ func Create(ctx context.Context, _store store.Store, repo *model.Repo, pipeline
return nil, errors.New(msg)
}

if pipeline.Event == model.EventPush || pipeline.IsPullRequest() {
skipMatch := skipPipelineRegex.FindString(pipeline.Message)
if len(skipMatch) > 0 {
ref := pipeline.Commit
if len(ref) == 0 {
ref = pipeline.Ref
}
log.Debug().Str("repo", repo.FullName).Msgf("ignoring pipeline as skip-ci was found in the commit (%s) message '%s'", ref, pipeline.Message)
return nil, ErrFiltered
if constraint.IsSkipCommitMessage(metadata.Event(pipeline.Event), pipeline.Message) {
ref := pipeline.Commit
if len(ref) == 0 {
ref = pipeline.Ref
}
log.Debug().Str("repo", repo.FullName).Msgf("ignoring pipeline as skip-ci was found in the commit (%s) message '%s'", ref, pipeline.Message)
return nil, ErrFiltered
}

_forge, err := server.Config.Services.Manager.ForgeFromRepo(repo)
Expand Down
4 changes: 2 additions & 2 deletions server/pipeline/items.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ func parsePipeline(ctx context.Context, forge forge.Forge, store store.Store, cu

var secrets []compiler.Secret
for _, sec := range secs {
var events []string
var events []pipeline_metadata.Event
for _, event := range sec.Events {
events = append(events, string(event))
events = append(events, pipeline_metadata.Event(event))
}

secrets = append(secrets, compiler.Secret{
Expand Down
Loading