diff --git a/docs/docs/20-usage/20-pipeline-syntax.md b/docs/docs/20-usage/20-pipeline-syntax.md index c8853dcba4..1b9920cf13 100644 --- a/docs/docs/20-usage/20-pipeline-syntax.md +++ b/docs/docs/20-usage/20-pipeline-syntax.md @@ -380,6 +380,11 @@ Woodpecker gives the ability to define Docker volumes in the Yaml. You can use t For more details check the [volumes docs](/docs/usage/volumes/). +### `detach` + +Woodpecker gives the ability to detach steps to run them in background until the pipeline finishes. + +For more details check the [service docs](/docs/usage/services#detachment). ## Advanced Configurations diff --git a/pipeline/frontend/yaml/compiler/cacher.go b/pipeline/frontend/yaml/compiler/cacher.go index 3de19b50cd..3c27816c9b 100644 --- a/pipeline/frontend/yaml/compiler/cacher.go +++ b/pipeline/frontend/yaml/compiler/cacher.go @@ -23,7 +23,7 @@ func (c *volumeCacher) Restore(repo, branch string, mounts []string) *yaml.Conta return &yaml.Container{ Name: "rebuild_cache", Image: "plugins/volume-cache:1.0.0", - Vargs: map[string]interface{}{ + Settings: map[string]interface{}{ "mount": mounts, "path": "/cache", "restore": true, @@ -46,7 +46,7 @@ func (c *volumeCacher) Rebuild(repo, branch string, mounts []string) *yaml.Conta return &yaml.Container{ Name: "rebuild_cache", Image: "plugins/volume-cache:1.0.0", - Vargs: map[string]interface{}{ + Settings: map[string]interface{}{ "mount": mounts, "path": "/cache", "rebuild": true, @@ -76,7 +76,7 @@ func (c *s3Cacher) Restore(repo, branch string, mounts []string) *yaml.Container return &yaml.Container{ Name: "rebuild_cache", Image: "plugins/s3-cache:latest", - Vargs: map[string]interface{}{ + Settings: map[string]interface{}{ "mount": mounts, "access_key": c.access, "secret_key": c.secret, @@ -91,7 +91,7 @@ func (c *s3Cacher) Rebuild(repo, branch string, mounts []string) *yaml.Container return &yaml.Container{ Name: "rebuild_cache", Image: "plugins/s3-cache:latest", - Vargs: map[string]interface{}{ + Settings: map[string]interface{}{ "mount": mounts, "access_key": c.access, "secret_key": c.secret, diff --git a/pipeline/frontend/yaml/compiler/compiler.go b/pipeline/frontend/yaml/compiler/compiler.go index 5742edf94a..ab542a17ac 100644 --- a/pipeline/frontend/yaml/compiler/compiler.go +++ b/pipeline/frontend/yaml/compiler/compiler.go @@ -114,7 +114,7 @@ func (c *Compiler) Compile(conf *yaml.Config) *backend.Config { // TODO: switch to `:latest` once v1.1.0 got released // https://github.com/woodpecker-ci/plugin-git/issues/3 Image: "woodpeckerci/plugin-git:next", - Vargs: map[string]interface{}{"depth": "0"}, + Settings: map[string]interface{}{"depth": "0"}, Environment: c.cloneEnv, } name := fmt.Sprintf("%s_clone", c.prefix) diff --git a/pipeline/frontend/yaml/compiler/convert.go b/pipeline/frontend/yaml/compiler/convert.go index 2e9674c429..be9df7efac 100644 --- a/pipeline/frontend/yaml/compiler/convert.go +++ b/pipeline/frontend/yaml/compiler/convert.go @@ -72,7 +72,7 @@ func (c *Compiler) createProcess(name string, container *yaml.Container, section } if !detached { - if err := paramsToEnv(container.Vargs, environment); err != nil { + if err := paramsToEnv(container.Settings, environment); err != nil { log.Error().Err(err).Msg("paramsToEnv") } } diff --git a/pipeline/frontend/yaml/container.go b/pipeline/frontend/yaml/container.go index 3172d97f46..180805306f 100644 --- a/pipeline/frontend/yaml/container.go +++ b/pipeline/frontend/yaml/container.go @@ -58,7 +58,9 @@ type ( Secrets Secrets `yaml:"secrets,omitempty"` Sysctls types.SliceorMap `yaml:"sysctls,omitempty"` Constraints Constraints `yaml:"when,omitempty"` - Vargs map[string]interface{} `yaml:",inline"` + Settings map[string]interface{} `yaml:"settings"` + // Deprecated + Vargs map[string]interface{} `yaml:",inline"` // TODO: remove deprecated with v0.16.0 } ) @@ -84,5 +86,17 @@ func (c *Containers) UnmarshalYAML(value *yaml.Node) error { c.Containers = append(c.Containers, &container) } } + + // TODO: drop Vargs in favor of Settings in v1.16.0 release + for _, cc := range c.Containers { + if cc.Settings == nil && cc.Vargs != nil { + cc.Settings = make(map[string]interface{}) + } + for k, v := range cc.Vargs { + cc.Settings[k] = v + } + cc.Vargs = nil + } + return nil } diff --git a/pipeline/frontend/yaml/container_test.go b/pipeline/frontend/yaml/container_test.go index bb5bb34d13..bc54681888 100644 --- a/pipeline/frontend/yaml/container_test.go +++ b/pipeline/frontend/yaml/container_test.go @@ -58,6 +58,10 @@ tmpfs: - /var/lib/test when: branch: master +settings: + foo: bar + baz: false +deprecated_setting: fallback `) func TestUnmarshalContainer(t *testing.T) { @@ -110,6 +114,13 @@ func TestUnmarshalContainer(t *testing.T) { Include: []string{"master"}, }, }, + Settings: map[string]interface{}{ + "foo": "bar", + "baz": false, + }, + Vargs: map[string]interface{}{ + "deprecated_setting": "fallback", + }, } got := Container{} err := yaml.Unmarshal(containerYaml, &got) @@ -135,11 +146,15 @@ func TestUnmarshalContainers(t *testing.T) { }, }, { - from: "test: { name: unit_test, image: node }", + from: "test: { name: unit_test, image: node, deprecated_setting: fallback, settings: { normal_setting: true } }", want: []*Container{ { Name: "unit_test", Image: "node", + Settings: map[string]interface{}{ + "deprecated_setting": "fallback", + "normal_setting": true, + }, }, }, }, diff --git a/pipeline/frontend/yaml/linter/linter.go b/pipeline/frontend/yaml/linter/linter.go index c4bf621161..4ed47fb3f1 100644 --- a/pipeline/frontend/yaml/linter/linter.go +++ b/pipeline/frontend/yaml/linter/linter.go @@ -76,9 +76,9 @@ func (l *Linter) lintCommands(c *yaml.Container) error { if len(c.Commands) == 0 { return nil } - if len(c.Vargs) != 0 { + if len(c.Settings) != 0 { var keys []string - for key := range c.Vargs { + for key := range c.Settings { keys = append(keys, key) } return fmt.Errorf("Cannot configure both commands and custom attributes %v", keys) diff --git a/pipeline/frontend/yaml/linter/linter_test.go b/pipeline/frontend/yaml/linter/linter_test.go index 2fcccc038f..e6c6a56a30 100644 --- a/pipeline/frontend/yaml/linter/linter_test.go +++ b/pipeline/frontend/yaml/linter/linter_test.go @@ -21,6 +21,8 @@ pipeline: publish: image: plugins/docker repo: foo/bar + settings: + foo: bar services: redis: image: redis diff --git a/pipeline/schema/.woodpecker/test-plugin.yml b/pipeline/schema/.woodpecker/test-plugin.yml index 244cacf251..7d82c5275f 100644 --- a/pipeline/schema/.woodpecker/test-plugin.yml +++ b/pipeline/schema/.woodpecker/test-plugin.yml @@ -7,9 +7,11 @@ pipeline: publish: image: plugins/docker - repo: foo/bar - tags: latest + settings: + repo: foo/bar + tags: latest notify: image: plugins/slack - channel: dev + settings: + channel: dev diff --git a/pipeline/schema/.woodpecker/test-step.yml b/pipeline/schema/.woodpecker/test-step.yml index f2c2b6742f..f6d01afecb 100644 --- a/pipeline/schema/.woodpecker/test-step.yml +++ b/pipeline/schema/.woodpecker/test-step.yml @@ -21,6 +21,15 @@ pipeline: - go test environment: + image: golang + environment: + CGO: 0 + GOOS: linux + GOARCH: amd64 + commands: + - go test + + environment-array: image: golang environment: - CGO=0 diff --git a/pipeline/schema/schema.json b/pipeline/schema/schema.json index 10de74452e..2837211231 100644 --- a/pipeline/schema/schema.json +++ b/pipeline/schema/schema.json @@ -97,7 +97,7 @@ "step": { "description": "Every step of your pipeline executes arbitrary commands inside a specified docker container. Read more: https://woodpecker-ci.org/docs/usage/pipeline-syntax#steps", "type": "object", - "additionalProperties": true, + "additionalProperties": false, "required": ["image"], "properties": { "image": { @@ -121,9 +121,19 @@ }, "environment": { "description": "Pass environment variables to a pipeline step. Read more: https://woodpecker-ci.org/docs/usage/environment", - "type": "array", - "items": { "type": "string" }, - "minLength": 1 + "oneOf": [ + { + "type": "array", + "items": { "type": "string" }, + "minLength": 1 + }, + { + "type": "object", + "additionalProperties": { + "type": ["boolean", "string", "number"] + } + } + ] }, "secrets": { "description": "Pass secrets to a pipeline step at runtime. Read more: https://woodpecker-ci.org/docs/usage/secrets", @@ -156,6 +166,17 @@ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minLength": 1 } ] + }, + "detach": { + "description": "Detach a step to run in background until pipeline finishes. Read more: https://woodpecker-ci.org/docs/usage/services#detachment", + "type": "boolean" + }, + "settings": { + "description": "Change the settings of your plugin. Read more: https://woodpecker-ci.org/docs/usage/plugins/plugins", + "type": "object", + "additionalProperties": { + "type": ["boolean", "string", "number"] + } } } },