diff --git a/pipeline/container.go b/pipeline/container.go index 395fce02..b4ecc4a9 100644 --- a/pipeline/container.go +++ b/pipeline/container.go @@ -191,8 +191,9 @@ func (c *Container) Execute(r *RuleData) bool { execute = false // check if you need to run a status failure ruleset - if !(c.Ruleset.If.Empty() && c.Ruleset.Unless.Empty()) && - !(c.Ruleset.If.NoStatus() && c.Ruleset.Unless.NoStatus()) && + + if ((!(c.Ruleset.If.Empty() && c.Ruleset.Unless.Empty()) && + !(c.Ruleset.If.NoStatus() && c.Ruleset.Unless.NoStatus())) || c.Ruleset.If.Parallel) && c.Ruleset.Match(r) { // approve the need to run the container execute = true diff --git a/pipeline/ruleset.go b/pipeline/ruleset.go index a2a2045f..e63ba0fc 100644 --- a/pipeline/ruleset.go +++ b/pipeline/ruleset.go @@ -30,14 +30,15 @@ type ( // // swagger:model PipelineRules Rules struct { - Branch Ruletype `json:"branch,omitempty" yaml:"branch,omitempty"` - Comment Ruletype `json:"comment,omitempty" yaml:"comment,omitempty"` - Event Ruletype `json:"event,omitempty" yaml:"event,omitempty"` - Path Ruletype `json:"path,omitempty" yaml:"path,omitempty"` - Repo Ruletype `json:"repo,omitempty" yaml:"repo,omitempty"` - Status Ruletype `json:"status,omitempty" yaml:"status,omitempty"` - Tag Ruletype `json:"tag,omitempty" yaml:"tag,omitempty"` - Target Ruletype `json:"target,omitempty" yaml:"target,omitempty"` + Branch Ruletype `json:"branch,omitempty" yaml:"branch,omitempty"` + Comment Ruletype `json:"comment,omitempty" yaml:"comment,omitempty"` + Event Ruletype `json:"event,omitempty" yaml:"event,omitempty"` + Path Ruletype `json:"path,omitempty" yaml:"path,omitempty"` + Repo Ruletype `json:"repo,omitempty" yaml:"repo,omitempty"` + Status Ruletype `json:"status,omitempty" yaml:"status,omitempty"` + Tag Ruletype `json:"tag,omitempty" yaml:"tag,omitempty"` + Target Ruletype `json:"target,omitempty" yaml:"target,omitempty"` + Parallel bool `json:"-" yaml:"-"` } // Ruletype is the pipeline representation of an element @@ -49,14 +50,15 @@ type ( // RuleData is the data to check our ruleset // against for a step in a pipeline. RuleData struct { - Branch string `json:"branch,omitempty" yaml:"branch,omitempty"` - Comment string `json:"comment,omitempty" yaml:"comment,omitempty"` - Event string `json:"event,omitempty" yaml:"event,omitempty"` - Path []string `json:"path,omitempty" yaml:"path,omitempty"` - Repo string `json:"repo,omitempty" yaml:"repo,omitempty"` - Status string `json:"status,omitempty" yaml:"status,omitempty"` - Tag string `json:"tag,omitempty" yaml:"tag,omitempty"` - Target string `json:"target,omitempty" yaml:"target,omitempty"` + Branch string `json:"branch,omitempty" yaml:"branch,omitempty"` + Comment string `json:"comment,omitempty" yaml:"comment,omitempty"` + Event string `json:"event,omitempty" yaml:"event,omitempty"` + Path []string `json:"path,omitempty" yaml:"path,omitempty"` + Repo string `json:"repo,omitempty" yaml:"repo,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Tag string `json:"tag,omitempty" yaml:"tag,omitempty"` + Target string `json:"target,omitempty" yaml:"target,omitempty"` + Parallel bool `json:"-" yaml:"-"` } ) diff --git a/pipeline/stage.go b/pipeline/stage.go index 9fc40691..e1c9d449 100644 --- a/pipeline/stage.go +++ b/pipeline/stage.go @@ -26,6 +26,7 @@ type ( Environment map[string]string `json:"environment,omitempty" yaml:"environment,omitempty"` Name string `json:"name,omitempty" yaml:"name,omitempty"` Needs []string `json:"needs,omitempty" yaml:"needs,omitempty"` + Independent bool `json:"independent,omitempty" yaml:"independent,omitempty"` Steps ContainerSlice `json:"steps,omitempty" yaml:"steps,omitempty"` } ) diff --git a/yaml/build_test.go b/yaml/build_test.go index 5d8cd966..adb9ed63 100644 --- a/yaml/build_test.go +++ b/yaml/build_test.go @@ -333,8 +333,9 @@ func TestYaml_Build_UnmarshalYAML(t *testing.T) { }, Stages: StageSlice{ { - Name: "dependencies", - Needs: []string{"clone"}, + Name: "dependencies", + Needs: []string{"clone"}, + Independent: false, Steps: StepSlice{ { Commands: raw.StringSlice{"./gradlew downloadDependencies"}, @@ -368,8 +369,9 @@ func TestYaml_Build_UnmarshalYAML(t *testing.T) { }, }, { - Name: "test", - Needs: []string{"dependencies", "clone"}, + Name: "test", + Needs: []string{"dependencies", "clone"}, + Independent: false, Steps: StepSlice{ { Commands: raw.StringSlice{"./gradlew check"}, @@ -403,8 +405,9 @@ func TestYaml_Build_UnmarshalYAML(t *testing.T) { }, }, { - Name: "build", - Needs: []string{"dependencies", "clone"}, + Name: "build", + Needs: []string{"dependencies", "clone"}, + Independent: true, Steps: StepSlice{ { Commands: raw.StringSlice{"./gradlew build"}, diff --git a/yaml/stage.go b/yaml/stage.go index 355ecbed..8a4bc5d6 100644 --- a/yaml/stage.go +++ b/yaml/stage.go @@ -24,6 +24,7 @@ type ( Environment raw.StringSliceMap `yaml:"environment,omitempty" json:"environment,omitempty" jsonschema:"description=Provide environment variables injected into the container environment.\nReference: https://go-vela.github.io/docs/reference/yaml/stages/#the-environment-tag"` Name string `yaml:"name,omitempty" json:"name,omitempty" jsonschema:"minLength=1,description=Unique identifier for the stage in the pipeline.\nReference: https://go-vela.github.io/docs/reference/yaml/stages/#the-name-tag"` Needs raw.StringSlice `yaml:"needs,omitempty,flow" json:"needs,omitempty" jsonschema:"description=Stages that must complete before starting the current one.\nReference: https://go-vela.github.io/docs/reference/yaml/stages/#the-needs-tag"` + Independent bool `yaml:"independent,omitempty" json:"independent,omitempty" jsonschema:"description=Stage will continue executing if other stage fails"` Steps StepSlice `yaml:"steps,omitempty" json:"steps,omitempty" jsonschema:"required,description=Sequential execution instructions for the stage.\nReference: https://go-vela.github.io/docs/reference/yaml/stages/#the-steps-tag"` } ) @@ -42,6 +43,7 @@ func (s *StageSlice) ToPipeline() *pipeline.StageSlice { Environment: stage.Environment, Name: stage.Name, Needs: stage.Needs, + Independent: stage.Independent, Steps: *stage.Steps.ToPipeline(), }) } @@ -113,6 +115,9 @@ func (s StageSlice) MarshalYAML() (interface{}, error) { // add the existing needs to the new stage outputStage.Needs = inputStage.Needs + // add the existing dependent tag to the new stage + outputStage.Independent = inputStage.Independent + // add the existing steps to the new stage outputStage.Steps = inputStage.Steps diff --git a/yaml/stage_test.go b/yaml/stage_test.go index 9e138fcd..88c23a29 100644 --- a/yaml/stage_test.go +++ b/yaml/stage_test.go @@ -193,6 +193,7 @@ func TestYaml_StageSlice_UnmarshalYAML(t *testing.T) { Environment: map[string]string{ "STAGE_ENV_VAR": "stage", }, + Independent: true, Steps: StepSlice{ { Commands: []string{"./gradlew downloadDependencies"}, @@ -213,6 +214,7 @@ func TestYaml_StageSlice_UnmarshalYAML(t *testing.T) { "STAGE_ENV_VAR": "stage", "SECOND_STAGE_ENV": "stage2", }, + Independent: false, Steps: StepSlice{ { Commands: []string{"./gradlew check"}, @@ -232,6 +234,7 @@ func TestYaml_StageSlice_UnmarshalYAML(t *testing.T) { Environment: map[string]string{ "STAGE_ENV_VAR": "stage", }, + Independent: false, Steps: StepSlice{ { Commands: []string{"./gradlew build"}, @@ -310,8 +313,9 @@ func TestYaml_StageSlice_MarshalYAML(t *testing.T) { file: "testdata/stage.yml", want: &StageSlice{ { - Name: "dependencies", - Needs: []string{"clone"}, + Name: "dependencies", + Needs: []string{"clone"}, + Independent: true, Steps: StepSlice{ { Commands: []string{"./gradlew downloadDependencies"}, @@ -326,8 +330,9 @@ func TestYaml_StageSlice_MarshalYAML(t *testing.T) { }, }, { - Name: "test", - Needs: []string{"dependencies", "clone"}, + Name: "test", + Needs: []string{"dependencies", "clone"}, + Independent: false, Steps: StepSlice{ { Commands: []string{"./gradlew check"}, @@ -342,8 +347,9 @@ func TestYaml_StageSlice_MarshalYAML(t *testing.T) { }, }, { - Name: "build", - Needs: []string{"dependencies", "clone"}, + Name: "build", + Needs: []string{"dependencies", "clone"}, + Independent: false, Steps: StepSlice{ { Commands: []string{"./gradlew build"}, diff --git a/yaml/testdata/build_anchor_stage.yml b/yaml/testdata/build_anchor_stage.yml index bfeb0e43..2fc87932 100644 --- a/yaml/testdata/build_anchor_stage.yml +++ b/yaml/testdata/build_anchor_stage.yml @@ -38,6 +38,7 @@ stages: build: needs: [ dependencies ] + independent: true steps: - name: build commands: diff --git a/yaml/testdata/stage.yml b/yaml/testdata/stage.yml index 6f3fd2ff..543ffdf8 100644 --- a/yaml/testdata/stage.yml +++ b/yaml/testdata/stage.yml @@ -2,6 +2,7 @@ dependencies: environment: STAGE_ENV_VAR: stage + independent: true steps: - name: install commands: @@ -17,6 +18,7 @@ test: environment: STAGE_ENV_VAR: stage SECOND_STAGE_ENV: stage2 + independent: false steps: - name: test commands: