mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 11:51:02 +00:00
Add default event filter (#1140)
breakout from #934 when new events are added you don't have to worry that pipeline will behave different as it does now with this Co-authored-by: Anbraten <anton@ju60.de>
This commit is contained in:
parent
7e18e69563
commit
ca84f703e3
6 changed files with 101 additions and 65 deletions
1
Makefile
1
Makefile
|
@ -52,6 +52,7 @@ else
|
|||
|
||||
all: build
|
||||
|
||||
.PHONY: vendor
|
||||
vendor:
|
||||
go mod tidy
|
||||
go mod vendor
|
||||
|
|
|
@ -100,7 +100,7 @@ pipeline:
|
|||
|
||||
Woodpecker gives the ability to skip individual commits by adding `[CI SKIP]` to the commit message. Note this is case-insensitive.
|
||||
|
||||
```diff
|
||||
```sh
|
||||
git commit -m "updated README [CI SKIP]"
|
||||
```
|
||||
|
||||
|
@ -234,7 +234,7 @@ Commands of every pipeline step are executed serially as if you would enter them
|
|||
|
||||
There is no magic here. The above commands are converted to a simple shell script. The commands in the above example are roughly converted to the below script:
|
||||
|
||||
```diff
|
||||
```sh
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
|
@ -244,7 +244,7 @@ go test
|
|||
|
||||
The above shell script is then executed as the container entrypoint. The below docker command is an (incomplete) example of how the script is executed:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
docker run --entrypoint=build.sh golang
|
||||
```
|
||||
|
||||
|
@ -315,21 +315,21 @@ pipeline:
|
|||
|
||||
Execute a step if the branch is `master` or `develop`:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- branch: [master, develop]
|
||||
```
|
||||
|
||||
Execute a step if the branch starts with `prefix/*`:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- branch: prefix/*
|
||||
```
|
||||
|
||||
Execute a step using custom include and exclude logic:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- branch:
|
||||
include: [ master, release/* ]
|
||||
|
@ -338,9 +338,17 @@ when:
|
|||
|
||||
#### `event`
|
||||
|
||||
:::info
|
||||
**By default steps are filtered by following event types:**
|
||||
|
||||
`push`, `pull_request, `tag`, `deployment`.
|
||||
:::
|
||||
|
||||
Available events: `push`, `pull_request`, `tag`, `deployment`
|
||||
|
||||
Execute a step if the build event is a `tag`:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- event: tag
|
||||
```
|
||||
|
@ -353,26 +361,19 @@ when:
|
|||
+ branch: main
|
||||
```
|
||||
|
||||
Execute a step for all non-pull request events:
|
||||
Execute a step for multiple events:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- event: [push, tag, deployment]
|
||||
```
|
||||
|
||||
Execute a step for all build events:
|
||||
|
||||
```diff
|
||||
when:
|
||||
- event: [push, pull_request, tag, deployment]
|
||||
```
|
||||
|
||||
#### `tag`
|
||||
|
||||
This filter only applies to tag events.
|
||||
Use glob expression to execute a step if the tag name starts with `v`:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- event: tag
|
||||
tag: v*
|
||||
|
@ -400,14 +401,14 @@ This condition should be used in conjunction with a [matrix](/docs/usage/matrix-
|
|||
|
||||
Execute a step for a specific platform:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- platform: linux/amd64
|
||||
```
|
||||
|
||||
Execute a step for a specific platform using wildcards:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- platform: [ linux/*, windows/amd64 ]
|
||||
```
|
||||
|
@ -416,7 +417,7 @@ when:
|
|||
|
||||
Execute a step for deployment events matching the target deployment environment:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- environment: production
|
||||
- event: deployment
|
||||
|
@ -426,7 +427,7 @@ when:
|
|||
|
||||
Execute a step for a single matrix permutation:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- matrix:
|
||||
GO_VERSION: 1.5
|
||||
|
@ -437,7 +438,7 @@ when:
|
|||
|
||||
Execute a step only on a certain Woodpecker instance matching the specified hostname:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- instance: stage.woodpecker.company.com
|
||||
```
|
||||
|
@ -452,14 +453,14 @@ Gitea only support **push** at the moment ([go-gitea/gitea#18228](https://github
|
|||
|
||||
Execute a step only on a pipeline with certain files being changed:
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- path: "src/*"
|
||||
```
|
||||
|
||||
You can use [glob patterns](https://github.com/bmatcuk/doublestar#patterns) to match the changed files and specify if the step should run if a file matching that pattern has been changed `include` or if some files have **not** been changed `exclude`.
|
||||
|
||||
```diff
|
||||
```yaml
|
||||
when:
|
||||
- path:
|
||||
include: [ '.woodpecker/*.yml', '*.ini' ]
|
||||
|
@ -559,7 +560,7 @@ The base attribute defines a shared base volume available to all pipeline steps.
|
|||
|
||||
This would be equivalent to the following docker commands:
|
||||
|
||||
```bash
|
||||
```sh
|
||||
docker volume create my-named-volume
|
||||
|
||||
docker run --volume=my-named-volume:/go golang:latest
|
||||
|
|
|
@ -63,7 +63,13 @@ func (when *When) Match(metadata frontend.Metadata) bool {
|
|||
return true
|
||||
}
|
||||
}
|
||||
return when.IsEmpty()
|
||||
|
||||
if when.IsEmpty() {
|
||||
// test against default Constraints
|
||||
empty := &Constraint{}
|
||||
return empty.Match(metadata)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (when *When) IncludesStatus(status string) bool {
|
||||
|
@ -120,6 +126,16 @@ func (when *When) UnmarshalYAML(value *yaml.Node) error {
|
|||
// Match returns true if all constraints match the given input. If a single
|
||||
// constraint fails a false value is returned.
|
||||
func (c *Constraint) Match(metadata frontend.Metadata) bool {
|
||||
// if event filter is not set, set default
|
||||
if c.Event.IsEmpty() {
|
||||
c.Event.Include = []string{
|
||||
frontend.EventPush,
|
||||
frontend.EventPull,
|
||||
frontend.EventTag,
|
||||
frontend.EventDeploy,
|
||||
}
|
||||
}
|
||||
|
||||
match := c.Platform.Match(metadata.Sys.Platform) &&
|
||||
c.Environment.Match(metadata.Curr.Target) &&
|
||||
c.Event.Match(metadata.Curr.Event) &&
|
||||
|
@ -140,6 +156,11 @@ func (c *Constraint) Match(metadata frontend.Metadata) bool {
|
|||
return match
|
||||
}
|
||||
|
||||
// IsEmpty return true if a constraint has no conditions
|
||||
func (c List) IsEmpty() bool {
|
||||
return len(c.Include) == 0 && len(c.Exclude) == 0
|
||||
}
|
||||
|
||||
// Match returns true if the string matches the include patterns and does not
|
||||
// match any of the exclude patterns.
|
||||
func (c *List) Match(v string) bool {
|
||||
|
|
|
@ -383,89 +383,98 @@ func TestConstraintMap(t *testing.T) {
|
|||
|
||||
func TestConstraints(t *testing.T) {
|
||||
testdata := []struct {
|
||||
desc string
|
||||
conf string
|
||||
with frontend.Metadata
|
||||
want bool
|
||||
}{
|
||||
// no constraints, must match
|
||||
{
|
||||
desc: "no constraints, must match on default events",
|
||||
conf: "",
|
||||
with: frontend.Metadata{},
|
||||
with: frontend.Metadata{
|
||||
Curr: frontend.Build{
|
||||
Event: frontend.EventPush,
|
||||
},
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
// branch constraint
|
||||
{
|
||||
desc: "global branch filter",
|
||||
conf: "{ branch: develop }",
|
||||
with: frontend.Metadata{Curr: frontend.Build{Commit: frontend.Commit{Branch: "master"}}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Event: frontend.EventPush, Commit: frontend.Commit{Branch: "master"}}},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
desc: "global branch filter",
|
||||
conf: "{ branch: master }",
|
||||
with: frontend.Metadata{Curr: frontend.Build{Commit: frontend.Commit{Branch: "master"}}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Event: frontend.EventPush, Commit: frontend.Commit{Branch: "master"}}},
|
||||
want: true,
|
||||
},
|
||||
// environment constraint
|
||||
{
|
||||
conf: "{ branch: develop }",
|
||||
with: frontend.Metadata{Curr: frontend.Build{Commit: frontend.Commit{Branch: "master"}}},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
conf: "{ branch: master }",
|
||||
with: frontend.Metadata{Curr: frontend.Build{Commit: frontend.Commit{Branch: "master"}}},
|
||||
want: true,
|
||||
},
|
||||
// repo constraint
|
||||
{
|
||||
desc: "repo constraint",
|
||||
conf: "{ repo: owner/* }",
|
||||
with: frontend.Metadata{Repo: frontend.Repo{Name: "owner/repo"}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Event: frontend.EventPush}, Repo: frontend.Repo{Name: "owner/repo"}},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
desc: "repo constraint",
|
||||
conf: "{ repo: octocat/* }",
|
||||
with: frontend.Metadata{Repo: frontend.Repo{Name: "owner/repo"}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Event: frontend.EventPush}, Repo: frontend.Repo{Name: "owner/repo"}},
|
||||
want: false,
|
||||
},
|
||||
// ref constraint
|
||||
{
|
||||
desc: "ref constraint",
|
||||
conf: "{ ref: refs/tags/* }",
|
||||
with: frontend.Metadata{Curr: frontend.Build{Commit: frontend.Commit{Ref: "refs/tags/v1.0.0"}}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Commit: frontend.Commit{Ref: "refs/tags/v1.0.0"}, Event: frontend.EventPush}},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
desc: "ref constraint",
|
||||
conf: "{ ref: refs/tags/* }",
|
||||
with: frontend.Metadata{Curr: frontend.Build{Commit: frontend.Commit{Ref: "refs/heads/master"}}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Commit: frontend.Commit{Ref: "refs/heads/master"}, Event: frontend.EventPush}},
|
||||
want: false,
|
||||
},
|
||||
// platform constraint
|
||||
{
|
||||
desc: "platform constraint",
|
||||
conf: "{ platform: linux/amd64 }",
|
||||
with: frontend.Metadata{Sys: frontend.System{Platform: "linux/amd64"}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Event: frontend.EventPush}, Sys: frontend.System{Platform: "linux/amd64"}},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
desc: "platform constraint",
|
||||
conf: "{ repo: linux/amd64 }",
|
||||
with: frontend.Metadata{Sys: frontend.System{Platform: "windows/amd64"}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Event: frontend.EventPush}, Sys: frontend.System{Platform: "windows/amd64"}},
|
||||
want: false,
|
||||
},
|
||||
// instance constraint
|
||||
{
|
||||
desc: "instance constraint",
|
||||
conf: "{ instance: agent.tld }",
|
||||
with: frontend.Metadata{Sys: frontend.System{Host: "agent.tld"}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Event: frontend.EventPush}, Sys: frontend.System{Host: "agent.tld"}},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
desc: "instance constraint",
|
||||
conf: "{ instance: agent.tld }",
|
||||
with: frontend.Metadata{Sys: frontend.System{Host: "beta.agent.tld"}},
|
||||
with: frontend.Metadata{Curr: frontend.Build{Event: frontend.EventPush}, Sys: frontend.System{Host: "beta.agent.tld"}},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
desc: "no constraints, and event get filtered by default default event filter",
|
||||
conf: "",
|
||||
with: frontend.Metadata{
|
||||
Curr: frontend.Build{Event: "non-default"},
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, test := range testdata {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
c := parseConstraints(t, test.conf)
|
||||
got, want := c.Match(test.with), test.want
|
||||
if got != want {
|
||||
t.Errorf("Expect %+v matches %q is %v", test.with, test.conf, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -186,13 +186,11 @@
|
|||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"enum": ["push", "pull_request", "tag", "deployment"]
|
||||
},
|
||||
"minLength": 1
|
||||
"minLength": 1,
|
||||
"items": { "$ref": "#/definitions/event_enum" }
|
||||
},
|
||||
{
|
||||
"enum": ["push", "pull_request", "tag", "deployment"]
|
||||
"$ref": "#/definitions/event_enum"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -270,6 +268,10 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"event_enum": {
|
||||
"default": ["push", "pull_request", "tag", "deployment"],
|
||||
"enum": ["push", "pull_request", "tag", "deployment"]
|
||||
},
|
||||
"step_image": {
|
||||
"description": "Read more: https://woodpecker-ci.org/docs/usage/pipeline-syntax#image",
|
||||
"type": "string"
|
||||
|
|
|
@ -465,7 +465,9 @@ depends_on: [ shouldbefiltered ]
|
|||
func TestTree(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
build := &model.Build{}
|
||||
build := &model.Build{
|
||||
Event: model.EventPush,
|
||||
}
|
||||
|
||||
b := ProcBuilder{
|
||||
Repo: &model.Repo{},
|
||||
|
|
Loading…
Reference in a new issue