diff --git a/agent/runner.go b/agent/runner.go index 62fd2d261..4f815c1a3 100644 --- a/agent/runner.go +++ b/agent/runner.go @@ -19,6 +19,7 @@ import ( "encoding/json" "io" "io/ioutil" + "runtime" "strconv" "sync" "time" @@ -283,7 +284,7 @@ func (r *Runner) Run(ctx context.Context) error { state.Pipeline.Step.Environment = map[string]string{} } - // TODO: find better way to update this state + // TODO: find better way to update this state and move it to pipeline to have the same env in cli-exec state.Pipeline.Step.Environment["CI_MACHINE"] = r.hostname state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "success" state.Pipeline.Step.Environment["CI_BUILD_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) @@ -293,6 +294,8 @@ func (r *Runner) Run(ctx context.Context) error { state.Pipeline.Step.Environment["CI_JOB_STARTED"] = strconv.FormatInt(state.Pipeline.Time, 10) state.Pipeline.Step.Environment["CI_JOB_FINISHED"] = strconv.FormatInt(time.Now().Unix(), 10) + state.Pipeline.Step.Environment["CI_SYSTEM_ARCH"] = runtime.GOOS + "/" + runtime.GOARCH + if state.Pipeline.Error != nil { state.Pipeline.Step.Environment["CI_BUILD_STATUS"] = "failure" state.Pipeline.Step.Environment["CI_JOB_STATUS"] = "failure" diff --git a/cli/exec/exec.go b/cli/exec/exec.go index 0182e1f16..10fee160d 100644 --- a/cli/exec/exec.go +++ b/cli/exec/exec.go @@ -206,6 +206,11 @@ func execWithAxis(c *cli.Context, file, repoPath string, axis matrix.Axis) error // return the metadata from the cli context. func metadataFromContext(c *cli.Context, axis matrix.Axis) frontend.Metadata { + platform := c.String("system-platform") + if platform == "" { + platform = runtime.GOOS + "/" + runtime.GOARCH + } + return frontend.Metadata{ Repo: frontend.Repo{ Name: c.String("repo-name"), @@ -262,9 +267,9 @@ func metadataFromContext(c *cli.Context, axis matrix.Axis) frontend.Metadata { Matrix: axis, }, Sys: frontend.System{ - Name: c.String("system-name"), - Link: c.String("system-link"), - Arch: c.String("system-arch"), + Name: c.String("system-name"), + Link: c.String("system-link"), + Platform: platform, }, } } diff --git a/cli/exec/flags.go b/cli/exec/flags.go index 412266867..2a3a81f1f 100644 --- a/cli/exec/flags.go +++ b/cli/exec/flags.go @@ -101,9 +101,8 @@ var flags = []cli.Flag{ // metadata parameters // &cli.StringFlag{ - EnvVars: []string{"CI_SYSTEM_ARCH"}, - Name: "system-arch", - Value: "linux/amd64", + EnvVars: []string{"CI_SYSTEM_PLATFORM"}, + Name: "system-platform", }, &cli.StringFlag{ EnvVars: []string{"CI_SYSTEM_NAME"}, diff --git a/cmd/agent/agent.go b/cmd/agent/agent.go index 3f6096eca..0ecad8c12 100644 --- a/cmd/agent/agent.go +++ b/cmd/agent/agent.go @@ -20,6 +20,7 @@ import ( "net/http" "os" "runtime" + "strings" "sync" "github.com/rs/zerolog" @@ -39,18 +40,26 @@ import ( ) func loop(c *cli.Context) error { - filter := rpc.Filter{ - Labels: map[string]string{ - "platform": runtime.GOOS + "/" + runtime.GOARCH, - }, - Expr: c.String("filter"), - } - hostname := c.String("hostname") if len(hostname) == 0 { hostname, _ = os.Hostname() } + labels := map[string]string{ + "hostname": hostname, + "platform": runtime.GOOS + "/" + runtime.GOARCH, + "repo": "*", // allow all repos by default + } + + for _, v := range c.StringSlice("filter-labels") { + parts := strings.SplitN(v, "=", 2) + labels[parts[0]] = parts[1] + } + + filter := rpc.Filter{ + Labels: labels, + } + if c.Bool("pretty") { log.Logger = log.Output( zerolog.ConsoleWriter{ diff --git a/cmd/agent/flags.go b/cmd/agent/flags.go index 8b9cf6c2d..f5d3af84c 100644 --- a/cmd/agent/flags.go +++ b/cmd/agent/flags.go @@ -72,10 +72,10 @@ var flags = []cli.Flag{ Name: "hostname", Usage: "agent hostname", }, - &cli.StringFlag{ - EnvVars: []string{"WOODPECKER_FILTER"}, + &cli.StringSliceFlag{ + EnvVars: []string{"WOODPECKER_FILTER_LABELS"}, Name: "filter", - Usage: "filter expression to restrict builds by label", + Usage: "List of labels to filter tasks on. An agent must be assigned every tag listed in a task to be selected.", }, &cli.IntFlag{ EnvVars: []string{"WOODPECKER_MAX_PROCS"}, diff --git a/docs/docs/20-usage/20-pipeline-syntax.md b/docs/docs/20-usage/20-pipeline-syntax.md index 505a63dc4..41e2277c7 100644 --- a/docs/docs/20-usage/20-pipeline-syntax.md +++ b/docs/docs/20-usage/20-pipeline-syntax.md @@ -96,26 +96,6 @@ pipeline: + exclude: [ develop, feature/* ] ``` -### `platform` - -To configure your pipeline to only be executed on an agent with a specific platform, you can use the `platform` key. -Have a look at the official [go docs](https://go.dev/doc/install/source) for the available platforms. The syntax of the platform is `GOOS/GOARCH` like `linux/arm64` or `linux/amd64`. - -Example: - -Assuming we have two agents, one `arm` and one `amd64`. Previously this pipeline would have executed on **either agent**, as Woodpecker is not fussy about where it runs the pipelines. By setting the following option it will only be executed on an agent with the platform `linux/arm64`. - -```diff -+platform: linux/arm64 - - pipeline: - build: - image: golang - commands: - - go build - - go test -``` - ### Skip Commits Woodpecker gives the ability to skip individual commits by adding `[CI SKIP]` to the commit message. Note this is case-insensitive. @@ -401,6 +381,10 @@ pipeline: #### `platform` +:::note +This condition should be used in conjunction with a [matrix](/docs/usage/matrix-pipelines#example-matrix-pipeline-using-multiple-platforms) pipeline as a regular pipeline will only executed by a single agent which only has one arch. +::: + Execute a step for a specific platform: ```diff @@ -448,8 +432,8 @@ when: #### `path` :::info -Path conditions are applied only to **push** and **pull_request** events. -It is currently **only available** for GitHub, GitLab. +Path conditions are applied only to **push** and **pull_request** events. +It is currently **only available** for GitHub, GitLab. Gitea only support **push** at the moment ([go-gitea/gitea#18228](https://github.com/go-gitea/gitea/pull/18228)). ::: @@ -586,7 +570,52 @@ git clone https://github.com/octocat/hello-world \ Woodpecker has integrated support for matrix builds. Woodpecker executes a separate build task for each combination in the matrix, allowing you to build and test a single commit against multiple configurations. -For more details check the [matrix build docs](/docs/usage/matrix-builds/). +For more details check the [matrix build docs](/docs/usage/matrix-pipelines/). + +## `platform` + +To configure your pipeline to only be executed on an agent with a specific platform, you can use the `platform` key. +Have a look at the official [go docs](https://go.dev/doc/install/source) for the available platforms. The syntax of the platform is `GOOS/GOARCH` like `linux/arm64` or `linux/amd64`. + +Example: + +Assuming we have two agents, one `arm` and one `amd64`. Previously this pipeline would have executed on **either agent**, as Woodpecker is not fussy about where it runs the pipelines. By setting the following option it will only be executed on an agent with the platform `linux/arm64`. + +```diff ++platform: linux/arm64 + +pipeline: + build: + image: golang + commands: + - go build + - go test +``` + +## `labels` + +You can set labels for your pipeline to select an agent to execute the pipeline on. An agent will pick up and run a pipeline when **every** label assigned to a pipeline matches the agents labels. + +To set additional agent labels check the [agent configuration options](/docs/administration/agent-config#woodpecker_filter_labels). Agents will have at least three default labels: `platform=agent-os/agent-arch`, `hostname=my-agent` and `repo=*`. Agents can use a `*` as a wildcard for a label. For example `repo=*` will match every repo. + +Pipeline labels with an empty value will be ignored. +By default each pipeline has at least the `repo=your-user/your-repo-name` label. If you have set the [platform attribute](#platform) for your pipeline it will have a label like `platform=your-os/your-arch` as well. + +You can add additional labels as a key value map: + +```diff ++labels: ++ location: europe # only agents with `location=europe` or `location=*` will be used ++ weather: sun ++ hostname: "" # this label will be ignored as it is empty + +pipeline: + build: + image: golang + commands: + - go build + - go test +``` ## `clone` diff --git a/docs/docs/20-usage/30-matrix-builds.md b/docs/docs/20-usage/30-matrix-pipelines.md similarity index 71% rename from docs/docs/20-usage/30-matrix-builds.md rename to docs/docs/20-usage/30-matrix-pipelines.md index fa9d241c7..41bcb9019 100644 --- a/docs/docs/20-usage/30-matrix-builds.md +++ b/docs/docs/20-usage/30-matrix-pipelines.md @@ -1,6 +1,6 @@ -# Matrix builds +# Matrix pipelines -Woodpecker has integrated support for matrix builds. Woodpecker executes a separate build task for each combination in the matrix, allowing you to build and test a single commit against multiple configurations. +Woodpecker has integrated support for matrix pipeline. Woodpecker executes a separate pipeline for each combination in the matrix, allowing you to build and test a single commit against multiple configurations. Example matrix definition: @@ -33,6 +33,15 @@ matrix: Matrix variables are interpolated in the yaml using the `${VARIABLE}` syntax, before the yaml is parsed. This is an example yaml file before interpolating matrix parameters: ```yaml +matrix: + GO_VERSION: + - 1.4 + - 1.3 + DATABASE: + - mysql:5.5 + - mysql:6.5 + - mariadb:10.1 + pipeline: build: image: golang:${GO_VERSION} @@ -44,15 +53,6 @@ pipeline: services: database: image: ${DATABASE} - -matrix: - GO_VERSION: - - 1.4 - - 1.3 - DATABASE: - - mysql:5.5 - - mysql:6.5 - - mariadb:10.1 ``` Example YAML file after injecting the matrix parameters: @@ -78,36 +78,61 @@ services: ## Examples -Example matrix build based on Docker image tag: +### Example matrix pipeline based on Docker image tag ```yaml +matrix: + TAG: + - 1.7 + - 1.8 + - latest + pipeline: build: image: golang:${TAG} commands: - go build - go test - -matrix: - TAG: - - 1.7 - - 1.8 - - latest ``` -Example matrix build based on Docker image: +### Example matrix pipeline based on container image ```yaml +matrix: + IMAGE: + - golang:1.7 + - golang:1.8 + - golang:latest + pipeline: build: image: ${IMAGE} commands: - go build - go test - -matrix: - IMAGE: - - golang:1.7 - - golang:1.8 - - golang:latest +``` + +### Example matrix pipeline using multiple platforms + +```yaml +matrix: + platform: + - linux/amd64 + - linux/arm64 + +platform: ${platform} + +pipeline: + test: + image: alpine + commands: + - echo "I am running on ${platform}" + + test-arm-only: + image: alpine + commands: + - echo "I am running on ${platform}" + - echo "Arm is cool!" + when: + platform: linux/arm* ``` diff --git a/docs/docs/30-administration/15-agent-config.md b/docs/docs/30-administration/15-agent-config.md index 8fa7b662e..50c35222a 100644 --- a/docs/docs/30-administration/15-agent-config.md +++ b/docs/docs/30-administration/15-agent-config.md @@ -12,7 +12,6 @@ services: environment: + - WOODPECKER_SERVER=localhost:9000 + - WOODPECKER_AGENT_SECRET="your-shared-secret-goes-here" - ``` The following are automatically set and can be overridden: @@ -37,45 +36,6 @@ services: + - WOODPECKER_MAX_PROCS=4 ``` -## Filtering agents - -When building your pipelines as long as you have set the platform or filter, builds can be made to only run code on certain agents. - -``` -- WOODPECKER_HOSTNAME=mycompany-ci-01.example.com -- WOODPECKER_FILTER= -``` - -### Filter on Platform - -Only want certain pipelines or steps to run on certain agents with specific platforms? Such as arm vs amd64? - -```yaml -# .woodpecker.yml -pipeline: - build: - image: golang - commands: - - go build - - go test - when: - platform: linux/amd64 - - - testing: - image: golang - commands: - - go build - - go test - when: - platform: linux/arm* - - -``` - -See [Conditionals Pipeline](/docs/usage/pipeline-syntax#step-when---conditional-execution) syntax for more - - ## All agent configuration options Here is the full list of configuration options and their default variables. @@ -125,6 +85,11 @@ Configures the agent hostname. Configures the number of parallel builds. +### `WOODPECKER_FILTER_LABELS` +> Default: empty + +Configures labels to filter pipeline pick up. Use a list of key-value pairs like `key=value,second-key=*`. `*` can be used as a wildcard. By default agents provide three additional labels `platform=os/arch`, `hostname=my-agent` and `repo=*` which can be overwritten if needed. To learn how labels work check out the [pipeline syntax page](/docs/usage/pipeline-syntax#labels). + ### `WOODPECKER_HEALTHCHECK` > Default: `true` diff --git a/docs/docs/91-migrations.md b/docs/docs/91-migrations.md index 1b306913b..27b891fdd 100644 --- a/docs/docs/91-migrations.md +++ b/docs/docs/91-migrations.md @@ -2,6 +2,11 @@ Some versions need some changes to the server configuration or the pipeline configuration files. +## 1.0.0 + +- Refactored support of old agent filter labels and expression. Learn how to use the new [filter](/docs/usage/pipeline-syntax#labels). +- Renamed step environment variable `CI_SYSTEM_ARCH` to `CI_SYSTEM_PLATFORM`. Same applies for the cli exec variable. + ## 0.15.0 - Default value for custom pipeline path is now empty / un-set which results in following resolution: diff --git a/go.mod b/go.mod index 9e1f0cfc7..db1f77328 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,6 @@ require ( github.com/tevino/abool v1.2.0 github.com/ugorji/go v1.2.7 // indirect github.com/urfave/cli/v2 v2.5.1 - github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915 github.com/xanzy/go-gitlab v0.64.0 github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonschema v1.2.0 diff --git a/go.sum b/go.sum index 05fffc649..f9c3fa0fa 100644 --- a/go.sum +++ b/go.sum @@ -1413,8 +1413,6 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= -github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915 h1:9zBOoKSR9CBeYoKQv6LFIuImg8lorCjh8XzK72bJMRg= -github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915/go.mod h1:PbzlZ93HrA1cf16OUP1vckAPq57gtF+ccnwZeDkmC9s= github.com/xanzy/go-gitlab v0.64.0 h1:rMgQdW9S1w3qvNAH2LYpFd2xh7KNLk+JWJd7sorNuTc= github.com/xanzy/go-gitlab v0.64.0/go.mod h1:F0QEXwmqiBUxCgJm8fE9S+1veX4XC9Z4cfaAbqwk4YM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= diff --git a/pipeline/frontend/metadata.go b/pipeline/frontend/metadata.go index 73424f26a..6601c066c 100644 --- a/pipeline/frontend/metadata.go +++ b/pipeline/frontend/metadata.go @@ -87,11 +87,11 @@ type ( // System defines runtime metadata for a ci/cd system. System struct { - Name string `json:"name,omitempty"` - Host string `json:"host,omitempty"` - Link string `json:"link,omitempty"` - Arch string `json:"arch,omitempty"` - Version string `json:"version,omitempty"` + Name string `json:"name,omitempty"` + Host string `json:"host,omitempty"` + Link string `json:"link,omitempty"` + Platform string `json:"arch,omitempty"` + Version string `json:"version,omitempty"` } ) @@ -179,11 +179,13 @@ func (m *Metadata) Environ() map[string]string { "CI_PREV_BUILD_STARTED": strconv.FormatInt(m.Prev.Started, 10), "CI_PREV_BUILD_FINISHED": strconv.FormatInt(m.Prev.Finished, 10), - "CI_SYSTEM_NAME": m.Sys.Name, - "CI_SYSTEM_LINK": m.Sys.Link, - "CI_SYSTEM_HOST": m.Sys.Host, - "CI_SYSTEM_ARCH": m.Sys.Arch, - "CI_SYSTEM_VERSION": version.Version, + "CI_SYSTEM_NAME": m.Sys.Name, + "CI_SYSTEM_LINK": m.Sys.Link, + "CI_SYSTEM_HOST": m.Sys.Host, + "CI_SYSTEM_PLATFORM": m.Sys.Platform, // will be set by pipeline platform option or by agent + "CI_SYSTEM_VERSION": version.Version, + + "CI_SYSTEM_ARCH": m.Sys.Platform, // TODO: remove after next version } if m.Curr.Event == EventTag { params["CI_COMMIT_TAG"] = strings.TrimPrefix(m.Curr.Commit.Ref, "refs/tags/") @@ -198,5 +200,5 @@ func (m *Metadata) Environ() map[string]string { var pullRegexp = regexp.MustCompile(`\d+`) func (m *Metadata) SetPlatform(platform string) { - m.Sys.Arch = platform + m.Sys.Platform = platform } diff --git a/pipeline/frontend/yaml/compiler/compiler.go b/pipeline/frontend/yaml/compiler/compiler.go index 4e26739ad..d317d74dd 100644 --- a/pipeline/frontend/yaml/compiler/compiler.go +++ b/pipeline/frontend/yaml/compiler/compiler.go @@ -92,7 +92,7 @@ func (c *Compiler) Compile(conf *yaml.Config) *backend.Config { }) // create a default network - if strings.HasPrefix(c.metadata.Sys.Arch, windowsPrefix) { + if strings.HasPrefix(c.metadata.Sys.Platform, windowsPrefix) { config.Networks = append(config.Networks, &backend.Network{ Name: fmt.Sprintf("%s_default", c.prefix), Driver: networkDriverNAT, diff --git a/pipeline/frontend/yaml/compiler/convert.go b/pipeline/frontend/yaml/compiler/convert.go index cb913da94..3e1fb6c5b 100644 --- a/pipeline/frontend/yaml/compiler/convert.go +++ b/pipeline/frontend/yaml/compiler/convert.go @@ -78,7 +78,7 @@ func (c *Compiler) createProcess(name string, container *yaml.Container, section } if len(container.Commands) != 0 { - if c.metadata.Sys.Arch == "windows/amd64" { + if c.metadata.Sys.Platform == "windows/amd64" { entrypoint = []string{"powershell", "-noprofile", "-noninteractive", "-command"} command = []string{"[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Env:CI_SCRIPT)) | iex"} environment["CI_SCRIPT"] = generateScriptWindows(container.Commands) diff --git a/pipeline/frontend/yaml/constraint/constraint.go b/pipeline/frontend/yaml/constraint/constraint.go index 54af231c6..22c4d284f 100644 --- a/pipeline/frontend/yaml/constraint/constraint.go +++ b/pipeline/frontend/yaml/constraint/constraint.go @@ -50,7 +50,7 @@ type ( // Match returns true if all constraints match the given input. If a single // constraint fails a false value is returned. func (c *Constraints) Match(metadata frontend.Metadata) bool { - match := c.Platform.Match(metadata.Sys.Arch) && + match := c.Platform.Match(metadata.Sys.Platform) && c.Environment.Match(metadata.Curr.Target) && c.Event.Match(metadata.Curr.Event) && c.Repo.Match(metadata.Repo.Name) && diff --git a/pipeline/frontend/yaml/constraint/constraint_test.go b/pipeline/frontend/yaml/constraint/constraint_test.go index 5eb9e4658..6a2d3ff3b 100644 --- a/pipeline/frontend/yaml/constraint/constraint_test.go +++ b/pipeline/frontend/yaml/constraint/constraint_test.go @@ -440,12 +440,12 @@ func TestConstraints(t *testing.T) { // platform constraint { conf: "{ platform: linux/amd64 }", - with: frontend.Metadata{Sys: frontend.System{Arch: "linux/amd64"}}, + with: frontend.Metadata{Sys: frontend.System{Platform: "linux/amd64"}}, want: true, }, { conf: "{ repo: linux/amd64 }", - with: frontend.Metadata{Sys: frontend.System{Arch: "windows/amd64"}}, + with: frontend.Metadata{Sys: frontend.System{Platform: "windows/amd64"}}, want: false, }, // instance constraint diff --git a/pipeline/rpc/client_grpc.go b/pipeline/rpc/client_grpc.go index 96913ec3f..71bdf072f 100644 --- a/pipeline/rpc/client_grpc.go +++ b/pipeline/rpc/client_grpc.go @@ -40,7 +40,6 @@ func (c *client) Next(ctx context.Context, f Filter) (*Pipeline, error) { var err error req := new(proto.NextRequest) req.Filter = new(proto.Filter) - req.Filter.Expr = f.Expr req.Filter.Labels = f.Labels for { res, err = c.client.Next(ctx, req) diff --git a/pipeline/rpc/peer.go b/pipeline/rpc/peer.go index 4cda5e499..177a76205 100644 --- a/pipeline/rpc/peer.go +++ b/pipeline/rpc/peer.go @@ -10,7 +10,6 @@ type ( // Filter defines filters for fetching items from the queue. Filter struct { Labels map[string]string `json:"labels"` - Expr string `json:"expr"` } // State defines the pipeline state. diff --git a/pipeline/rpc/proto/generate.go b/pipeline/rpc/proto/generate.go index 5e4fe3c86..a0f827ec1 100644 --- a/pipeline/rpc/proto/generate.go +++ b/pipeline/rpc/proto/generate.go @@ -17,6 +17,7 @@ package proto //go:generate protoc --go_out=paths=source_relative:. woodpecker.proto //go:generate protoc --go-grpc_out=paths=source_relative:. woodpecker.proto -// get needed binary's: -// go install google.golang.org/protobuf/cmd/protoc-gen-go -// go install google.golang.org/grpc/cmd/protoc-gen-go-grpc +// install protoc: https://grpc.io/docs/protoc-installation/ +// and get needed binary's: +// go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +// go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest diff --git a/pipeline/rpc/proto/woodpecker.pb.go b/pipeline/rpc/proto/woodpecker.pb.go index 33fefc451..19feb9960 100644 --- a/pipeline/rpc/proto/woodpecker.pb.go +++ b/pipeline/rpc/proto/woodpecker.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 -// protoc v3.18.1 +// protoc-gen-go v1.28.0 +// protoc v3.12.4 // source: woodpecker.proto package proto @@ -328,7 +328,6 @@ type Filter struct { unknownFields protoimpl.UnknownFields Labels map[string]string `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Expr string `protobuf:"bytes,2,opt,name=expr,proto3" json:"expr,omitempty"` } func (x *Filter) Reset() { @@ -370,13 +369,6 @@ func (x *Filter) GetLabels() map[string]string { return nil } -func (x *Filter) GetExpr() string { - if x != nil { - return x.Expr - } - return "" -} - type Pipeline struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1069,98 +1061,96 @@ var file_woodpecker_proto_rawDesc = []byte{ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x75, - 0x74, 0x22, 0x8a, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, - 0x78, 0x70, 0x72, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4e, - 0x0a, 0x08, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x2e, - 0x0a, 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x93, - 0x01, 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3a, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, - 0x47, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, - 0x4e, 0x47, 0x10, 0x02, 0x22, 0x34, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x38, 0x0a, 0x09, 0x4e, 0x65, - 0x78, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2b, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65, - 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x41, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x1d, 0x0a, 0x0b, 0x57, 0x61, 0x69, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x41, 0x0a, 0x0b, 0x44, 0x6f, 0x6e, 0x65, 0x52, 0x65, + 0x74, 0x22, 0x76, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, + 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4e, 0x0a, 0x08, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x2e, 0x0a, 0x12, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x13, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x40, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x22, 0x3a, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0f, + 0x0a, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x22, + 0x34, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, + 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x38, 0x0a, 0x09, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x2b, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x22, + 0x41, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x22, 0x1d, 0x0a, 0x0b, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x22, 0x41, 0x0a, 0x0b, 0x44, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x22, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x22, 0x1f, 0x0a, 0x0d, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x1f, 0x0a, 0x0d, 0x45, 0x78, 0x74, - 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x40, 0x0a, 0x0d, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x04, 0x66, - 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x43, 0x0a, 0x0d, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x22, 0x3d, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x1f, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, - 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0xfa, 0x02, 0x0a, 0x0a, 0x57, 0x6f, - 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x04, 0x4e, 0x65, 0x78, 0x74, - 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x78, - 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, - 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x04, 0x57, 0x61, 0x69, 0x74, 0x12, 0x12, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, - 0x12, 0x2a, 0x0a, 0x04, 0x44, 0x6f, 0x6e, 0x65, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x44, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x06, - 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, - 0x78, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x06, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x06, - 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x28, 0x0a, 0x03, - 0x4c, 0x6f, 0x67, 0x12, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x32, 0x48, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x12, 0x3e, 0x0a, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x42, 0x38, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, - 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2d, 0x63, 0x69, 0x2f, 0x77, 0x6f, 0x6f, - 0x64, 0x70, 0x65, 0x63, 0x6b, 0x65, 0x72, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x40, 0x0a, 0x0d, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x43, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x3d, 0x0a, 0x0a, + 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x04, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x07, 0x0a, 0x05, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x32, 0xfa, 0x02, 0x0a, 0x0a, 0x57, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, + 0x6b, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x04, 0x4e, 0x65, 0x78, 0x74, 0x12, 0x12, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x12, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, + 0x2a, 0x0a, 0x04, 0x57, 0x61, 0x69, 0x74, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x04, 0x44, + 0x6f, 0x6e, 0x65, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x6f, 0x6e, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x06, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x64, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, + 0x64, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x28, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x11, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x00, 0x32, 0x48, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x3e, 0x0a, 0x05, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x38, 0x5a, 0x36, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x6f, 0x6f, 0x64, 0x70, 0x65, + 0x63, 0x6b, 0x65, 0x72, 0x2d, 0x63, 0x69, 0x2f, 0x77, 0x6f, 0x6f, 0x64, 0x70, 0x65, 0x63, 0x6b, + 0x65, 0x72, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pipeline/rpc/proto/woodpecker.proto b/pipeline/rpc/proto/woodpecker.proto index cc6ce4b06..305f8b942 100644 --- a/pipeline/rpc/proto/woodpecker.proto +++ b/pipeline/rpc/proto/woodpecker.proto @@ -31,7 +31,6 @@ message Line { message Filter { map labels = 1; - string expr = 2; } message Pipeline { diff --git a/pipeline/rpc/proto/woodpecker_grpc.pb.go b/pipeline/rpc/proto/woodpecker_grpc.pb.go index c853f2b66..d17bac8d3 100644 --- a/pipeline/rpc/proto/woodpecker_grpc.pb.go +++ b/pipeline/rpc/proto/woodpecker_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.1.0 -// - protoc v3.18.1 +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.12.4 // source: woodpecker.proto package proto diff --git a/pipeline/schema/.woodpecker/test-labels.yml b/pipeline/schema/.woodpecker/test-labels.yml new file mode 100644 index 000000000..0230d299a --- /dev/null +++ b/pipeline/schema/.woodpecker/test-labels.yml @@ -0,0 +1,10 @@ +labels: + location: europe + weather: sun + hostname: "" + +pipeline: + build: + image: golang:latest + commands: + - go test diff --git a/pipeline/schema/.woodpecker/test-platform.yml b/pipeline/schema/.woodpecker/test-platform.yml new file mode 100644 index 000000000..dda1cc8eb --- /dev/null +++ b/pipeline/schema/.woodpecker/test-platform.yml @@ -0,0 +1,7 @@ +platform: linux/amd64 + +pipeline: + build: + image: golang:latest + commands: + - go test diff --git a/pipeline/schema/schema.json b/pipeline/schema/schema.json index 9d2414bd4..28435d78b 100644 --- a/pipeline/schema/schema.json +++ b/pipeline/schema/schema.json @@ -17,6 +17,8 @@ "services": { "$ref": "#/definitions/services" }, "workspace": { "$ref": "#/definitions/workspace" }, "matrix": { "$ref": "#/definitions/matrix" }, + "platform": { "$ref": "#/definitions/platform" }, + "labels": { "$ref": "#/definitions/labels" }, "skip_clone": { "type": "boolean" }, "depends_on": { "type": "array", @@ -270,7 +272,7 @@ "oneOf": [ { "type": "string" }, { - "type" :"array", + "type": "array", "items": { "type": "string" } @@ -311,7 +313,7 @@ "additionalProperties": true }, "matrix": { - "description": "TODO Read more: https://woodpecker-ci.org/docs/usage/matrix-builds", + "description": "Execute pipeline for each matrix combination. Read more: https://woodpecker-ci.org/docs/usage/matrix-pipelines", "type": "object", "properties": { "include": { @@ -329,6 +331,18 @@ }, "minLength": 1 } + }, + "platform": { + "description": "Configures the platform the pipeline will be executed on. Read more: https://woodpecker-ci.org/docs/usage/pipeline-syntax#platform", + "type": "string", + "additionalProperties": false + }, + "labels": { + "description": "Configures the labels used for the agent selection. Read more: https://woodpecker-ci.org/docs/usage/pipeline-syntax#clone", + "type": "object", + "additionalProperties": { + "type": ["boolean", "string", "number"] + } } } } diff --git a/pipeline/schema/schema_test.go b/pipeline/schema/schema_test.go index a2d3ee0d9..3cf956849 100644 --- a/pipeline/schema/schema_test.go +++ b/pipeline/schema/schema_test.go @@ -70,6 +70,14 @@ func TestSchema(t *testing.T) { name: "Workspace", testFile: ".woodpecker/test-workspace.yml", }, + { + name: "Platform", + testFile: ".woodpecker/test-platform.yml", + }, + { + name: "Labels", + testFile: ".woodpecker/test-labels.yml", + }, { name: "Broken Config", testFile: ".woodpecker/test-broken.yml", diff --git a/server/grpc/filter.go b/server/grpc/filter.go index dd4002365..78ecd227d 100644 --- a/server/grpc/filter.go +++ b/server/grpc/filter.go @@ -15,36 +15,30 @@ package grpc import ( - "github.com/woodpecker-ci/expr" - "github.com/woodpecker-ci/woodpecker/pipeline/rpc" "github.com/woodpecker-ci/woodpecker/server/queue" ) -func createFilterFunc(filter rpc.Filter) (queue.Filter, error) { - var st *expr.Selector - var err error - - if filter.Expr != "" { - st, err = expr.ParseString(filter.Expr) - if err != nil { - return nil, err - } - } - +func createFilterFunc(agentFilter rpc.Filter) (queue.FilterFn, error) { return func(task *queue.Task) bool { - if st != nil { - match, _ := st.Eval(expr.NewRow(task.Labels)) - return match - } - - for k, v := range filter.Labels { - // if platform is not set ignore that filter - if k == "platform" && task.Labels[k] == "" { + for taskLabel, taskLabelValue := range task.Labels { + // if a task label is empty it will be ignored + if taskLabelValue == "" { continue } - if task.Labels[k] != v { + agentLabelValue, ok := agentFilter.Labels[taskLabel] + + if !ok { + return false + } + + // if agent label has a wildcard + if agentLabelValue == "*" { + continue + } + + if taskLabelValue != agentLabelValue { return false } } diff --git a/server/grpc/filter_test.go b/server/grpc/filter_test.go index bac98280f..5b8780cd1 100644 --- a/server/grpc/filter_test.go +++ b/server/grpc/filter_test.go @@ -26,72 +26,70 @@ import ( func TestCreateFilterFunc(t *testing.T) { t.Parallel() - type filterTests struct { - tsk queue.Task - exp bool - } - tests := []struct { - struc rpc.Filter - ft []filterTests - }{{ - struc: rpc.Filter{}, - ft: []filterTests{{ - tsk: queue.Task{ - Labels: map[string]string{"platform": "", "repo": "test/woodpecker"}, + name string + agentLabels map[string]string + task queue.Task + exp bool + }{ + { + name: "agent with missing labels", + agentLabels: map[string]string{"repo": "test/woodpecker"}, + task: queue.Task{ + Labels: map[string]string{"platform": "linux/amd64", "repo": "test/woodpecker"}, + }, + exp: false, + }, + { + name: "agent with wrong labels", + agentLabels: map[string]string{"platform": "linux/arm64"}, + task: queue.Task{ + Labels: map[string]string{"platform": "linux/amd64"}, + }, + exp: false, + }, + { + name: "agent with correct labels", + agentLabels: map[string]string{"platform": "linux/amd64", "location": "europe"}, + task: queue.Task{ + Labels: map[string]string{"platform": "linux/amd64", "location": "europe"}, }, exp: true, - }, { - tsk: queue.Task{ + }, + { + name: "agent with additional labels", + agentLabels: map[string]string{"platform": "linux/amd64", "location": "europe"}, + task: queue.Task{ + Labels: map[string]string{"platform": "linux/amd64"}, + }, + exp: true, + }, + { + name: "agent with wildcard label", + agentLabels: map[string]string{"platform": "linux/amd64", "location": "*"}, + task: queue.Task{ + Labels: map[string]string{"platform": "linux/amd64", "location": "america"}, + }, + exp: true, + }, + { + name: "agent with platform label and task without", + agentLabels: map[string]string{"platform": "linux/amd64"}, + task: queue.Task{ Labels: map[string]string{"platform": ""}, }, exp: true, - }}, - }, { - struc: rpc.Filter{ - Labels: map[string]string{"platform": "abc"}, }, - ft: []filterTests{{ - tsk: queue.Task{ - Labels: map[string]string{"platform": "def"}, - }, - exp: false, - }, { - tsk: queue.Task{ - Labels: map[string]string{"platform": ""}, - }, - exp: true, - }}, - }, { - struc: rpc.Filter{ - Expr: "platform = 'abc' OR repo = 'test/woodpecker'", - }, - ft: []filterTests{{ - tsk: queue.Task{ - Labels: map[string]string{"platform": "", "repo": "test/woodpecker"}, - }, - exp: true, - }, { - tsk: queue.Task{ - Labels: map[string]string{"platform": "abc", "repo": "else"}, - }, - exp: true, - }, { - tsk: queue.Task{ - Labels: map[string]string{"platform": "also", "repo": "else"}, - }, - exp: false, - }}, - }} + } for _, test := range tests { - fn, err := createFilterFunc(test.struc) - if !assert.NoError(t, err) { - t.Fail() - } + t.Run(test.name, func(t *testing.T) { + fn, err := createFilterFunc(rpc.Filter{Labels: test.agentLabels}) + if !assert.NoError(t, err) { + t.Fail() + } - for _, ft := range test.ft { - assert.EqualValues(t, ft.exp, fn(&ft.tsk)) - } + assert.EqualValues(t, test.exp, fn(&test.task)) + }) } } diff --git a/server/grpc/rpc.go b/server/grpc/rpc.go index 2f0c4ac65..97c6d39a3 100644 --- a/server/grpc/rpc.go +++ b/server/grpc/rpc.go @@ -52,7 +52,7 @@ type RPC struct { } // Next implements the rpc.Next function -func (s *RPC) Next(c context.Context, filter rpc.Filter) (*rpc.Pipeline, error) { +func (s *RPC) Next(c context.Context, agentFilter rpc.Filter) (*rpc.Pipeline, error) { metadata, ok := grpcMetadata.FromIncomingContext(c) if ok { hostname, ok := metadata["hostname"] @@ -61,7 +61,7 @@ func (s *RPC) Next(c context.Context, filter rpc.Filter) (*rpc.Pipeline, error) } } - fn, err := createFilterFunc(filter) + fn, err := createFilterFunc(agentFilter) if err != nil { return nil, err } diff --git a/server/grpc/server.go b/server/grpc/server.go index 709759d38..43e1f1d4b 100644 --- a/server/grpc/server.go +++ b/server/grpc/server.go @@ -63,7 +63,6 @@ func NewWoodpeckerServer(remote remote.Remote, queue queue.Queue, logger logging func (s *WoodpeckerServer) Next(c context.Context, req *proto.NextRequest) (*proto.NextReply, error) { filter := rpc.Filter{ Labels: req.GetFilter().GetLabels(), - Expr: req.GetFilter().GetExpr(), } res := new(proto.NextReply) diff --git a/server/queue/fifo.go b/server/queue/fifo.go index 0fe32fc7f..f8d2a036c 100644 --- a/server/queue/fifo.go +++ b/server/queue/fifo.go @@ -26,7 +26,7 @@ type entry struct { } type worker struct { - filter Filter + filter FilterFn channel chan *Task } @@ -74,7 +74,7 @@ func (q *fifo) PushAtOnce(c context.Context, tasks []*Task) error { } // Poll retrieves and removes the head of this queue. -func (q *fifo) Poll(c context.Context, f Filter) (*Task, error) { +func (q *fifo) Poll(c context.Context, f FilterFn) (*Task, error) { q.Lock() w := &worker{ channel: make(chan *Task, 1), diff --git a/server/queue/persistent.go b/server/queue/persistent.go index 9e8f197c4..7b8cb9e2f 100644 --- a/server/queue/persistent.go +++ b/server/queue/persistent.go @@ -96,7 +96,7 @@ func (q *persistentQueue) PushAtOnce(c context.Context, tasks []*Task) error { } // Poll retrieves and removes a task head of this queue. -func (q *persistentQueue) Poll(c context.Context, f Filter) (*Task, error) { +func (q *persistentQueue) Poll(c context.Context, f FilterFn) (*Task, error) { task, err := q.Queue.Poll(c, f) if task != nil { log.Debug().Msgf("pull queue item: %s: remove from backup", task.ID) diff --git a/server/queue/queue.go b/server/queue/queue.go index fb998041c..c8f3efbed 100644 --- a/server/queue/queue.go +++ b/server/queue/queue.go @@ -25,7 +25,7 @@ type Task struct { // Data is the actual data in the entry. Data []byte `json:"data"` - // Labels represents the key-value pairs the entry is lebeled with. + // Labels represents the key-value pairs the entry is labeled with. Labels map[string]string `json:"labels,omitempty"` // Task IDs this task depend @@ -128,7 +128,7 @@ func (t *InfoT) String() string { // Filter filters tasks in the queue. If the Filter returns false, // the Task is skipped and not returned to the subscriber. -type Filter func(*Task) bool +type FilterFn func(*Task) bool // Queue defines a task queue for scheduling tasks among // a pool of workers. @@ -140,7 +140,7 @@ type Queue interface { PushAtOnce(c context.Context, tasks []*Task) error // Poll retrieves and removes a task head of this queue. - Poll(c context.Context, f Filter) (*Task, error) + Poll(c context.Context, f FilterFn) (*Task, error) // Extend extends the deadline for a task. Extend(c context.Context, id string) error diff --git a/server/shared/procBuilder.go b/server/shared/procBuilder.go index 864268878..29b680548 100644 --- a/server/shared/procBuilder.go +++ b/server/shared/procBuilder.go @@ -110,8 +110,6 @@ func (b *ProcBuilder) Build() ([]*BuildItem, error) { proc.State = model.StatusSkipped } - metadata.SetPlatform(parsed.Platform) - ir := b.toInternalRepresentation(parsed, environ, metadata, proc.ID) if len(ir.Stages) == 0 { @@ -124,7 +122,7 @@ func (b *ProcBuilder) Build() ([]*BuildItem, error) { Labels: parsed.Labels, DependsOn: parsed.DependsOn, RunsOn: parsed.RunsOn, - Platform: metadata.Sys.Arch, + Platform: parsed.Platform, } if item.Labels == nil { item.Labels = map[string]string{} @@ -365,10 +363,10 @@ func metadataFromStruct(repo *model.Repo, build, last *model.Build, proc *model. Matrix: proc.Environ, }, Sys: frontend.System{ - Name: "woodpecker", - Link: link, - Host: host, - Arch: "linux/amd64", + Name: "woodpecker", + Link: link, + Host: host, + Platform: "", // will be set by pipeline platform option or by agent }, } } diff --git a/vendor/github.com/woodpecker-ci/expr/.gitignore b/vendor/github.com/woodpecker-ci/expr/.gitignore deleted file mode 100644 index e06403978..000000000 --- a/vendor/github.com/woodpecker-ci/expr/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.out -*.txt diff --git a/vendor/github.com/woodpecker-ci/expr/README b/vendor/github.com/woodpecker-ci/expr/README deleted file mode 100644 index 706e57878..000000000 --- a/vendor/github.com/woodpecker-ci/expr/README +++ /dev/null @@ -1,5 +0,0 @@ -Go package for parsing and evaluating SQL expressions. - -Documentation: - - https://pkg.go.dev/github.com/woodpecker-ci/expr diff --git a/vendor/github.com/woodpecker-ci/expr/eval.go b/vendor/github.com/woodpecker-ci/expr/eval.go deleted file mode 100644 index cb60596b5..000000000 --- a/vendor/github.com/woodpecker-ci/expr/eval.go +++ /dev/null @@ -1,158 +0,0 @@ -package expr - -import ( - "bytes" - "path/filepath" - "regexp" - - "github.com/woodpecker-ci/expr/parse" -) - -// state represents the state of an execution. It's not part of the -// statement so that multiple executions of the same statement -// can execute in parallel. -type state struct { - node parse.Node - vars Row -} - -// at marks the state to be on node n, for error reporting. -func (s *state) at(node parse.Node) { - s.node = node -} - -// Walk functions step through the major pieces of the template structure, -// generating output as they go. -func (s *state) walk(node parse.BoolExpr) bool { - s.at(node) - - switch node := node.(type) { - case *parse.ComparisonExpr: - return s.eval(node) - case *parse.AndExpr: - return s.walk(node.Left) && s.walk(node.Right) - case *parse.OrExpr: - return s.walk(node.Left) || s.walk(node.Right) - case *parse.NotExpr: - return !s.walk(node.Expr) - case *parse.ParenBoolExpr: - return s.walk(node.Expr) - default: - panic("invalid node type") - } -} - -func (s *state) eval(node *parse.ComparisonExpr) bool { - switch node.Operator { - case parse.OperatorEq: - return s.evalEq(node) - case parse.OperatorGt: - return s.evalGt(node) - case parse.OperatorGte: - return s.evalGte(node) - case parse.OperatorLt: - return s.evalLt(node) - case parse.OperatorLte: - return s.evalLte(node) - case parse.OperatorNeq: - return !s.evalEq(node) - case parse.OperatorGlob: - return s.evalGlob(node) - case parse.OperatorNotGlob: - return !s.evalGlob(node) - case parse.OperatorRe: - return s.evalRegexp(node) - case parse.OperatorNotRe: - return !s.evalRegexp(node) - case parse.OperatorIn: - return s.evalIn(node) - case parse.OperatorNotIn: - return !s.evalIn(node) - default: - panic("inalid operator type") - } -} - -func (s *state) evalEq(node *parse.ComparisonExpr) bool { - return bytes.Equal( - s.toValue(node.Left), - s.toValue(node.Right), - ) -} - -func (s *state) evalGt(node *parse.ComparisonExpr) bool { - return bytes.Compare( - s.toValue(node.Left), - s.toValue(node.Right), - ) == 1 -} - -func (s *state) evalGte(node *parse.ComparisonExpr) bool { - return bytes.Compare( - s.toValue(node.Left), - s.toValue(node.Right), - ) >= 0 -} - -func (s *state) evalLt(node *parse.ComparisonExpr) bool { - return bytes.Compare( - s.toValue(node.Left), - s.toValue(node.Right), - ) == -1 -} - -func (s *state) evalLte(node *parse.ComparisonExpr) bool { - return bytes.Compare( - s.toValue(node.Left), - s.toValue(node.Right), - ) <= 0 -} - -func (s *state) evalGlob(node *parse.ComparisonExpr) bool { - match, _ := filepath.Match( - string(s.toValue(node.Right)), - string(s.toValue(node.Left)), - ) - return match -} - -func (s *state) evalRegexp(node *parse.ComparisonExpr) bool { - match, _ := regexp.Match( - string(s.toValue(node.Right)), - s.toValue(node.Left), - ) - return match -} - -func (s *state) evalIn(node *parse.ComparisonExpr) bool { - left := s.toValue(node.Left) - right, ok := node.Right.(*parse.ArrayLit) - if !ok { - panic("expected array literal") - } - - for _, expr := range right.Values { - if bytes.Equal(left, s.toValue(expr)) { - return true - } - } - return false -} - -func (s *state) toValue(expr parse.ValExpr) []byte { - switch node := expr.(type) { - case *parse.Field: - return s.vars.Field(node.Name) - case *parse.BasicLit: - return node.Value - default: - panic("invalid expression type") - } -} - -// errRecover is the handler that turns panics into returns. -func errRecover(err *error) { - if e := recover(); e != nil { - *err = e.(error) - } -} diff --git a/vendor/github.com/woodpecker-ci/expr/go.mod b/vendor/github.com/woodpecker-ci/expr/go.mod deleted file mode 100644 index f26310ba4..000000000 --- a/vendor/github.com/woodpecker-ci/expr/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/woodpecker-ci/expr - -go 1.16 - -require github.com/kr/pretty v0.2.1 diff --git a/vendor/github.com/woodpecker-ci/expr/go.sum b/vendor/github.com/woodpecker-ci/expr/go.sum deleted file mode 100644 index 10212ca87..000000000 --- a/vendor/github.com/woodpecker-ci/expr/go.sum +++ /dev/null @@ -1,5 +0,0 @@ -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= diff --git a/vendor/github.com/woodpecker-ci/expr/parse/lex.go b/vendor/github.com/woodpecker-ci/expr/parse/lex.go deleted file mode 100644 index 350c06953..000000000 --- a/vendor/github.com/woodpecker-ci/expr/parse/lex.go +++ /dev/null @@ -1,268 +0,0 @@ -package parse - -import ( - "unicode" - "unicode/utf8" -) - -// token is a lexical token. -type token uint - -// list of lexical tokens. -const ( - // special tokens - tokenIllegal token = iota - tokenEOF - - // identifiers and basic type literals - tokenIdent - tokenText - tokenReal - tokenInteger - - // operators and delimiters - tokenEq // == - tokenLt // < - tokenLte // <= - tokenGt // > - tokenGte // >= - tokenNeq // != - tokenComma // , - tokenLparen // ( - tokenRparen // ) - - // keywords - tokenNot - tokenAnd - tokenOr - tokenIn - tokenGlob - tokenRegexp - tokenBetween - tokenTrue - tokenFalse -) - -// lexer implements a lexical scanner that reads unicode characters -// and tokens from a byte buffer. -type lexer struct { - buf []byte - pos int - start int - width int -} - -// scan reads the next token or Unicode character from source and -// returns it. It returns EOF at the end of the source. -func (l *lexer) scan() token { - l.start = l.pos - l.skipWhitespace() - - r := l.read() - switch { - case isIdent(r): - l.unread() - return l.scanIdent() - case isQuote(r): - l.unread() - return l.scanQuote() - case isNumeric(r): - l.unread() - return l.scanNumber() - case isCompare(r): - l.unread() - return l.scanCompare() - } - - switch r { - case eof: - return tokenEOF - case '(': - return tokenLparen - case ')': - return tokenRparen - case ',': - return tokenComma - } - - return tokenIllegal -} - -// peek reads the next token or Unicode character from source and -// returns it without advancing the scanner. -func (l *lexer) peek() token { - var ( - pos = l.pos - start = l.start - width = l.width - ) - tok := l.scan() - l.pos = pos - l.start = start - l.width = width - return tok -} - -// bytes returns the bytes corresponding to the most recently scanned -// token. Valid after calling Scan(). -func (l *lexer) bytes() []byte { - return l.buf[l.start:l.pos] -} - -// string returns the string corresponding to the most recently scanned -// token. Valid after calling Scan(). -func (l *lexer) string() string { - return string(l.bytes()) -} - -// init initializes a scanner with a new buffer. -func (l *lexer) init(buf []byte) { - l.buf = buf - l.pos = 0 - l.start = 0 - l.width = 0 -} - -func (l *lexer) scanIdent() token { - for { - if r := l.read(); r == eof { - break - } else if !isIdent(r) { - l.unread() - break - } - } - - ident := l.bytes() - switch string(ident) { - case "NOT", "not": - return tokenNot - case "AND", "and": - return tokenAnd - case "OR", "or": - return tokenOr - case "IN", "in": - return tokenIn - case "GLOB", "glob": - return tokenGlob - case "REGEXP", "regexp": - return tokenRegexp - case "BETWEEN", "between": - return tokenBetween - case "TRUE", "true": - return tokenTrue - case "FALSE", "false": - return tokenFalse - } - - return tokenIdent -} - -func (l *lexer) scanQuote() (tok token) { - l.read() // consume first quote - - for { - if r := l.read(); r == eof { - return tokenIllegal - } else if isQuote(r) { - break - } - } - return tokenText -} - -func (l *lexer) scanNumber() token { - for { - if r := l.read(); r == eof { - break - } else if !isNumeric(r) { - l.unread() - break - } - } - return tokenInteger -} - -func (l *lexer) scanCompare() (tok token) { - switch l.read() { - case '=': - tok = tokenEq - case '!': - tok = tokenNeq - case '>': - tok = tokenGt - case '<': - tok = tokenLt - } - - r := l.read() - switch { - case tok == tokenGt && r == '=': - tok = tokenGte - case tok == tokenLt && r == '=': - tok = tokenLte - case tok == tokenEq && r == '=': - tok = tokenEq - case tok == tokenNeq && r == '=': - tok = tokenNeq - case tok == tokenNeq && r != '=': - tok = tokenIllegal - default: - l.unread() - } - return -} - -func (l *lexer) skipWhitespace() { - for { - if r := l.read(); r == eof { - break - } else if !isWhitespace(r) { - l.unread() - break - } - } - l.ignore() -} - -func (l *lexer) read() rune { - if l.pos >= len(l.buf) { - l.width = 0 - return eof - } - r, w := utf8.DecodeRune(l.buf[l.pos:]) - l.width = w - l.pos += l.width - return r -} - -func (l *lexer) unread() { - l.pos -= l.width -} - -func (l *lexer) ignore() { - l.start = l.pos -} - -// eof rune sent when end of file is reached -var eof = rune(0) - -func isWhitespace(r rune) bool { - return r == ' ' || r == '\t' || r == '\n' -} - -func isNumeric(r rune) bool { - return unicode.IsDigit(r) || r == '.' -} - -func isQuote(r rune) bool { - return r == '\'' -} - -func isCompare(r rune) bool { - return r == '=' || r == '!' || r == '>' || r == '<' -} - -func isIdent(r rune) bool { - return unicode.IsLetter(r) || r == '_' || r == '-' -} diff --git a/vendor/github.com/woodpecker-ci/expr/parse/node.go b/vendor/github.com/woodpecker-ci/expr/parse/node.go deleted file mode 100644 index 952f9a63e..000000000 --- a/vendor/github.com/woodpecker-ci/expr/parse/node.go +++ /dev/null @@ -1,119 +0,0 @@ -package parse - -// Node is an element in the parse tree. -type Node interface { - node() -} - -// ValExpr defines a value expression. -type ValExpr interface { - Node - value() -} - -// BoolExpr defines a boolean expression. -type BoolExpr interface { - Node - bool() -} - -// An expression is represented by a tree consisting of one -// or more of the following concrete expression nodes. -// -type ( - // ComparisonExpr represents a two-value comparison expression. - ComparisonExpr struct { - Operator Operator - Left, Right ValExpr - } - - // AndExpr represents an AND expression. - AndExpr struct { - Left, Right BoolExpr - } - - // OrExpr represents an OR expression. - OrExpr struct { - Left, Right BoolExpr - } - - // NotExpr represents a NOT expression. - NotExpr struct { - Expr BoolExpr - } - - // ParenBoolExpr represents a parenthesized boolean expression. - ParenBoolExpr struct { - Expr BoolExpr - } - - // BasicLit represents a basic literal. - BasicLit struct { - Kind Literal // INT, REAL, TEXT - Value []byte - } - - // ArrayLit represents an array literal. - ArrayLit struct { - Values []ValExpr - } - - // Field represents a value lookup by name. - Field struct { - Name []byte - } -) - -// Operator identifies the type of operator. -type Operator int - -// Comparison operators. -const ( - OperatorEq Operator = iota - OperatorLt - OperatorLte - OperatorGt - OperatorGte - OperatorNeq - OperatorIn - OperatorRe - OperatorGlob - OperatorNotIn - OperatorNotRe - OperatorNotGlob - OperatorBetween - OperatorNotBetween -) - -// Literal identifies the type of literal. -type Literal int - -// The list of possible literal kinds. -const ( - LiteralBool Literal = iota - LiteralInt - LiteralReal - LiteralText -) - -// node() defines the node in a parse tree -func (x *ComparisonExpr) node() {} -func (x *AndExpr) node() {} -func (x *OrExpr) node() {} -func (x *NotExpr) node() {} -func (x *ParenBoolExpr) node() {} -func (x *BasicLit) node() {} -func (x *ArrayLit) node() {} -func (x *Field) node() {} - -// bool() defines the node as a boolean expression. -func (x *ComparisonExpr) bool() {} -func (x *AndExpr) bool() {} -func (x *OrExpr) bool() {} -func (x *NotExpr) bool() {} -func (x *ParenBoolExpr) bool() {} - -// value() defines the node as a value expression. -func (x *BasicLit) value() {} -func (x *ArrayLit) value() {} -func (x *Field) value() {} diff --git a/vendor/github.com/woodpecker-ci/expr/parse/parse.go b/vendor/github.com/woodpecker-ci/expr/parse/parse.go deleted file mode 100644 index 6e8b97e6c..000000000 --- a/vendor/github.com/woodpecker-ci/expr/parse/parse.go +++ /dev/null @@ -1,272 +0,0 @@ -package parse - -import ( - "bytes" - "fmt" -) - -// Tree is the representation of a single parsed SQL statement. -type Tree struct { - Root BoolExpr - - lex *lexer - depth int -} - -// Parse parses the SQL statement and returns a Tree. -func Parse(buf []byte) (*Tree, error) { - t := new(Tree) - t.lex = new(lexer) - return t.Parse(buf) -} - -// Parse parses the SQL statement buffer to construct an ast -// representation for execution. -func (t *Tree) Parse(buf []byte) (tree *Tree, err error) { - defer t.recover(&err) - t.lex.init(buf) - t.Root = t.parseExpr() - return t, nil -} - -// recover is the handler that turns panics into returns. -func (t *Tree) recover(err *error) { - if e := recover(); e != nil { - *err = e.(error) - } -} - -// errorf formats the error and terminates processing. -func (t *Tree) errorf(format string, args ...interface{}) { - t.Root = nil - format = fmt.Sprintf("selector: parse error:%d: %s", t.lex.start, format) - panic(fmt.Errorf(format, args...)) -} - -func (t *Tree) parseExpr() BoolExpr { - switch t.lex.peek() { - case tokenLparen: - t.lex.scan() - return t.parseGroup() - case tokenNot: - t.lex.scan() - return t.parseNot() - } - - left := t.parseVal() - node := t.parseComparison(left) - - switch t.lex.scan() { - case tokenOr: - return t.parseOr(node) - case tokenAnd: - return t.parseAnd(node) - case tokenRparen: - if t.depth == 0 { - t.errorf("unexpected token") - return nil - } - return node - default: - return node - } -} - -func (t *Tree) parseGroup() BoolExpr { - t.depth++ - node := t.parseExpr() - t.depth-- - - switch t.lex.scan() { - case tokenOr: - return t.parseOr(node) - case tokenAnd: - return t.parseAnd(node) - case tokenEOF: - return node - default: - t.errorf("unexpected token") - return nil - } -} - -func (t *Tree) parseAnd(left BoolExpr) BoolExpr { - node := new(AndExpr) - node.Left = left - node.Right = t.parseExpr() - return node -} - -func (t *Tree) parseOr(left BoolExpr) BoolExpr { - node := new(OrExpr) - node.Left = left - node.Right = t.parseExpr() - return node -} - -func (t *Tree) parseNot() BoolExpr { - node := new(NotExpr) - node.Expr = t.parseExpr() - return node -} - -func (t *Tree) parseComparison(left ValExpr) BoolExpr { - var negate bool - if t.lex.peek() == tokenNot { - t.lex.scan() - negate = true - } - - op := t.parseOperator() - - if negate { - switch op { - case OperatorIn: - op = OperatorNotIn - case OperatorGlob: - op = OperatorNotGlob - case OperatorRe: - op = OperatorNotRe - case OperatorBetween: - op = OperatorNotBetween - } - } - - switch op { - case OperatorBetween: - return t.parseBetween(left) - case OperatorNotBetween: - return t.parseNotBetween(left) - } - - node := new(ComparisonExpr) - node.Left = left - node.Operator = op - - switch node.Operator { - case OperatorIn, OperatorNotIn: - node.Right = t.parseList() - case OperatorRe, OperatorNotRe: - // TODO we should use a custom regexp node here that parses and - // compiles the regexp, insteam of recompiling on every evaluation. - node.Right = t.parseVal() - default: - node.Right = t.parseVal() - } - return node -} - -func (t *Tree) parseNotBetween(value ValExpr) BoolExpr { - node := new(NotExpr) - node.Expr = t.parseBetween(value) - return node -} - -func (t *Tree) parseBetween(value ValExpr) BoolExpr { - left := new(ComparisonExpr) - left.Left = value - left.Operator = OperatorGte - left.Right = t.parseVal() - - if t.lex.scan() != tokenAnd { - t.errorf("unexpected token, expecting AND") - return nil - } - - right := new(ComparisonExpr) - right.Left = value - right.Operator = OperatorLte - right.Right = t.parseVal() - - node := new(AndExpr) - node.Left = left - node.Right = right - return node -} - -func (t *Tree) parseOperator() (op Operator) { - switch t.lex.scan() { - case tokenEq: - return OperatorEq - case tokenGt: - return OperatorGt - case tokenGte: - return OperatorGte - case tokenLt: - return OperatorLt - case tokenLte: - return OperatorLte - case tokenNeq: - return OperatorNeq - case tokenIn: - return OperatorIn - case tokenRegexp: - return OperatorRe - case tokenGlob: - return OperatorGlob - case tokenBetween: - return OperatorBetween - default: - t.errorf("illegal operator") - return - } -} - -func (t *Tree) parseVal() ValExpr { - switch t.lex.scan() { - case tokenIdent: - node := new(Field) - node.Name = t.lex.bytes() - return node - case tokenText: - return t.parseText() - case tokenReal, tokenInteger, tokenTrue, tokenFalse: - node := new(BasicLit) - node.Value = t.lex.bytes() - return node - default: - t.errorf("illegal value expression") - return nil - } -} - -func (t *Tree) parseList() ValExpr { - if t.lex.scan() != tokenLparen { - t.errorf("unexpected token, expecting (") - return nil - } - node := new(ArrayLit) - for { - next := t.lex.peek() - switch next { - case tokenEOF: - t.errorf("unexpected eof, expecting )") - case tokenComma: - t.lex.scan() - case tokenRparen: - t.lex.scan() - return node - default: - child := t.parseVal() - node.Values = append(node.Values, child) - } - } -} - -func (t *Tree) parseText() ValExpr { - node := new(BasicLit) - node.Value = t.lex.bytes() - - // this is where we strip the starting and ending quote - // and unescape the string. On the surface this might look - // like it is subject to index out of bounds errors but - // it is safe because it is already verified by the lexer. - node.Value = node.Value[1 : len(node.Value)-1] - node.Value = bytes.Replace(node.Value, quoteEscaped, quoteUnescaped, -1) - return node -} - -var ( - quoteEscaped = []byte("\\'") - quoteUnescaped = []byte("'") -) diff --git a/vendor/github.com/woodpecker-ci/expr/selector.go b/vendor/github.com/woodpecker-ci/expr/selector.go deleted file mode 100644 index e3fb2d8ba..000000000 --- a/vendor/github.com/woodpecker-ci/expr/selector.go +++ /dev/null @@ -1,50 +0,0 @@ -package expr - -import "github.com/woodpecker-ci/expr/parse" - -// Selector reprents a parsed SQL selector statement. -type Selector struct { - *parse.Tree -} - -// Parse parses the SQL statement and returns a new Statement object. -func Parse(b []byte) (selector *Selector, err error) { - selector = new(Selector) - selector.Tree, err = parse.Parse(b) - return -} - -// ParseString parses the SQL statement and returns a new Statement object. -func ParseString(s string) (selector *Selector, err error) { - return Parse([]byte(s)) -} - -// Eval evaluates the SQL statement using the provided data and returns true -// if all conditions are satisfied. If a runtime error is experiences a false -// value is returned along with an error message. -func (s *Selector) Eval(row Row) (match bool, err error) { - defer errRecover(&err) - state := &state{vars: row} - match = state.walk(s.Root) - return -} - -// Row defines a row of columnar data. -// -// Note that the field name and field values are represented as []byte -// since stomp header names and values are represented as []byte to avoid -// extra allocations when converting from []byte to string. -type Row interface { - Field([]byte) []byte -} - -// NewRow return a Row bound to a map of key value strings. -func NewRow(m map[string]string) Row { - return mapRow(m) -} - -type mapRow map[string]string - -func (m mapRow) Field(name []byte) []byte { - return []byte(m[string(name)]) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index cfd07ddcc..7da179729 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -606,10 +606,6 @@ github.com/ultraware/whitespace github.com/urfave/cli/v2 # github.com/uudashr/gocognit v1.0.5 github.com/uudashr/gocognit -# github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915 -## explicit -github.com/woodpecker-ci/expr -github.com/woodpecker-ci/expr/parse # github.com/xanzy/go-gitlab v0.64.0 ## explicit github.com/xanzy/go-gitlab