From 4dfbba7cb812cc7598504da4ac896009bf77ee3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20G=C3=B6drei?= Date: Tue, 16 Jan 2024 10:51:02 +0100 Subject: [PATCH] Control draft pr trigger (#907) * Introduce draft_pull_request_enabled on TriggerMapItemModel and update String func and related tests * Start migrating CheckDuplicatedTriggerMapItems tests * Update trigger item duplication test to support draft pr enabled status * Introduce draft-pr flag for trigger and trigger-check commands * Code cleanup * Typo fix * Migrate trigger map item tests to table driven tests, add draft pr match and string tests * Update trigger map item tests * Add integration tests for draft pr trigger and fix run_and_trigger_params override * Resolve TODOs * Improve TriggerMapModel.checkDuplicatedTriggerMapItems --- _tests/integration/helper.go | 2 +- _tests/integration/json_params_test.go | 16 +- _tests/integration/new_trigger_test.go | 51 +- .../integration/new_trigger_test_bitrise.yml | 4 + cli/commands.go | 10 +- cli/run_trigger_params.go | 18 +- cli/run_trigger_params_test.go | 48 +- cli/trigger.go | 7 +- cli/trigger_check.go | 8 +- models/models_methods_test.go | 77 ++ models/trigger_map.go | 51 +- models/trigger_map_item.go | 40 +- models/trigger_map_item_test.go | 944 +++++++++--------- models/trigger_map_test.go | 240 +++-- 14 files changed, 834 insertions(+), 682 deletions(-) diff --git a/_tests/integration/helper.go b/_tests/integration/helper.go index 686c40557..70ce1fea2 100644 --- a/_tests/integration/helper.go +++ b/_tests/integration/helper.go @@ -19,7 +19,7 @@ func toBase64(t *testing.T, str string) string { return string(bytes) } -func toJSON(t *testing.T, stringStringMap map[string]string) string { +func toJSON(t *testing.T, stringStringMap map[string]interface{}) string { bytes, err := json.Marshal(stringStringMap) require.NoError(t, err) return string(bytes) diff --git a/_tests/integration/json_params_test.go b/_tests/integration/json_params_test.go index ea3d4e62a..f5c131723 100644 --- a/_tests/integration/json_params_test.go +++ b/_tests/integration/json_params_test.go @@ -12,7 +12,7 @@ func Test_JsonParams(t *testing.T) { t.Log("run test") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "workflow": "json_params_test_target", } @@ -24,7 +24,7 @@ func Test_JsonParams(t *testing.T) { t.Log("run test - param override") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "workflow": "exit_code_test_fail", } @@ -36,7 +36,7 @@ func Test_JsonParams(t *testing.T) { t.Log("trigger test") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pattern": "json_params_test_target", } @@ -48,7 +48,7 @@ func Test_JsonParams(t *testing.T) { t.Log("trigger test - param override") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pattern": "exit_code_test_fail", } @@ -60,7 +60,7 @@ func Test_JsonParams(t *testing.T) { t.Log("run test base64") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "workflow": "json_params_test_target", } @@ -72,7 +72,7 @@ func Test_JsonParams(t *testing.T) { t.Log("trigger test base64") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pattern": "json_params_test_target", } @@ -84,7 +84,7 @@ func Test_JsonParams(t *testing.T) { t.Log("trigger check test") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pattern": "json_params_test_target", "format": "json", @@ -98,7 +98,7 @@ func Test_JsonParams(t *testing.T) { t.Log("trigger check test - param override") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pattern": "json_params_test_target", "format": "raw", diff --git a/_tests/integration/new_trigger_test.go b/_tests/integration/new_trigger_test.go index 65c1ae538..c06ae3084 100644 --- a/_tests/integration/new_trigger_test.go +++ b/_tests/integration/new_trigger_test.go @@ -12,7 +12,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("deprecated trigger test") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pattern": "deprecated_code_push", "format": "json", @@ -26,7 +26,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("deprecated trigger test - PR mode") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pattern": "deprecated_pr", "format": "json", @@ -40,7 +40,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("deprecated trigger test - pipeline") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pattern": "deprecated_pipeline", "format": "json", @@ -54,7 +54,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("new trigger test - code push") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "push-branch": "code_push", "format": "json", @@ -68,7 +68,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("new trigger test - code push - no match") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "push-branch": "no_match", "format": "json", @@ -81,7 +81,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("new trigger test - pull request - defined source and target pattern") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pr-source-branch": "pr_source", "pr-target-branch": "pr_target", @@ -96,7 +96,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("new trigger test - pull request - defined source and target pattern - no match") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pr-source-branch": "no_match", "pr-target-branch": "no_match", @@ -110,7 +110,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("new trigger test base64 - pull request - defined source and target pattern") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pr-source-branch": "pr_source", "pr-target-branch": "pr_target", @@ -125,7 +125,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("new trigger test - pull request - defined target pattern") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pr-source-branch": "pr_source", "pr-target-branch": "pr_target_only", @@ -140,7 +140,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("new trigger test - pull request - defined source pattern") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "pr-source-branch": "pr_source_only", "pr-target-branch": "pr_target", @@ -155,7 +155,7 @@ func Test_NewTrigger(t *testing.T) { t.Log("new trigger test - pipeline") { - config := map[string]string{ + config := map[string]interface{}{ "config": configPth, "push-branch": "pipeline_code_push", "format": "json", @@ -166,4 +166,33 @@ func Test_NewTrigger(t *testing.T) { require.NoError(t, err, out) require.Equal(t, `{"pipeline":"pipeline_code_push","push-branch":"pipeline_code_push"}`, out) } + + t.Log("draft pr control test - draft pr disabled - ready to review pr trigger") + { + config := map[string]interface{}{ + "config": configPth, + "pr-source-branch": "no_draft_pr", + "format": "json", + } + + cmd := command.New(binPath(), "trigger-check", "--json-params", toJSON(t, config)) + out, err := cmd.RunAndReturnTrimmedCombinedOutput() + require.NoError(t, err, out) + require.Equal(t, `{"pr-source-branch":"no_draft_pr","workflow":"no_draft_pr"}`, out) + } + + t.Log("draft pr control test - draft pr disabled - draft pr trigger") + { + config := map[string]interface{}{ + "config": configPth, + "pr-source-branch": "no_draft_pr", + "draft-pr": true, + "format": "json", + } + + cmd := command.New(binPath(), "trigger-check", "--json-params", toJSON(t, config)) + out, err := cmd.RunAndReturnTrimmedCombinedOutput() + require.Error(t, err, out) + require.Equal(t, `{"is_valid":true,"error":"no matching pipeline \u0026 workflow found with trigger params: push-branch: , pr-source-branch: no_draft_pr, pr-target-branch: , tag: "}`, out) + } } diff --git a/_tests/integration/new_trigger_test_bitrise.yml b/_tests/integration/new_trigger_test_bitrise.yml index 581a7fbfb..a6a2573f7 100644 --- a/_tests/integration/new_trigger_test_bitrise.yml +++ b/_tests/integration/new_trigger_test_bitrise.yml @@ -23,6 +23,9 @@ trigger_map: workflow: pr_target - pull_request_source_branch: pr_source_only workflow: pr_source +- pull_request_source_branch: no_draft_pr + draft_pull_request_enabled: false + workflow: no_draft_pr pipelines: deprecated_pipeline: @@ -48,3 +51,4 @@ workflows: pr_source_and_target: pr_target: pr_source: + no_draft_pr: diff --git a/cli/commands.go b/cli/commands.go index 418866d9a..52c1b847b 100644 --- a/cli/commands.go +++ b/cli/commands.go @@ -13,11 +13,11 @@ const ( PushBranchKey = "push-branch" PRSourceBranchKey = "pr-source-branch" PRTargetBranchKey = "pr-target-branch" + DraftPRKey = "draft-pr" - IncludeWorkflowMetaKey = "include-workflow-meta" - ConfigKey = "config" - InventoryKey = "inventory" - OuputFormatKey = "format" + ConfigKey = "config" + InventoryKey = "inventory" + OuputFormatKey = "format" ) var ( @@ -60,6 +60,7 @@ var ( cli.StringFlag{Name: PushBranchKey, Usage: "Git push branch name."}, cli.StringFlag{Name: PRSourceBranchKey, Usage: "Git pull request source branch name."}, cli.StringFlag{Name: PRTargetBranchKey, Usage: "Git pull request target branch name."}, + cli.BoolFlag{Name: DraftPRKey, Usage: "Is the pull request in draft state?"}, cli.StringFlag{Name: TagKey, Usage: "Git tag name."}, cli.StringFlag{Name: OuputFormatKey, Usage: "Output format. Accepted: json, yml."}, @@ -68,7 +69,6 @@ var ( cli.StringFlag{Name: JSONParamsKey, Usage: "Specify command flags with json string-string hash."}, cli.StringFlag{Name: JSONParamsBase64Key, Usage: "Specify command flags with base64 encoded json string-string hash."}, - // should deprecate cli.StringFlag{Name: ConfigBase64Key, Usage: "base64 encoded config data."}, cli.StringFlag{Name: InventoryBase64Key, Usage: "base64 encoded inventory data."}, diff --git a/cli/run_trigger_params.go b/cli/run_trigger_params.go index 9d20a4e40..03ffb789b 100644 --- a/cli/run_trigger_params.go +++ b/cli/run_trigger_params.go @@ -20,6 +20,7 @@ type RunAndTriggerParamsModel struct { PushBranch string `json:"push-branch"` PRSourceBranch string `json:"pr-source-branch"` PRTargetBranch string `json:"pr-target-branch"` + IsDraftPR bool `json:"draft-pr"` Tag string `json:"tag"` // Trigger Check Params @@ -44,7 +45,7 @@ func parseRunAndTriggerJSONParams(jsonParams string) (RunAndTriggerParamsModel, func parseRunAndTriggerParams( workflowToRunID, triggerPattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch string, isDraftPR *bool, tag, format, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, @@ -68,7 +69,7 @@ func parseRunAndTriggerParams( } } - // Owerride params + // Override params if workflowToRunID != "" { params.WorkflowToRunID = workflowToRunID } @@ -86,6 +87,9 @@ func parseRunAndTriggerParams( if prTargetBranch != "" { params.PRTargetBranch = prTargetBranch } + if isDraftPR != nil { + params.IsDraftPR = *isDraftPR + } if tag != "" { params.Tag = tag } @@ -115,24 +119,24 @@ func parseRunParams( bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams string) (RunAndTriggerParamsModel, error) { - return parseRunAndTriggerParams(workflowToRunID, "", "", "", "", "", "", bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams) + return parseRunAndTriggerParams(workflowToRunID, "", "", "", "", nil, "", "", bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams) } func parseTriggerParams( triggerPattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch string, isDraftPR *bool, tag, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams string) (RunAndTriggerParamsModel, error) { - return parseRunAndTriggerParams("", triggerPattern, pushBranch, prSourceBranch, prTargetBranch, tag, "", bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams) + return parseRunAndTriggerParams("", triggerPattern, pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag, "", bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams) } func parseTriggerCheckParams( triggerPattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch string, isDraftPR *bool, tag, format, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams string) (RunAndTriggerParamsModel, error) { - return parseRunAndTriggerParams("", triggerPattern, pushBranch, prSourceBranch, prTargetBranch, tag, format, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams) + return parseRunAndTriggerParams("", triggerPattern, pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag, format, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams) } diff --git a/cli/run_trigger_params_test.go b/cli/run_trigger_params_test.go index 68eae2a40..7d1b8aa6b 100644 --- a/cli/run_trigger_params_test.go +++ b/cli/run_trigger_params_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "testing" + "github.com/bitrise-io/go-utils/pointers" "github.com/stretchr/testify/require" ) @@ -13,7 +14,7 @@ func toBase64(t *testing.T, str string) string { return string(bytes) } -func toJSON(t *testing.T, stringStringMap map[string]string) string { +func toJSON(t *testing.T, stringStringMap map[string]interface{}) string { bytes, err := json.Marshal(stringStringMap) require.NoError(t, err) return string(bytes) @@ -22,13 +23,14 @@ func toJSON(t *testing.T, stringStringMap map[string]string) string { func TestParseRunAndTriggerJSONParams(t *testing.T) { t.Log("it parses cli params") { - paramsMap := map[string]string{ + paramsMap := map[string]interface{}{ WorkflowKey: "primary", PatternKey: "master", PushBranchKey: "deploy", PRSourceBranchKey: "development", PRTargetBranchKey: "release", + DraftPRKey: true, TagKey: "0.9.0", OuputFormatKey: "json", @@ -48,6 +50,7 @@ func TestParseRunAndTriggerJSONParams(t *testing.T) { require.Equal(t, "deploy", params.PushBranch) require.Equal(t, "development", params.PRSourceBranch) require.Equal(t, "release", params.PRTargetBranch) + require.Equal(t, true, params.IsDraftPR) require.Equal(t, "0.9.0", params.Tag) require.Equal(t, "json", params.Format) @@ -70,6 +73,7 @@ func TestParseRunAndTriggerJSONParams(t *testing.T) { require.Equal(t, "", params.PushBranch) require.Equal(t, "", params.PRSourceBranch) require.Equal(t, "", params.PRTargetBranch) + require.Equal(t, false, params.IsDraftPR) require.Equal(t, "", params.Format) @@ -90,6 +94,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { pushBranch := "master" prSourceBranch := "develop" prTargetBranch := "master" + isDraftPR := pointers.NewBoolPtr(true) tag := "0.9.0" format := "json" @@ -105,7 +110,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { params, err := parseRunAndTriggerParams( workflow, pattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag, format, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, @@ -119,6 +124,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { require.Equal(t, pushBranch, params.PushBranch) require.Equal(t, prSourceBranch, params.PRSourceBranch) require.Equal(t, prTargetBranch, params.PRTargetBranch) + require.Equal(t, true, params.IsDraftPR) require.Equal(t, tag, params.Tag) require.Equal(t, format, params.Format) @@ -138,6 +144,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { pushBranch := "master" prSourceBranch := "develop" prTargetBranch := "master" + isDraftPR := true tag := "0.9.0" format := "json" @@ -147,13 +154,14 @@ func TestParseRunAndTriggerParams(t *testing.T) { inventoryPath := ".secrets.bitrise.yml" inventoryBase64Data := toBase64(t, ".secrets.bitrise.yml") - paramsMap := map[string]string{ + paramsMap := map[string]interface{}{ WorkflowKey: workflow, PatternKey: pattern, PushBranchKey: pushBranch, PRSourceBranchKey: prSourceBranch, PRTargetBranchKey: prTargetBranch, + DraftPRKey: isDraftPR, TagKey: tag, OuputFormatKey: format, @@ -167,7 +175,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { jsonParams := toJSON(t, paramsMap) base64JSONParams := "" - params, err := parseRunAndTriggerParams("", "", "", "", "", "", "", "", "", "", "", jsonParams, base64JSONParams) + params, err := parseRunAndTriggerParams("", "", "", "", "", nil, "", "", "", "", "", "", jsonParams, base64JSONParams) require.NoError(t, err) require.Equal(t, workflow, params.WorkflowToRunID) @@ -176,6 +184,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { require.Equal(t, pushBranch, params.PushBranch) require.Equal(t, prSourceBranch, params.PRSourceBranch) require.Equal(t, prTargetBranch, params.PRTargetBranch) + require.Equal(t, true, params.IsDraftPR) require.Equal(t, tag, params.Tag) require.Equal(t, format, params.Format) @@ -195,6 +204,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { pushBranch := "master" prSourceBranch := "develop" prTargetBranch := "master" + isDraftPR := true tag := "0.9.0" format := "json" @@ -204,13 +214,14 @@ func TestParseRunAndTriggerParams(t *testing.T) { inventoryPath := ".secrets.bitrise.yml" inventoryBase64Data := toBase64(t, ".secrets.bitrise.yml") - paramsMap := map[string]string{ + paramsMap := map[string]interface{}{ WorkflowKey: workflow, PatternKey: pattern, PushBranchKey: pushBranch, PRSourceBranchKey: prSourceBranch, PRTargetBranchKey: prTargetBranch, + DraftPRKey: isDraftPR, TagKey: tag, OuputFormatKey: format, @@ -224,7 +235,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { jsonParams := "" base64JSONParams := toBase64(t, toJSON(t, paramsMap)) - params, err := parseRunAndTriggerParams("", "", "", "", "", "", "", "", "", "", "", jsonParams, base64JSONParams) + params, err := parseRunAndTriggerParams("", "", "", "", "", nil, "", "", "", "", "", "", jsonParams, base64JSONParams) require.NoError(t, err) require.Equal(t, workflow, params.WorkflowToRunID) @@ -233,6 +244,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { require.Equal(t, pushBranch, params.PushBranch) require.Equal(t, prSourceBranch, params.PRSourceBranch) require.Equal(t, prTargetBranch, params.PRTargetBranch) + require.Equal(t, true, params.IsDraftPR) require.Equal(t, tag, params.Tag) require.Equal(t, format, params.Format) @@ -252,6 +264,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { pushBranch := "master" prSourceBranch := "develop" prTargetBranch := "master" + isDraftPR := false tag := "0.9.0" format := "json" @@ -261,13 +274,14 @@ func TestParseRunAndTriggerParams(t *testing.T) { inventoryPath := ".secrets.bitrise.yml" inventoryBase64Data := toBase64(t, ".secrets.bitrise.yml") - paramsMap := map[string]string{ + paramsMap := map[string]interface{}{ WorkflowKey: workflow, PatternKey: pattern, PushBranchKey: pushBranch, PRSourceBranchKey: prSourceBranch, PRTargetBranchKey: prTargetBranch, + DraftPRKey: isDraftPR, TagKey: tag, OuputFormatKey: format, @@ -278,10 +292,10 @@ func TestParseRunAndTriggerParams(t *testing.T) { InventoryBase64Key: inventoryBase64Data, } - jsonParams := `{"workflow":"test"}` + jsonParams := `{"workflow":"test","draft-pr":true}` base64JSONParams := toBase64(t, toJSON(t, paramsMap)) - params, err := parseRunAndTriggerParams("", "", "", "", "", "", "", "", "", "", "", jsonParams, base64JSONParams) + params, err := parseRunAndTriggerParams("", "", "", "", "", nil, "", "", "", "", "", "", jsonParams, base64JSONParams) require.NoError(t, err) require.Equal(t, "test", params.WorkflowToRunID) @@ -290,6 +304,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { require.Equal(t, "", params.PushBranch) require.Equal(t, "", params.PRSourceBranch) require.Equal(t, "", params.PRTargetBranch) + require.Equal(t, true, params.IsDraftPR) require.Equal(t, "", params.Tag) require.Equal(t, "", params.Format) @@ -309,6 +324,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { pushBranch := "master" prSourceBranch := "develop" prTargetBranch := "master" + isDraftPR := pointers.NewBoolPtr(true) tag := "0.9.0" format := "json" @@ -324,7 +340,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { params, err := parseRunAndTriggerParams( workflow, pattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag, format, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, @@ -338,6 +354,7 @@ func TestParseRunAndTriggerParams(t *testing.T) { require.Equal(t, pushBranch, params.PushBranch) require.Equal(t, prSourceBranch, params.PRSourceBranch) require.Equal(t, prTargetBranch, params.PRTargetBranch) + require.Equal(t, true, params.IsDraftPR) require.Equal(t, tag, params.Tag) require.Equal(t, format, params.Format) @@ -378,6 +395,7 @@ func TestParseRunParams(t *testing.T) { require.Equal(t, "", params.PushBranch) require.Equal(t, "", params.PRSourceBranch) require.Equal(t, "", params.PRTargetBranch) + require.Equal(t, false, params.IsDraftPR) require.Equal(t, "", params.Tag) require.Equal(t, "", params.Format) @@ -397,6 +415,7 @@ func TestParseTriggerParams(t *testing.T) { pushBranch := "master" prSourceBranch := "develop" prTargetBranch := "master" + isDraftPR := pointers.NewBoolPtr(true) tag := "0.9.0" bitriseConfigPath := "bitrise.yml" @@ -410,7 +429,7 @@ func TestParseTriggerParams(t *testing.T) { params, err := parseTriggerParams( pattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, base64JSONParams, @@ -423,6 +442,7 @@ func TestParseTriggerParams(t *testing.T) { require.Equal(t, pushBranch, params.PushBranch) require.Equal(t, prSourceBranch, params.PRSourceBranch) require.Equal(t, prTargetBranch, params.PRTargetBranch) + require.Equal(t, true, params.IsDraftPR) require.Equal(t, tag, params.Tag) require.Equal(t, "", params.Format) @@ -442,6 +462,7 @@ func TestParseTriggerCheckParams(t *testing.T) { pushBranch := "master" prSourceBranch := "develop" prTargetBranch := "master" + isDraftPR := pointers.NewBoolPtr(true) tag := "0.9.0" format := "json" @@ -456,7 +477,7 @@ func TestParseTriggerCheckParams(t *testing.T) { params, err := parseTriggerCheckParams( pattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag, format, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, @@ -470,6 +491,7 @@ func TestParseTriggerCheckParams(t *testing.T) { require.Equal(t, pushBranch, params.PushBranch) require.Equal(t, prSourceBranch, params.PRSourceBranch) require.Equal(t, prTargetBranch, params.PRTargetBranch) + require.Equal(t, true, params.IsDraftPR) require.Equal(t, tag, params.Tag) require.Equal(t, format, params.Format) diff --git a/cli/trigger.go b/cli/trigger.go index 03ecf1281..3061e1ecf 100644 --- a/cli/trigger.go +++ b/cli/trigger.go @@ -28,6 +28,7 @@ var triggerCommand = cli.Command{ cli.StringFlag{Name: PushBranchKey, Usage: "Git push branch name."}, cli.StringFlag{Name: PRSourceBranchKey, Usage: "Git pull request source branch name."}, cli.StringFlag{Name: PRTargetBranchKey, Usage: "Git pull request target branch name."}, + cli.BoolFlag{Name: DraftPRKey, Usage: "Is the pull request in draft state?"}, cli.StringFlag{Name: TagKey, Usage: "Git tag name."}, // cli params used in CI mode @@ -100,6 +101,10 @@ func trigger(c *cli.Context) error { pushBranch := c.String(PushBranchKey) prSourceBranch := c.String(PRSourceBranchKey) prTargetBranch := c.String(PRTargetBranchKey) + var isDraftPR *bool + if c.IsSet(DraftPRKey) { + isDraftPR = pointers.NewBoolPtr(c.Bool(DraftPRKey)) + } tag := c.String(TagKey) bitriseConfigBase64Data := c.String(ConfigBase64Key) @@ -113,7 +118,7 @@ func trigger(c *cli.Context) error { triggerParams, err := parseTriggerParams( triggerPattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, jsonParams, jsonParamsBase64) diff --git a/cli/trigger_check.go b/cli/trigger_check.go index 011338fd4..96403a5ab 100644 --- a/cli/trigger_check.go +++ b/cli/trigger_check.go @@ -65,7 +65,7 @@ func getPipelineAndWorkflowIDByParamsInCompatibleMode(triggerMap models.TriggerM params = migratePatternToParams(params, isPullRequestMode) } - return triggerMap.FirstMatchingTarget(params.PushBranch, params.PRSourceBranch, params.PRTargetBranch, params.Tag) + return triggerMap.FirstMatchingTarget(params.PushBranch, params.PRSourceBranch, params.PRTargetBranch, params.IsDraftPR, params.Tag) } // -------------------- @@ -90,6 +90,10 @@ func triggerCheck(c *cli.Context) error { pushBranch := c.String(PushBranchKey) prSourceBranch := c.String(PRSourceBranchKey) prTargetBranch := c.String(PRTargetBranchKey) + var isDraftPR *bool + if c.IsSet(DraftPRKey) { + isDraftPR = pointers.NewBoolPtr(c.Bool(DraftPRKey)) + } tag := c.String(TagKey) bitriseConfigBase64Data := c.String(ConfigBase64Key) @@ -105,7 +109,7 @@ func triggerCheck(c *cli.Context) error { triggerParams, err := parseTriggerCheckParams( triggerPattern, - pushBranch, prSourceBranch, prTargetBranch, tag, + pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag, format, bitriseConfigPath, bitriseConfigBase64Data, inventoryPath, inventoryBase64Data, diff --git a/models/models_methods_test.go b/models/models_methods_test.go index bbe0986a6..d124af2e2 100644 --- a/models/models_methods_test.go +++ b/models/models_methods_test.go @@ -384,6 +384,83 @@ workflows: } } +// Trigger map +func TestTriggerMapItemValidate(t *testing.T) { + t.Log("utility workflow triggered - Warning") + { + configStr := ` +format_version: 1.3.1 +default_step_lib_source: "https://github.com/bitrise-io/bitrise-steplib.git" + +trigger_map: +- push_branch: "/release" + workflow: _deps-update + +workflows: + _deps-update: +` + + config, err := configModelFromYAMLBytes([]byte(configStr)) + require.NoError(t, err) + + warnings, err := config.Validate() + require.NoError(t, err) + require.Equal(t, []string{"workflow (_deps-update) defined in trigger item (push_branch: /release -> workflow: _deps-update), but utility workflows can't be triggered directly"}, warnings) + } + + t.Log("pipeline not exists") + { + configStr := ` +format_version: 1.3.1 +default_step_lib_source: "https://github.com/bitrise-io/bitrise-steplib.git" + +trigger_map: +- push_branch: "/release" + pipeline: release + +pipelines: + primary: + stages: + - ci-stage: {} + +stages: + ci-stage: + workflows: + - ci: {} + +workflows: + ci: +` + + config, err := configModelFromYAMLBytes([]byte(configStr)) + require.NoError(t, err) + + _, err = config.Validate() + require.EqualError(t, err, "pipeline (release) defined in trigger item (push_branch: /release -> pipeline: release), but does not exist") + } + + t.Log("workflow not exists") + { + configStr := ` +format_version: 1.3.1 +default_step_lib_source: "https://github.com/bitrise-io/bitrise-steplib.git" + +trigger_map: +- push_branch: "/release" + workflow: release + +workflows: + ci: +` + + config, err := configModelFromYAMLBytes([]byte(configStr)) + require.NoError(t, err) + + _, err = config.Validate() + require.EqualError(t, err, "workflow (release) defined in trigger item (push_branch: /release -> workflow: release), but does not exist") + } +} + // ---------------------------- // --- Merge diff --git a/models/trigger_map.go b/models/trigger_map.go index c46786b2f..ce1f63822 100644 --- a/models/trigger_map.go +++ b/models/trigger_map.go @@ -21,9 +21,9 @@ func (triggerMap TriggerMapModel) Validate(workflows, pipelines []string) ([]str return warnings, nil } -func (triggerMap TriggerMapModel) FirstMatchingTarget(pushBranch, prSourceBranch, prTargetBranch, tag string) (string, string, error) { +func (triggerMap TriggerMapModel) FirstMatchingTarget(pushBranch, prSourceBranch, prTargetBranch string, isDraftPR bool, tag string) (string, string, error) { for _, item := range triggerMap { - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, isDraftPR, tag) if err != nil { return "", "", err } @@ -36,50 +36,17 @@ func (triggerMap TriggerMapModel) FirstMatchingTarget(pushBranch, prSourceBranch } func (triggerMap TriggerMapModel) checkDuplicatedTriggerMapItems() error { - triggerTypeItemMap := map[string][]TriggerMapItemModel{} + items := make(map[string]struct{}) for _, triggerItem := range triggerMap { - if triggerItem.Pattern == "" { - triggerType, err := triggerEventType(triggerItem.PushBranch, triggerItem.PullRequestSourceBranch, triggerItem.PullRequestTargetBranch, triggerItem.Tag) - if err != nil { - return fmt.Errorf("trigger map item (%v) validate failed, error: %s", triggerItem, err) - } + content := triggerItem.String(false) - triggerItems := triggerTypeItemMap[string(triggerType)] - - for _, item := range triggerItems { - switch triggerType { - case TriggerEventTypeCodePush: - if triggerItem.PushBranch == item.PushBranch { - return fmt.Errorf("duplicated trigger item found (%s)", triggerItem.String(false)) - } - case TriggerEventTypePullRequest: - if triggerItem.PullRequestSourceBranch == item.PullRequestSourceBranch && - triggerItem.PullRequestTargetBranch == item.PullRequestTargetBranch { - return fmt.Errorf("duplicated trigger item found (%s)", triggerItem.String(false)) - } - case TriggerEventTypeTag: - if triggerItem.Tag == item.Tag { - return fmt.Errorf("duplicated trigger item found (%s)", triggerItem.String(false)) - } - } - } - - triggerItems = append(triggerItems, triggerItem) - triggerTypeItemMap[string(triggerType)] = triggerItems - } else if triggerItem.Pattern != "" { - triggerItems := triggerTypeItemMap["deprecated"] - - for _, item := range triggerItems { - if triggerItem.Pattern == item.Pattern && - triggerItem.IsPullRequestAllowed == item.IsPullRequestAllowed { - return fmt.Errorf("duplicated trigger item found (%s)", triggerItem.String(false)) - } - } - - triggerItems = append(triggerItems, triggerItem) - triggerTypeItemMap["deprecated"] = triggerItems + _, ok := items[content] + if ok { + return fmt.Errorf("duplicated trigger item found (%s)", content) } + + items[content] = struct{}{} } return nil diff --git a/models/trigger_map_item.go b/models/trigger_map_item.go index 88af32eb0..eaacfca25 100644 --- a/models/trigger_map_item.go +++ b/models/trigger_map_item.go @@ -16,15 +16,22 @@ const ( TriggerEventTypeUnknown TriggerEventType = "unknown" ) +const defaultDraftPullRequestEnabled = true + type TriggerMapItemModel struct { - PushBranch string `json:"push_branch,omitempty" yaml:"push_branch,omitempty"` + // Trigger target + PipelineID string `json:"pipeline,omitempty" yaml:"pipeline,omitempty"` + WorkflowID string `json:"workflow,omitempty" yaml:"workflow,omitempty"` + // Commit push event criteria + PushBranch string `json:"push_branch,omitempty" yaml:"push_branch,omitempty"` + // Tag push event criteria + Tag string `json:"tag,omitempty" yaml:"tag,omitempty"` + // Pull Request event criteria PullRequestSourceBranch string `json:"pull_request_source_branch,omitempty" yaml:"pull_request_source_branch,omitempty"` PullRequestTargetBranch string `json:"pull_request_target_branch,omitempty" yaml:"pull_request_target_branch,omitempty"` - Tag string `json:"tag,omitempty" yaml:"tag,omitempty"` - PipelineID string `json:"pipeline,omitempty" yaml:"pipeline,omitempty"` - WorkflowID string `json:"workflow,omitempty" yaml:"workflow,omitempty"` + DraftPullRequestEnabled *bool `json:"draft_pull_request_enabled,omitempty" yaml:"draft_pull_request_enabled,omitempty"` - // deprecated + // Deprecated Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"` IsPullRequestAllowed bool `json:"is_pull_request_allowed,omitempty" yaml:"is_pull_request_allowed,omitempty"` } @@ -34,10 +41,10 @@ func (triggerItem TriggerMapItemModel) Validate(workflows, pipelines []string) ( // Validate target if triggerItem.PipelineID != "" && triggerItem.WorkflowID != "" { - return warnings, fmt.Errorf("invalid trigger item: (%s), error: pipeline & workflow both defined", triggerItem.Pattern) + return warnings, fmt.Errorf("both pipeline and workflow are defined as trigger target: %s", triggerItem.String(false)) } if triggerItem.PipelineID == "" && triggerItem.WorkflowID == "" { - return warnings, fmt.Errorf("invalid trigger item: (%s), error: empty pipeline & workflow", triggerItem.Pattern) + return warnings, fmt.Errorf("no pipeline nor workflow is defined as a trigger target: %s", triggerItem.String(false)) } if strings.HasPrefix(triggerItem.WorkflowID, "_") { @@ -83,7 +90,7 @@ func (triggerItem TriggerMapItemModel) Validate(workflows, pipelines []string) ( return warnings, nil } -func (triggerItem TriggerMapItemModel) MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag string) (bool, error) { +func (triggerItem TriggerMapItemModel) MatchWithParams(pushBranch, prSourceBranch, prTargetBranch string, isDraftPR bool, tag string) (bool, error) { paramsEventType, err := triggerEventType(pushBranch, prSourceBranch, prTargetBranch, tag) if err != nil { return false, err @@ -123,7 +130,12 @@ func (triggerItem TriggerMapItemModel) MatchWithParams(pushBranch, prSourceBranc targetMatch = glob.Glob(migratedTriggerItem.PullRequestTargetBranch, prTargetBranch) } - return (sourceMatch && targetMatch), nil + prStateMatch := true + if !migratedTriggerItem.IsDraftPullRequestEnabled() && isDraftPR { + prStateMatch = false + } + + return sourceMatch && targetMatch && prStateMatch, nil case TriggerEventTypeTag: match := glob.Glob(migratedTriggerItem.Tag, tag) return match, nil @@ -133,6 +145,14 @@ func (triggerItem TriggerMapItemModel) MatchWithParams(pushBranch, prSourceBranc return false, nil } +func (triggerItem TriggerMapItemModel) IsDraftPullRequestEnabled() bool { + draftPullRequestEnabled := defaultDraftPullRequestEnabled + if triggerItem.DraftPullRequestEnabled != nil { + draftPullRequestEnabled = *triggerItem.DraftPullRequestEnabled + } + return draftPullRequestEnabled +} + func (triggerItem TriggerMapItemModel) String(printTarget bool) string { str := "" @@ -155,6 +175,8 @@ func (triggerItem TriggerMapItemModel) String(printTarget bool) string { str += fmt.Sprintf("pull_request_target_branch: %s", triggerItem.PullRequestTargetBranch) } + + str += fmt.Sprintf(" && draft_pull_request_enabled: %v", triggerItem.IsDraftPullRequestEnabled()) } if triggerItem.Tag != "" { diff --git a/models/trigger_map_item_test.go b/models/trigger_map_item_test.go index ba21c133f..105ae7e57 100644 --- a/models/trigger_map_item_test.go +++ b/models/trigger_map_item_test.go @@ -3,257 +3,11 @@ package models import ( "testing" + "github.com/bitrise-io/go-utils/pointers" "github.com/stretchr/testify/require" ) -func TestTriggerMapItemValidate(t *testing.T) { - t.Log("utility workflow triggered - Warning") - { - configStr := ` -format_version: 1.3.1 -default_step_lib_source: "https://github.com/bitrise-io/bitrise-steplib.git" - -trigger_map: -- push_branch: "/release" - workflow: _deps-update - -workflows: - _deps-update: -` - - config, err := configModelFromYAMLBytes([]byte(configStr)) - require.NoError(t, err) - - warnings, err := config.Validate() - require.NoError(t, err) - require.Equal(t, []string{"workflow (_deps-update) defined in trigger item (push_branch: /release -> workflow: _deps-update), but utility workflows can't be triggered directly"}, warnings) - } - - t.Log("pipeline not exists") - { - configStr := ` -format_version: 1.3.1 -default_step_lib_source: "https://github.com/bitrise-io/bitrise-steplib.git" - -trigger_map: -- push_branch: "/release" - pipeline: release - -pipelines: - primary: - stages: - - ci-stage: {} - -stages: - ci-stage: - workflows: - - ci: {} - -workflows: - ci: -` - - config, err := configModelFromYAMLBytes([]byte(configStr)) - require.NoError(t, err) - - _, err = config.Validate() - require.EqualError(t, err, "pipeline (release) defined in trigger item (push_branch: /release -> pipeline: release), but does not exist") - } - - t.Log("workflow not exists") - { - configStr := ` -format_version: 1.3.1 -default_step_lib_source: "https://github.com/bitrise-io/bitrise-steplib.git" - -trigger_map: -- push_branch: "/release" - workflow: release - -workflows: - ci: -` - - config, err := configModelFromYAMLBytes([]byte(configStr)) - require.NoError(t, err) - - _, err = config.Validate() - require.EqualError(t, err, "workflow (release) defined in trigger item (push_branch: /release -> workflow: release), but does not exist") - } - - t.Log("it validates deprecated trigger item with triggered pipeline") - { - item := TriggerMapItemModel{ - Pattern: "*", - PipelineID: "primary", - } - _, err := item.Validate(nil, []string{"primary"}) - require.NoError(t, err) - } - - t.Log("it validates deprecated trigger item with triggered workflow") - { - item := TriggerMapItemModel{ - Pattern: "*", - WorkflowID: "primary", - } - _, err := item.Validate([]string{"primary"}, nil) - require.NoError(t, err) - } - - t.Log("it fails for invalid deprecated trigger item - pipeline & workflow both defined") - { - item := TriggerMapItemModel{ - Pattern: "*", - PipelineID: "pipeline-1", - WorkflowID: "workflow-1", - } - _, err := item.Validate([]string{"pipeline-1"}, []string{"workflow-1"}) - require.Error(t, err) - } - - t.Log("it fails for invalid deprecated trigger item - missing pipeline & workflow") - { - item := TriggerMapItemModel{ - Pattern: "*", - } - _, err := item.Validate([]string{"pipeline-1"}, []string{"workflow-1"}) - require.Error(t, err) - } - - t.Log("it fails for invalid deprecated trigger item - missing pattern") - { - item := TriggerMapItemModel{ - Pattern: "", - WorkflowID: "primary", - } - _, err := item.Validate([]string{"primary"}, nil) - require.Error(t, err) - } - - t.Log("it validates code-push trigger item with triggered pipeline") - { - item := TriggerMapItemModel{ - PushBranch: "*", - PipelineID: "primary", - } - _, err := item.Validate(nil, []string{"primary"}) - require.NoError(t, err) - } - - t.Log("it validates code-push trigger item with triggered workflow") - { - item := TriggerMapItemModel{ - PushBranch: "*", - WorkflowID: "primary", - } - _, err := item.Validate([]string{"primary"}, nil) - require.NoError(t, err) - } - - t.Log("it fails for invalid code-push trigger item - missing push-branch") - { - item := TriggerMapItemModel{ - PushBranch: "", - WorkflowID: "primary", - } - _, err := item.Validate([]string{"primary"}, nil) - require.Error(t, err) - } - - t.Log("it fails for invalid code-push trigger item - missing pipeline & workflow") - { - item := TriggerMapItemModel{ - PushBranch: "*", - } - _, err := item.Validate([]string{"primary"}, nil) - require.Error(t, err) - } - - t.Log("it validates pull-request trigger item with triggered pipeline") - { - item := TriggerMapItemModel{ - PullRequestSourceBranch: "feature/", - PipelineID: "primary", - } - _, err := item.Validate(nil, []string{"primary"}) - require.NoError(t, err) - } - - t.Log("it validates pull-request trigger item with triggered workflow") - { - item := TriggerMapItemModel{ - PullRequestSourceBranch: "feature/", - WorkflowID: "primary", - } - _, err := item.Validate([]string{"primary"}, nil) - require.NoError(t, err) - } - - t.Log("it validates pull-request trigger item with triggered pipeline") - { - item := TriggerMapItemModel{ - PullRequestTargetBranch: "master", - PipelineID: "primary", - } - _, err := item.Validate(nil, []string{"primary"}) - require.NoError(t, err) - } - - t.Log("it validates pull-request trigger item with triggered workflow") - { - item := TriggerMapItemModel{ - PullRequestTargetBranch: "master", - WorkflowID: "primary", - } - _, err := item.Validate([]string{"primary"}, nil) - require.NoError(t, err) - } - - t.Log("it fails for invalid pull-request trigger item - missing pipeline & workflow") - { - item := TriggerMapItemModel{ - PullRequestTargetBranch: "*", - } - _, err := item.Validate([]string{"primary"}, nil) - require.Error(t, err) - } - - t.Log("it fails for invalid pull-request trigger item - missing pipeline & workflow") - { - item := TriggerMapItemModel{ - PullRequestSourceBranch: "", - PullRequestTargetBranch: "", - } - _, err := item.Validate([]string{"primary"}, nil) - require.Error(t, err) - } - - t.Log("it fails for mixed trigger item") - { - item := TriggerMapItemModel{ - PushBranch: "master", - PullRequestSourceBranch: "feature/*", - PullRequestTargetBranch: "", - WorkflowID: "primary", - } - _, err := item.Validate([]string{"primary"}, nil) - require.Error(t, err) - } - - t.Log("it fails for mixed trigger item") - { - item := TriggerMapItemModel{ - PushBranch: "master", - Pattern: "*", - WorkflowID: "primary", - } - _, err := item.Validate([]string{"primary"}, nil) - require.Error(t, err) - } -} - -func TestMatchWithParamsCodePushItem(t *testing.T) { +func TestTriggerMapItemModel_MatchWithParams_CodePushParams(t *testing.T) { t.Log("The following patterns are all matches") { for aPattern, aPushBranch := range map[string]string{ @@ -273,7 +27,7 @@ func TestMatchWithParamsCodePushItem(t *testing.T) { PushBranch: aPattern, WorkflowID: "primary", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, true, match, "(pattern: %s) (branch: %s)", aPattern, aPushBranch) } @@ -290,7 +44,7 @@ func TestMatchWithParamsCodePushItem(t *testing.T) { PushBranch: "deploy", WorkflowID: "deploy", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, false, match) } @@ -306,7 +60,7 @@ func TestMatchWithParamsCodePushItem(t *testing.T) { PullRequestSourceBranch: "develop", WorkflowID: "test", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, false, match) } @@ -322,7 +76,7 @@ func TestMatchWithParamsCodePushItem(t *testing.T) { PullRequestTargetBranch: "master", WorkflowID: "primary", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, false, match) } @@ -339,164 +93,170 @@ func TestMatchWithParamsCodePushItem(t *testing.T) { PullRequestTargetBranch: "master", WorkflowID: "primary", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, false, match) } } -func TestMatchWithParamsPrTypeItem(t *testing.T) { - t.Log("pr against pr type item - MATCH") - { - pushBranch := "" - prSourceBranch := "develop" - prTargetBranch := "master" - tag := "" - - item := TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - PullRequestTargetBranch: "master", - WorkflowID: "primary", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, true, match) - } - - t.Log("pr against pr type item - MATCH") - { - pushBranch := "" - prSourceBranch := "feature/login" - prTargetBranch := "develop" - tag := "" - - item := TriggerMapItemModel{ - PullRequestSourceBranch: "feature/*", - PullRequestTargetBranch: "develop", - WorkflowID: "test", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, true, match) - } - - t.Log("pr against pr type item - MATCH") - { - pushBranch := "" - prSourceBranch := "develop" - prTargetBranch := "master" - tag := "" - - item := TriggerMapItemModel{ - PullRequestSourceBranch: "*", - PullRequestTargetBranch: "master", - WorkflowID: "primary", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, true, match) - } - - t.Log("pr against pr type item - MATCH") - { - pushBranch := "" - prSourceBranch := "develop" - prTargetBranch := "master" - tag := "" - - item := TriggerMapItemModel{ - PullRequestTargetBranch: "master", - WorkflowID: "primary", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, true, match) - } - - t.Log("pr against pr type item - MATCH") - { - pushBranch := "" - prSourceBranch := "develop" - prTargetBranch := "master" - tag := "" - - item := TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - WorkflowID: "primary", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, true, match) - } - - t.Log("pr against pr type item - MATCH") - { - pushBranch := "" - prSourceBranch := "" - prTargetBranch := "deploy_1_0_0" - tag := "" - - item := TriggerMapItemModel{ - PullRequestTargetBranch: "deploy_*", - WorkflowID: "primary", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, true, match) - } - - t.Log("pr against pr type item - NOT MATCH") - { - pushBranch := "" - prSourceBranch := "develop" - prTargetBranch := "master" - tag := "" - - item := TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - PullRequestTargetBranch: "deploy", - WorkflowID: "primary", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, false, match) - } - - t.Log("pr against pr type item - NOT MATCH") - { - pushBranch := "" - prSourceBranch := "develop" - prTargetBranch := "master" - tag := "" - - item := TriggerMapItemModel{ - PullRequestSourceBranch: "feature/*", - PullRequestTargetBranch: "master", - WorkflowID: "primary", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, false, match) - } - - t.Log("pr against push type item - NOT MATCH") - { - pushBranch := "" - prSourceBranch := "develop" - prTargetBranch := "master" - tag := "" - - item := TriggerMapItemModel{ - PushBranch: "master", - WorkflowID: "primary", - } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) - require.NoError(t, err) - require.Equal(t, false, match) +func TestTriggerMapItemModel_MatchWithParams_PRParams(t *testing.T) { + tests := []struct { + name string + triggerMapItem TriggerMapItemModel + pushBranch string + prSourceBranch string + prTargetBranch string + isDraftPR bool + tag string + want bool + wantErr string + }{ + // Match tests + { + name: "pr against pr type item - MATCH (source branch)", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + want: true, + }, + { + name: "pr against pr type item - MATCH (target branch)", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "master", + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + want: true, + }, + { + name: "pr against pr type item - MATCH (target and source branch)", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + want: true, + }, + { + name: "pr against pr type item (simple glob source branch) - MATCH", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "*", + PullRequestTargetBranch: "master", + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + want: true, + }, + { + name: "pr against pr type item (glob target branch) - MATCH", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "deploy_*", + WorkflowID: "primary", + }, + prTargetBranch: "deploy_1_0_0", + want: true, + }, + { + name: "pr against pr type item (complex glob source branch) - MATCH", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "feature/*", + PullRequestTargetBranch: "develop", + WorkflowID: "test", + }, + prSourceBranch: "feature/login", + prTargetBranch: "develop", + want: true, + }, + { + name: "draft pr against pr type item (draft pr explicitly enabled) - MATCH", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "master", + DraftPullRequestEnabled: pointers.NewBoolPtr(true), + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + isDraftPR: true, + want: true, + }, + { + name: "draft pr against pr type item (draft pr enabled by default) - MATCH", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "master", + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + isDraftPR: true, + want: true, + }, + // No match tests + { + name: "pr against pr type item - NOT MATCH (target branch mismatch)", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "deploy", + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + want: false, + }, + { + name: "pr against pr type item - NOT MATCH (source branch mismatch)", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "feature/*", + PullRequestTargetBranch: "master", + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + want: false, + }, + { + name: "pr against push type item - NOT MATCH", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "master", + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + want: false, + }, + { + name: "draft pr against pr type item (draft pr explicitly disabled) - MATCH", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "master", + DraftPullRequestEnabled: pointers.NewBoolPtr(false), + WorkflowID: "primary", + }, + prSourceBranch: "develop", + prTargetBranch: "master", + isDraftPR: true, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.triggerMapItem.MatchWithParams(tt.pushBranch, tt.prSourceBranch, tt.prTargetBranch, tt.isDraftPR, tt.tag) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + } + require.Equal(t, tt.want, got) + }) } } -func TestMatchWithParamsTagTypeItem(t *testing.T) { +func TestTriggerMapItemModel_MatchWithParams_TagParams(t *testing.T) { t.Log("tag against tag type item - MATCH") { pushBranch := "" @@ -508,7 +268,7 @@ func TestMatchWithParamsTagTypeItem(t *testing.T) { Tag: "0.9.*", WorkflowID: "deploy", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, true, match) } @@ -524,7 +284,7 @@ func TestMatchWithParamsTagTypeItem(t *testing.T) { Tag: "0.9.0", WorkflowID: "deploy", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, true, match) } @@ -540,7 +300,7 @@ func TestMatchWithParamsTagTypeItem(t *testing.T) { Tag: "0.9.*", WorkflowID: "deploy", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, true, match) } @@ -556,7 +316,7 @@ func TestMatchWithParamsTagTypeItem(t *testing.T) { Tag: "1.*", WorkflowID: "deploy", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, false, match) } @@ -572,105 +332,295 @@ func TestMatchWithParamsTagTypeItem(t *testing.T) { PushBranch: "master", WorkflowID: "primary", } - match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag) + match, err := item.MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, false, tag) require.NoError(t, err) require.Equal(t, false, match) } } -func TestTriggerMapItemModelString(t *testing.T) { - t.Log("triggering pipeline") - { - item := TriggerMapItemModel{ - PushBranch: "master", - PipelineID: "pipeline-1", - } - require.Equal(t, "push_branch: master -> pipeline: pipeline-1", item.String(true)) - require.Equal(t, "push_branch: master", item.String(false)) - } - - t.Log("push event") - { - item := TriggerMapItemModel{ - PushBranch: "master", - WorkflowID: "ci", - } - require.Equal(t, "push_branch: master -> workflow: ci", item.String(true)) - require.Equal(t, "push_branch: master", item.String(false)) - } - - t.Log("pull request event") - { - prSourceItem := TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - WorkflowID: "ci", - } - require.Equal(t, "pull_request_source_branch: develop -> workflow: ci", prSourceItem.String(true)) - require.Equal(t, "pull_request_source_branch: develop", prSourceItem.String(false)) - - prTargetItem := TriggerMapItemModel{ - PullRequestTargetBranch: "master", - WorkflowID: "ci", - } - require.Equal(t, "pull_request_target_branch: master -> workflow: ci", prTargetItem.String(true)) - require.Equal(t, "pull_request_target_branch: master", prTargetItem.String(false)) - - prItem := TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - PullRequestTargetBranch: "master", - WorkflowID: "ci", - } - require.Equal(t, "pull_request_source_branch: develop && pull_request_target_branch: master -> workflow: ci", prItem.String(true)) - require.Equal(t, "pull_request_source_branch: develop && pull_request_target_branch: master", prItem.String(false)) - } - - t.Log("tag event") - { - item := TriggerMapItemModel{ - Tag: "0.9.0", - WorkflowID: "release", - } - require.Equal(t, "tag: 0.9.0 -> workflow: release", item.String(true)) - require.Equal(t, "tag: 0.9.0", item.String(false)) - } - - t.Log("deprecated type") - { - prNotAllowedItem := TriggerMapItemModel{ - Pattern: "master", - IsPullRequestAllowed: false, - WorkflowID: "ci", - } - require.Equal(t, "pattern: master && is_pull_request_allowed: false -> workflow: ci", prNotAllowedItem.String(true)) - require.Equal(t, "pattern: master && is_pull_request_allowed: false", prNotAllowedItem.String(false)) - - prAllowedItem := TriggerMapItemModel{ - Pattern: "master", - IsPullRequestAllowed: true, - WorkflowID: "ci", - } - require.Equal(t, "pattern: master && is_pull_request_allowed: true -> workflow: ci", prAllowedItem.String(true)) - require.Equal(t, "pattern: master && is_pull_request_allowed: true", prAllowedItem.String(false)) +func TestTriggerMapItemModel_String(t *testing.T) { + tests := []struct { + name string + triggerMapItem TriggerMapItemModel + want string + wantWithPrintTarget string + }{ + { + name: "triggering pipeline", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "master", + PipelineID: "pipeline-1", + }, + want: "push_branch: master", + wantWithPrintTarget: "push_branch: master -> pipeline: pipeline-1", + }, + { + name: "push event", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "master", + WorkflowID: "ci", + }, + want: "push_branch: master", + wantWithPrintTarget: "push_branch: master -> workflow: ci", + }, + { + name: "pull request event - pr source branch", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + WorkflowID: "ci", + }, + want: "pull_request_source_branch: develop && draft_pull_request_enabled: true", + wantWithPrintTarget: "pull_request_source_branch: develop && draft_pull_request_enabled: true -> workflow: ci", + }, + { + name: "pull request event - pr target branch", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "master", + WorkflowID: "ci", + }, + want: "pull_request_target_branch: master && draft_pull_request_enabled: true", + wantWithPrintTarget: "pull_request_target_branch: master && draft_pull_request_enabled: true -> workflow: ci", + }, + { + name: "pull request event - pr target and source branch", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + WorkflowID: "ci", + }, + want: "pull_request_source_branch: develop && pull_request_target_branch: master && draft_pull_request_enabled: true", + wantWithPrintTarget: "pull_request_source_branch: develop && pull_request_target_branch: master && draft_pull_request_enabled: true -> workflow: ci", + }, + { + name: "pull request event - pr target and source branch and disable draft prs", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + DraftPullRequestEnabled: pointers.NewBoolPtr(false), + WorkflowID: "ci", + }, + want: "pull_request_source_branch: develop && pull_request_target_branch: master && draft_pull_request_enabled: false", + wantWithPrintTarget: "pull_request_source_branch: develop && pull_request_target_branch: master && draft_pull_request_enabled: false -> workflow: ci", + }, + { + name: "tag event", + triggerMapItem: TriggerMapItemModel{ + Tag: "0.9.0", + WorkflowID: "release", + }, + want: "tag: 0.9.0", + wantWithPrintTarget: "tag: 0.9.0 -> workflow: release", + }, + { + name: "deprecated type - pr disabled", + triggerMapItem: TriggerMapItemModel{ + Pattern: "master", + IsPullRequestAllowed: false, + WorkflowID: "ci", + }, + want: "pattern: master && is_pull_request_allowed: false", + wantWithPrintTarget: "pattern: master && is_pull_request_allowed: false -> workflow: ci", + }, + { + name: "deprecated type - pr enabled", + triggerMapItem: TriggerMapItemModel{ + Pattern: "master", + IsPullRequestAllowed: true, + WorkflowID: "ci", + }, + want: "pattern: master && is_pull_request_allowed: true", + wantWithPrintTarget: "pattern: master && is_pull_request_allowed: true -> workflow: ci", + }, + { + name: "mixed", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "master", + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + Tag: "0.9.0", + Pattern: "*", + IsPullRequestAllowed: true, + WorkflowID: "ci", + }, + want: "push_branch: master pull_request_source_branch: develop && pull_request_target_branch: master && draft_pull_request_enabled: true tag: 0.9.0 pattern: * && is_pull_request_allowed: true", + wantWithPrintTarget: "push_branch: master pull_request_source_branch: develop && pull_request_target_branch: master && draft_pull_request_enabled: true tag: 0.9.0 pattern: * && is_pull_request_allowed: true -> workflow: ci", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.want, tt.triggerMapItem.String(false)) + require.Equal(t, tt.wantWithPrintTarget, tt.triggerMapItem.String(true)) + }) } +} - t.Log("mixed") - { - item := TriggerMapItemModel{ - PushBranch: "master", - PullRequestSourceBranch: "develop", - PullRequestTargetBranch: "master", - Tag: "0.9.0", - Pattern: "*", - IsPullRequestAllowed: true, - WorkflowID: "ci", - } - require.Equal(t, "push_branch: master pull_request_source_branch: develop && pull_request_target_branch: master tag: 0.9.0 pattern: * && is_pull_request_allowed: true -> workflow: ci", item.String(true)) - require.Equal(t, "push_branch: master pull_request_source_branch: develop && pull_request_target_branch: master tag: 0.9.0 pattern: * && is_pull_request_allowed: true", item.String(false)) +func TestTriggerMapItemModel_Validate(t *testing.T) { + tests := []struct { + name string + triggerMapItem TriggerMapItemModel + workflows []string + pipelines []string + wantWarns []string + wantErr string + }{ + { + name: "it validates deprecated trigger item with triggered pipeline", + triggerMapItem: TriggerMapItemModel{ + Pattern: "*", + PipelineID: "primary", + }, + pipelines: []string{"primary"}, + }, + { + name: "it validates deprecated trigger item with triggered workflow", + triggerMapItem: TriggerMapItemModel{ + Pattern: "*", + WorkflowID: "primary", + }, + workflows: []string{"primary"}, + }, + { + name: "it fails for invalid deprecated trigger item - pipeline & workflow both defined", + triggerMapItem: TriggerMapItemModel{ + Pattern: "*", + PipelineID: "pipeline-1", + WorkflowID: "workflow-1", + }, + workflows: []string{"pipeline-1", "workflow-1"}, + wantErr: "both pipeline and workflow are defined as trigger target: pattern: * && is_pull_request_allowed: false", + }, + { + name: "it fails for invalid deprecated trigger item - missing pipeline & workflow", + triggerMapItem: TriggerMapItemModel{ + Pattern: "*", + }, + wantErr: "no pipeline nor workflow is defined as a trigger target: pattern: * && is_pull_request_allowed: false", + }, + { + name: "it fails for invalid deprecated trigger item - missing pattern", + triggerMapItem: TriggerMapItemModel{ + Pattern: "", + WorkflowID: "primary", + }, + workflows: []string{"primary"}, + wantErr: "trigger map item ( -> workflow: primary) validate failed, error: failed to determin trigger event from params: push-branch: , pr-source-branch: , pr-target-branch: , tag: ", + }, + { + name: "it validates code-push trigger item with triggered pipeline", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "*", + PipelineID: "primary", + }, + pipelines: []string{"primary"}, + }, + { + name: "it validates code-push trigger item with triggered workflow", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "*", + WorkflowID: "primary", + }, + workflows: []string{"primary"}, + }, + { + name: "it fails for invalid code-push trigger item - missing push-branch", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "", + WorkflowID: "primary", + }, + workflows: []string{"primary"}, + wantErr: "trigger map item ( -> workflow: primary) validate failed, error: failed to determin trigger event from params: push-branch: , pr-source-branch: , pr-target-branch: , tag: ", + }, + { + name: "it fails for invalid code-push trigger item - missing pipeline & workflow", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "*", + }, + wantErr: "no pipeline nor workflow is defined as a trigger target: push_branch: *", + }, + { + name: "it validates pull-request trigger item (with source branch) with triggered pipeline", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "feature/", + PipelineID: "primary", + }, + pipelines: []string{"primary"}, + }, + { + name: "it validates pull-request trigger item (with source branch) with triggered workflow", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "feature/", + WorkflowID: "primary", + }, + workflows: []string{"primary"}, + }, + { + name: "it validates pull-request trigger item (with target branch) with triggered pipeline", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "master", + PipelineID: "primary", + }, + pipelines: []string{"primary"}, + }, + { + name: "it validates pull-request trigger item (with target branch) with triggered workflow", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "master", + WorkflowID: "primary", + }, + workflows: []string{"primary"}, + }, + { + name: "it fails for invalid pull-request trigger item (target branch set) - missing pipeline & workflow", + triggerMapItem: TriggerMapItemModel{ + PullRequestTargetBranch: "*", + }, + wantErr: "no pipeline nor workflow is defined as a trigger target: pull_request_target_branch: * && draft_pull_request_enabled: true", + }, + { + name: "it fails for invalid pull-request trigger item (target and source branch set) - missing pipeline & workflow", + triggerMapItem: TriggerMapItemModel{ + PullRequestSourceBranch: "feature*", + PullRequestTargetBranch: "master", + }, + wantErr: "no pipeline nor workflow is defined as a trigger target: pull_request_source_branch: feature* && pull_request_target_branch: master && draft_pull_request_enabled: true", + }, + { + name: "it fails for mixed (mixed types) trigger item", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "master", + PullRequestSourceBranch: "feature/*", + PullRequestTargetBranch: "", + WorkflowID: "primary", + }, + workflows: []string{"primary"}, + wantErr: "trigger map item (push_branch: master pull_request_source_branch: feature/* && draft_pull_request_enabled: true -> workflow: primary) validate failed, error: push_branch (master) selects code-push trigger event, but pull_request_source_branch (feature/*) also provided", + }, + { + name: "it fails for mixed (mixed new and legacy properties) trigger item", + triggerMapItem: TriggerMapItemModel{ + PushBranch: "master", + Pattern: "*", + WorkflowID: "primary", + }, + workflows: []string{"primary"}, + wantErr: "deprecated trigger item (pattern defined), mixed with trigger params (push_branch: master, pull_request_source_branch: , pull_request_target_branch: , tag: )", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + warns, err := tt.triggerMapItem.Validate(tt.workflows, tt.pipelines) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + } + require.Equal(t, tt.wantWarns, warns) + }) } } func TestTriggerEventType(t *testing.T) { - t.Log("it determins trigger event type") + t.Log("it determines trigger event type") { pushBranch := "master" prSourceBranch := "" @@ -682,7 +632,7 @@ func TestTriggerEventType(t *testing.T) { require.Equal(t, TriggerEventTypeCodePush, event) } - t.Log("it determins trigger event type") + t.Log("it determines trigger event type") { pushBranch := "" prSourceBranch := "develop" @@ -694,7 +644,7 @@ func TestTriggerEventType(t *testing.T) { require.Equal(t, TriggerEventTypePullRequest, event) } - t.Log("it determins trigger event type") + t.Log("it determines trigger event type") { pushBranch := "" prSourceBranch := "" @@ -706,7 +656,7 @@ func TestTriggerEventType(t *testing.T) { require.Equal(t, TriggerEventTypePullRequest, event) } - t.Log("it determins trigger event type") + t.Log("it determines trigger event type") { pushBranch := "" prSourceBranch := "" diff --git a/models/trigger_map_test.go b/models/trigger_map_test.go index 95218204a..bfb1cda03 100644 --- a/models/trigger_map_test.go +++ b/models/trigger_map_test.go @@ -3,104 +3,172 @@ package models import ( "testing" + "github.com/bitrise-io/go-utils/pointers" "github.com/stretchr/testify/require" ) -func TestCheckDuplicatedTriggerMapItems(t *testing.T) { - t.Log("duplicated push - error") - { - err := TriggerMapModel{ - TriggerMapItemModel{ - PushBranch: "master", - WorkflowID: "ci", +func TestTriggerMapModel_Validate(t *testing.T) { + tests := []struct { + name string + triggerMap TriggerMapModel + workflows []string + pipelines []string + wantErr string + wantWarnings []string + }{ + { + name: "Simple trigger items", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + PushBranch: "master", + WorkflowID: "ci", + }, + TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + DraftPullRequestEnabled: pointers.NewBoolPtr(false), + WorkflowID: "ci", + }, + TriggerMapItemModel{ + Tag: "0.9.0", + WorkflowID: "release", + }, }, - TriggerMapItemModel{ - PushBranch: "master", - WorkflowID: "release", + workflows: []string{"ci", "release"}, + }, + { + name: "Push trigger items", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + PushBranch: "master", + WorkflowID: "ci", + }, + TriggerMapItemModel{ + PushBranch: "release", + WorkflowID: "release", + }, }, - }.checkDuplicatedTriggerMapItems() - - require.EqualError(t, err, "duplicated trigger item found (push_branch: master)") - } - - t.Log("duplicated pull request - error") - { - err := TriggerMapModel{ - TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - WorkflowID: "ci", + workflows: []string{"ci", "release"}, + }, + { + name: "Push trigger items - duplication", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + PushBranch: "master", + WorkflowID: "ci", + }, + TriggerMapItemModel{ + PushBranch: "master", + WorkflowID: "release", + }, }, - TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - WorkflowID: "release", + workflows: []string{"ci", "release"}, + wantErr: "duplicated trigger item found (push_branch: master)", + }, + { + name: "Pull Request trigger items", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + PullRequestSourceBranch: "feature*", + WorkflowID: "ci", + }, + TriggerMapItemModel{ + PullRequestSourceBranch: "master", + WorkflowID: "release", + }, }, - }.checkDuplicatedTriggerMapItems() - - require.EqualError(t, err, "duplicated trigger item found (pull_request_source_branch: develop)") - - err = TriggerMapModel{ - TriggerMapItemModel{ - PullRequestTargetBranch: "master", - WorkflowID: "ci", + workflows: []string{"ci", "release"}, + }, + { + name: "Pull Request trigger items - duplicated (source branch)", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + WorkflowID: "ci", + }, + TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + WorkflowID: "release", + }, }, - TriggerMapItemModel{ - PullRequestTargetBranch: "master", - WorkflowID: "release", + workflows: []string{"ci", "release"}, + wantErr: "duplicated trigger item found (pull_request_source_branch: develop && draft_pull_request_enabled: true)", + }, + { + name: "Pull Request trigger items - duplicated (target branch)", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + PullRequestTargetBranch: "master", + WorkflowID: "ci", + }, + TriggerMapItemModel{ + PullRequestTargetBranch: "master", + WorkflowID: "release", + }, }, - }.checkDuplicatedTriggerMapItems() - - require.EqualError(t, err, "duplicated trigger item found (pull_request_target_branch: master)") - - err = TriggerMapModel{ - TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - PullRequestTargetBranch: "master", - WorkflowID: "ci", + workflows: []string{"ci", "release"}, + wantErr: "duplicated trigger item found (pull_request_target_branch: master && draft_pull_request_enabled: true)", + }, + { + name: "Pull Request trigger items - duplicated (source & target branch)", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + WorkflowID: "ci", + }, + TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + WorkflowID: "release", + }, }, - TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - PullRequestTargetBranch: "master", - WorkflowID: "release", + workflows: []string{"ci", "release"}, + wantErr: "duplicated trigger item found (pull_request_source_branch: develop && pull_request_target_branch: master && draft_pull_request_enabled: true)", + }, + { + name: "Pull Request trigger items - different draft pr enabled", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + DraftPullRequestEnabled: pointers.NewBoolPtr(false), + WorkflowID: "release", + }, + TriggerMapItemModel{ + PullRequestSourceBranch: "develop", + PullRequestTargetBranch: "master", + DraftPullRequestEnabled: pointers.NewBoolPtr(true), + WorkflowID: "ci", + }, }, - }.checkDuplicatedTriggerMapItems() - - require.EqualError(t, err, "duplicated trigger item found (pull_request_source_branch: develop && pull_request_target_branch: master)") - } - - t.Log("duplicated tag - error") - { - err := TriggerMapModel{ - TriggerMapItemModel{ - Tag: "0.9.0", - WorkflowID: "ci", - }, - TriggerMapItemModel{ - Tag: "0.9.0", - WorkflowID: "release", + workflows: []string{"ci", "release"}, + }, + { + name: "Tag trigger items - duplicated", + triggerMap: TriggerMapModel{ + TriggerMapItemModel{ + Tag: "0.9.0", + WorkflowID: "ci", + }, + TriggerMapItemModel{ + Tag: "0.9.0", + WorkflowID: "release", + }, }, - }.checkDuplicatedTriggerMapItems() - - require.EqualError(t, err, "duplicated trigger item found (tag: 0.9.0)") + workflows: []string{"ci", "release"}, + wantErr: "duplicated trigger item found (tag: 0.9.0)", + }, } - - t.Log("complex trigger map - no error") - { - err := TriggerMapModel{ - TriggerMapItemModel{ - PushBranch: "master", - WorkflowID: "ci", - }, - TriggerMapItemModel{ - PullRequestSourceBranch: "develop", - PullRequestTargetBranch: "master", - WorkflowID: "ci", - }, - TriggerMapItemModel{ - Tag: "0.9.0", - WorkflowID: "release", - }, - }.checkDuplicatedTriggerMapItems() - - require.NoError(t, err) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + warnings, err := tt.triggerMap.Validate(tt.workflows, tt.pipelines) + if tt.wantErr == "" { + require.NoError(t, err) + } else { + require.EqualError(t, err, tt.wantErr) + } + require.Equal(t, tt.wantWarnings, warnings) + }) } }