diff --git a/codefresh/cfclient/pipeline.go b/codefresh/cfclient/pipeline.go index 442c8d56..d25de84d 100644 --- a/codefresh/cfclient/pipeline.go +++ b/codefresh/cfclient/pipeline.go @@ -103,25 +103,26 @@ func (t *CronTrigger) SetVariables(variables map[string]interface{}) { } type Spec struct { - Variables []Variable `json:"variables,omitempty"` - SpecTemplate *SpecTemplate `json:"specTemplate,omitempty"` - Triggers []Trigger `json:"triggers,omitempty"` - CronTriggers []CronTrigger `json:"cronTriggers,omitempty"` - Priority int `json:"priority,omitempty"` - Concurrency int `json:"concurrency,omitempty"` - BranchConcurrency int `json:"branchConcurrency,omitempty"` - TriggerConcurrency int `json:"triggerConcurrency,omitempty"` - Contexts []interface{} `json:"contexts,omitempty"` - Steps *Steps `json:"steps,omitempty"` - Stages *Stages `json:"stages,omitempty"` - Mode string `json:"mode,omitempty"` - FailFast *bool `json:"fail_fast,omitempty"` - RuntimeEnvironment RuntimeEnvironment `json:"runtimeEnvironment,omitempty"` - TerminationPolicy []map[string]interface{} `json:"terminationPolicy,omitempty"` - PackId string `json:"packId,omitempty"` - RequiredAvailableStorage string `json:"requiredAvailableStorage,omitempty"` - Hooks *Hooks `json:"hooks,omitempty"` - Options map[string]bool `json:"options,omitempty"` + Variables []Variable `json:"variables,omitempty"` + SpecTemplate *SpecTemplate `json:"specTemplate,omitempty"` + Triggers []Trigger `json:"triggers,omitempty"` + CronTriggers []CronTrigger `json:"cronTriggers,omitempty"` + Priority int `json:"priority,omitempty"` + Concurrency int `json:"concurrency,omitempty"` + BranchConcurrency int `json:"branchConcurrency,omitempty"` + TriggerConcurrency int `json:"triggerConcurrency,omitempty"` + Contexts []interface{} `json:"contexts,omitempty"` + Steps *Steps `json:"steps,omitempty"` + Stages *Stages `json:"stages,omitempty"` + Mode string `json:"mode,omitempty"` + FailFast *bool `json:"fail_fast,omitempty"` + RuntimeEnvironment RuntimeEnvironment `json:"runtimeEnvironment,omitempty"` + TerminationPolicy []map[string]interface{} `json:"terminationPolicy,omitempty"` + PackId string `json:"packId,omitempty"` + RequiredAvailableStorage string `json:"requiredAvailableStorage,omitempty"` + Hooks *Hooks `json:"hooks,omitempty"` + Options map[string]bool `json:"options,omitempty"` + PermitRestartFromFailedSteps bool `json:"permitRestartFromFailedSteps,omitempty"` } type Steps struct { diff --git a/codefresh/resource_pipeline.go b/codefresh/resource_pipeline.go index 4430262d..b3fd98c2 100644 --- a/codefresh/resource_pipeline.go +++ b/codefresh/resource_pipeline.go @@ -101,6 +101,12 @@ Or: original_yaml_string = file("/path/to/my/codefresh.yml") Optional: true, Default: 0, }, + "permit_restart_from_failed_steps": { + Description: "Defines whether it is permitted to restart builds in this pipeline from failed step. Defaults to true", + Type: schema.TypeBool, + Optional: true, + Default: true, + }, "spec_template": { Description: "The pipeline's spec template.", Type: schema.TypeList, @@ -774,6 +780,7 @@ func flattenSpec(spec cfclient.Spec) []interface{} { m["concurrency"] = spec.Concurrency m["branch_concurrency"] = spec.BranchConcurrency m["trigger_concurrency"] = spec.TriggerConcurrency + m["permit_restart_from_failed_steps"] = spec.PermitRestartFromFailedSteps m["priority"] = spec.Priority @@ -923,12 +930,13 @@ func mapResourceToPipeline(d *schema.ResourceData) (*cfclient.Pipeline, error) { OriginalYamlString: originalYamlString, }, Spec: cfclient.Spec{ - PackId: d.Get("spec.0.pack_id").(string), - RequiredAvailableStorage: d.Get("spec.0.required_available_storage").(string), - Priority: d.Get("spec.0.priority").(int), - Concurrency: d.Get("spec.0.concurrency").(int), - BranchConcurrency: d.Get("spec.0.branch_concurrency").(int), - TriggerConcurrency: d.Get("spec.0.trigger_concurrency").(int), + PackId: d.Get("spec.0.pack_id").(string), + RequiredAvailableStorage: d.Get("spec.0.required_available_storage").(string), + Priority: d.Get("spec.0.priority").(int), + Concurrency: d.Get("spec.0.concurrency").(int), + BranchConcurrency: d.Get("spec.0.branch_concurrency").(int), + TriggerConcurrency: d.Get("spec.0.trigger_concurrency").(int), + PermitRestartFromFailedSteps: d.Get("spec.0.permit_restart_from_failed_steps").(bool), }, } diff --git a/codefresh/resource_pipeline_test.go b/codefresh/resource_pipeline_test.go index 07dff4ad..d3530aa8 100644 --- a/codefresh/resource_pipeline_test.go +++ b/codefresh/resource_pipeline_test.go @@ -79,6 +79,39 @@ func TestAccCodefreshPipeline_Concurrency(t *testing.T) { }) } +func TestAccCodefreshPipeline_PremitRestartFromFailedSteps(t *testing.T) { + name := pipelineNamePrefix + acctest.RandString(10) + resourceName := "codefresh_pipeline.test" + var pipeline cfclient.Pipeline + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshPipelineBasicConfigPermitRestartFromFailedSteps(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", true), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName, &pipeline), + resource.TestCheckResourceAttr(resourceName, "spec.0.permit_restart_from_failed_steps", "true"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccCodefreshPipelineBasicConfigPermitRestartFromFailedSteps(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", false), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName, &pipeline), + resource.TestCheckResourceAttr(resourceName, "spec.0.permit_restart_from_failed_steps", "false"), + ), + }, + }, + }) +} + func TestAccCodefreshPipeline_Tags(t *testing.T) { name := pipelineNamePrefix + acctest.RandString(10) resourceName := "codefresh_pipeline.test" @@ -955,6 +988,33 @@ resource "codefresh_pipeline" "test" { `, rName, repo, path, revision, context, concurrency, concurrencyBranch, concurrencyTrigger) } +func testAccCodefreshPipelineBasicConfigPermitRestartFromFailedSteps(rName string, repo string, path string, revision string, context string, permitRestartFromFailedSteps bool) string { + return fmt.Sprintf(` +resource "codefresh_pipeline" "test" { + + lifecycle { + ignore_changes = [ + revision + ] + } + + name = "%s" + + spec { + spec_template { + repo = %q + path = %q + revision = %q + context = %q + } + + permit_restart_from_failed_steps = %t + + } +} +`, rName, repo, path, revision, context, permitRestartFromFailedSteps) +} + func testAccCodefreshPipelineBasicConfigTriggers( rName, repo, diff --git a/docs/resources/pipeline.md b/docs/resources/pipeline.md index 9313d8a9..8d4014e6 100644 --- a/docs/resources/pipeline.md +++ b/docs/resources/pipeline.md @@ -130,6 +130,7 @@ Optional: - `cron_trigger` (Block List) The pipeline's cron triggers. Conflicts with the deprecated [codefresh_pipeline_cron_trigger](https://registry.terraform.io/providers/codefresh-io/codefresh/latest/docs/resources/pipeline_cron_trigger) resource. (see [below for nested schema](#nestedblock--spec--cron_trigger)) - `options` (Block List, Max: 1) The options for the pipeline. (see [below for nested schema](#nestedblock--spec--options)) - `pack_id` (String) SAAS pack (`5cd1746617313f468d669013` for Small; `5cd1746717313f468d669014` for Medium; `5cd1746817313f468d669015` for Large; `5cd1746817313f468d669017` for XL; `5cd1746817313f468d669018` for XXL); `5cd1746817313f468d669020` for 4XL). +- `permit_restart_from_failed_steps` (Boolean) Defines whether it is permitted to restart builds in this pipeline from failed step. Defaults to true - `priority` (Number) Helps to organize the order of builds execution in case of reaching the concurrency limit (default: `0`). - `required_available_storage` (String) Minimum disk space required for build filesystem ( unit Gi is required). - `runtime_environment` (Block List) The runtime environment for the pipeline. (see [below for nested schema](#nestedblock--spec--runtime_environment))