diff --git a/bitrise/util_test.go b/bitrise/util_test.go index ae46e872..37d77cc5 100644 --- a/bitrise/util_test.go +++ b/bitrise/util_test.go @@ -305,3 +305,199 @@ workflows: require.Error(t, err) require.Equal(t, 0, len(warnings)) } + +func TestConfigModelFromYAMLFileContent_StepListValidation(t *testing.T) { + tests := []struct { + name string + config string + wantErr string + }{ + { + name: "Invalid bitrise.yml: step bundle in a step bundle's steps list", + config: ` +format_version: '11' +default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git +step_bundles: + build: {} + test: + steps: + - bundle::build: {}`, + wantErr: "step bundle is not allowed in a step list", + }, + { + name: "Invalid bitrise.yml: with group in a step bundle's steps list", + config: ` +format_version: '11' +default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git +step_bundles: + test: + steps: + - with: {}`, + wantErr: "'with' group is not allowed in a step list", + }, + { + name: "Invalid bitrise.yml: step bundle in a 'with' group's steps list", + config: ` +format_version: '11' +default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git +services: + postgres: + image: postgres:13 +workflows: + primary: + steps: + - with: + services: + - postgres + steps: + - bundle::test: {}`, + wantErr: "step bundle is not allowed in a step list", + }, + { + name: "Invalid bitrise.yml: with group in a 'with' group's steps list", + config: ` +format_version: '11' +default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git +services: + postgres: + image: postgres:13 +workflows: + primary: + steps: + - with: + services: + - postgres + steps: + - with: {}`, + wantErr: "'with' group is not allowed in a step list", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, warns, err := ConfigModelFromFileContent([]byte(tt.config), false) + require.Equal(t, []string(nil), warns) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestConfigModelFromJSONFileContent_StepListValidation(t *testing.T) { + tests := []struct { + name string + config string + wantErr string + }{ + { + name: "Invalid bitrise.yml: step bundle in a step bundle's steps list", + config: `{ + "format_version": "11", + "default_step_lib_source": "https://github.com/bitrise-io/bitrise-steplib.git", + "step_bundles": { + "build": {}, + "test": { + "steps": [ + { + "bundle::build": {} + } + ] + } + } +}`, + wantErr: "step bundle is not allowed in a step list", + }, + { + name: "Invalid bitrise.yml: with group in a step bundle's steps list", + config: `{ + "format_version": "11", + "default_step_lib_source": "https://github.com/bitrise-io/bitrise-steplib.git", + "step_bundles": { + "test": { + "steps": [ + { + "with": {} + } + ] + } + } +}`, + wantErr: "'with' group is not allowed in a step list", + }, + { + name: "Invalid bitrise.yml: step bundle in a 'with' group's steps list", + config: `{ + "format_version": "11", + "default_step_lib_source": "https://github.com/bitrise-io/bitrise-steplib.git", + "services": { + "postgres": { + "image": "postgres:13" + } + }, + "workflows": { + "primary": { + "steps": [ + { + "with": { + "services": [ + "postgres" + ], + "steps": [ + { + "bundle::test": {} + } + ] + } + } + ] + } + } +}`, + wantErr: "step bundle is not allowed in a step list", + }, + { + name: "Invalid bitrise.yml: with group in a 'with' group's steps list", + config: `{ + "format_version": "11", + "default_step_lib_source": "https://github.com/bitrise-io/bitrise-steplib.git", + "services": { + "postgres": { + "image": "postgres:13" + } + }, + "workflows": { + "primary": { + "steps": [ + { + "with": { + "services": [ + "postgres" + ], + "steps": [ + { + "with": {} + } + ] + } + } + ] + } + } +}`, + wantErr: "'with' group is not allowed in a step list", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, warns, err := ConfigModelFromFileContent([]byte(tt.config), true) + require.Equal(t, []string(nil), warns) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/models/models_methods.go b/models/models_methods.go index c56df340..925668c8 100644 --- a/models/models_methods.go +++ b/models/models_methods.go @@ -1306,6 +1306,47 @@ func (stepListItem *StepListItemModel) UnmarshalYAML(unmarshal func(interface{}) return nil } +func (stepListStepItem *StepListStepItemModel) UnmarshalJSON(b []byte) error { + var raw map[string]stepmanModels.StepModel + if err := json.Unmarshal(b, &raw); err != nil { + return err + } + + return stepListStepItem.fromRawStepListStepItem(raw) +} + +func (stepListStepItem *StepListStepItemModel) UnmarshalYAML(unmarshal func(interface{}) error) error { + var raw map[string]stepmanModels.StepModel + if err := unmarshal(&raw); err != nil { + return err + } + + return stepListStepItem.fromRawStepListStepItem(raw) +} + +func (stepListStepItem *StepListStepItemModel) fromRawStepListStepItem(raw map[string]stepmanModels.StepModel) error { + var key string + for k := range raw { + key = k + break + } + + // Only Steps are allowed + if key == StepListItemWithKey { + return errors.New("'with' group is not allowed in a step list") + } + if strings.HasPrefix(key, StepListItemStepBundleKeyPrefix) { + return errors.New("step bundle is not allowed in a step list") + } + + *stepListStepItem = map[string]stepmanModels.StepModel{} + for k, v := range raw { + (*stepListStepItem)[k] = v + } + + return nil +} + func (stepListStepItem *StepListStepItemModel) GetStepIDAndStep() (string, stepmanModels.StepModel, error) { if stepListStepItem == nil { return "", stepmanModels.StepModel{}, nil