From bd8daa9a444fb0855ba15f2769c78cade68c2db4 Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Fri, 27 Dec 2024 14:07:37 +1300 Subject: [PATCH 1/4] Add built-in trigger resource for project auto releases Set "id" to the action package reference when exists, without it new id is always generated and deployment process update will fail if package is referenced by built-in trigger --- octopusdeploy/schema_package_reference.go | 4 + octopusdeploy_framework/framework_provider.go | 1 + .../resource_built_in_trigger.go | 184 ++++++++++++++++++ .../schemas/bult_in_trigger.go | 71 +++++++ 4 files changed, 260 insertions(+) create mode 100644 octopusdeploy_framework/resource_built_in_trigger.go create mode 100644 octopusdeploy_framework/schemas/bult_in_trigger.go diff --git a/octopusdeploy/schema_package_reference.go b/octopusdeploy/schema_package_reference.go index 4bf75bf76..98f2f3ae7 100644 --- a/octopusdeploy/schema_package_reference.go +++ b/octopusdeploy/schema_package_reference.go @@ -113,6 +113,10 @@ func expandPackageReference(tfPkg map[string]interface{}) *packages.PackageRefer Properties: map[string]string{}, } + if id, ok := tfPkg["id"]; ok { + pkg.ID = id.(string) + } + if v, ok := tfPkg["extract_during_deployment"]; ok { pkg.Properties["Extract"] = cases.Title(language.Und, cases.NoLower).String(strconv.FormatBool(v.(bool))) } diff --git a/octopusdeploy_framework/framework_provider.go b/octopusdeploy_framework/framework_provider.go index 30595cac3..684b65268 100644 --- a/octopusdeploy_framework/framework_provider.go +++ b/octopusdeploy_framework/framework_provider.go @@ -133,6 +133,7 @@ func (p *octopusDeployFrameworkProvider) Resources(ctx context.Context) []func() NewGenericOidcResource, NewDeploymentFreezeTenantResource, NewGitTriggerResource, + NewBuiltInTriggerResource, } } diff --git a/octopusdeploy_framework/resource_built_in_trigger.go b/octopusdeploy_framework/resource_built_in_trigger.go new file mode 100644 index 000000000..067ef47dc --- /dev/null +++ b/octopusdeploy_framework/resource_built_in_trigger.go @@ -0,0 +1,184 @@ +package octopusdeploy_framework + +import ( + "context" + "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/packages" + "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/projects" + "github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/schemas" + "github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/util" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type builtInTriggerResource struct { + *Config +} + +func NewBuiltInTriggerResource() resource.Resource { + return &builtInTriggerResource{} +} + +var _ resource.ResourceWithImportState = &builtInTriggerResource{} + +func (r *builtInTriggerResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = util.GetTypeName("built_in_trigger") +} + +func (r *builtInTriggerResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schemas.BuiltInTriggerSchema{}.GetResourceSchema() +} + +func (r *builtInTriggerResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + r.Config = ResourceConfiguration(req, resp) +} + +func (r *builtInTriggerResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} + +func (r *builtInTriggerResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var data schemas.BuiltInTriggerResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + projectId := data.ProjectID.ValueString() + project, err := projects.GetByID(r.Client, data.SpaceID.ValueString(), projectId) + if err != nil { + resp.Diagnostics.AddError("Failed to read associated project for built-in trigger", err.Error()) + return + } + releaseStrategy := mapStateToReleaseCreationStrategy(&data) + project.ReleaseCreationStrategy = releaseStrategy + project.AutoCreateRelease = true + + _, err = projects.Update(r.Client, project) + if err != nil { + resp.Diagnostics.AddError("Error updating associated project for built-in trigger", err.Error()) + return + } + + // Reload project in case different values were computed for release strategy + updatedProject, err := projects.GetByID(r.Client, data.SpaceID.ValueString(), projectId) + if err != nil { + resp.Diagnostics.AddError("Failed to read associated project for built-in trigger", err.Error()) + return + } + + mapReleaseCreationStrategyToState(updatedProject, &data) + resp.Diagnostics.Append(resp.State.Set(ctx, data)...) +} + +func (r *builtInTriggerResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state schemas.BuiltInTriggerResourceModel + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + projectId := state.ProjectID.ValueString() + project, err := projects.GetByID(r.Client, state.SpaceID.ValueString(), projectId) + if err != nil { + resp.Diagnostics.AddError("Failed to read associated project for built-in trigger", err.Error()) + return + } + + mapReleaseCreationStrategyToState(project, &state) + + resp.Diagnostics.Append(resp.State.Set(ctx, state)...) +} + +func (r *builtInTriggerResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var data schemas.BuiltInTriggerResourceModel + diags := req.Plan.Get(ctx, &data) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + projectId := data.ProjectID.ValueString() + existingProject, err := projects.GetByID(r.Client, data.SpaceID.ValueString(), projectId) + if err != nil { + resp.Diagnostics.AddError("Failed to read associated project for built-in trigger", err.Error()) + return + } + + releaseStrategy := mapStateToReleaseCreationStrategy(&data) + existingProject.ReleaseCreationStrategy = releaseStrategy + existingProject.AutoCreateRelease = true + + _, err = projects.Update(r.Client, existingProject) + if err != nil { + resp.Diagnostics.AddError("Error updating associated project for built-in trigger", err.Error()) + return + } + + updatedProject, err := projects.GetByID(r.Client, data.SpaceID.ValueString(), projectId) + if err != nil { + resp.Diagnostics.AddError("Failed to read associated project for built-in trigger", err.Error()) + return + } + + mapReleaseCreationStrategyToState(updatedProject, &data) + resp.Diagnostics.Append(resp.State.Set(ctx, data)...) +} + +func (r *builtInTriggerResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state schemas.BuiltInTriggerResourceModel + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + projectId := state.ProjectID.ValueString() + project, err := projects.GetByID(r.Client, state.SpaceID.ValueString(), projectId) + if err != nil { + resp.Diagnostics.AddError("Failed to read associated project for built-in trigger", err.Error()) + return + } + + project.ReleaseCreationStrategy = &projects.ReleaseCreationStrategy{} + project.AutoCreateRelease = false + + _, err = projects.Update(r.Client, project) + if err != nil { + resp.Diagnostics.AddError("Error updating project to remove release creation strategy(built-in trigger)", err.Error()) + return + } + + resp.State.RemoveResource(ctx) +} + +func mapStateToReleaseCreationStrategy(state *schemas.BuiltInTriggerResourceModel) *projects.ReleaseCreationStrategy { + var releaseCreationPackageStepId string + releaseCreationPackageStepIdString := state.ReleaseCreationPackageStepID.ValueString() + if releaseCreationPackageStepIdString != "" { + releaseCreationPackageStepId = releaseCreationPackageStepIdString + } + + return &projects.ReleaseCreationStrategy{ + ReleaseCreationPackageStepID: releaseCreationPackageStepId, + ChannelID: state.ChannelID.ValueString(), + ReleaseCreationPackage: &packages.DeploymentActionPackage{ + DeploymentAction: state.ReleaseCreationPackage.DeploymentAction.ValueString(), + PackageReference: state.ReleaseCreationPackage.PackageReference.ValueString(), + }, + } +} + +func mapReleaseCreationStrategyToState(project *projects.Project, state *schemas.BuiltInTriggerResourceModel) { + releaseStrategy := project.ReleaseCreationStrategy + + if releaseStrategy.ReleaseCreationPackageStepID != "" { + state.ReleaseCreationPackageStepID = types.StringValue(releaseStrategy.ReleaseCreationPackageStepID) + } + + state.ChannelID = types.StringValue(releaseStrategy.ChannelID) + state.ReleaseCreationPackage.PackageReference = types.StringValue(releaseStrategy.ReleaseCreationPackage.PackageReference) + state.ReleaseCreationPackage.DeploymentAction = types.StringValue(releaseStrategy.ReleaseCreationPackage.DeploymentAction) + state.SpaceID = types.StringValue(project.SpaceID) +} diff --git a/octopusdeploy_framework/schemas/bult_in_trigger.go b/octopusdeploy_framework/schemas/bult_in_trigger.go new file mode 100644 index 000000000..0dca638da --- /dev/null +++ b/octopusdeploy_framework/schemas/bult_in_trigger.go @@ -0,0 +1,71 @@ +package schemas + +import ( + "github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/util" + datasourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type BuiltInTriggerSchema struct{} + +var _ EntitySchema = BuiltInTriggerSchema{} + +func (r BuiltInTriggerSchema) GetResourceSchema() resourceSchema.Schema { + return resourceSchema.Schema{ + Attributes: map[string]resourceSchema.Attribute{ + "project_id": util.ResourceString(). + Description("The ID of the project the trigger will be attached to."). + PlanModifiers(stringplanmodifier.RequiresReplace()). + Required(). + Build(), + "space_id": util.ResourceString(). + Description("Space ID of the associated project."). + Optional(). + Computed(). + Build(), + "channel_id": util.ResourceString(). + Description("The ID of the channel in which triggered release will be created."). + Required(). + Build(), + "release_creation_package_step_id": util.ResourceString(). + Description("The package step ID trigger will be listening."). + Optional(). + Computed(). + Build(), + "release_creation_package": resourceSchema.SingleNestedAttribute{ + Required: true, + Description: "Combination of deployment action and package references.", + Attributes: map[string]resourceSchema.Attribute{ + "deployment_action": util.ResourceString(). + Description("Deployment action."). + Optional(). + Build(), + "package_reference": util.ResourceString(). + Description("Package reference."). + Optional(). + Build(), + }, + }, + }, + } +} + +func (r BuiltInTriggerSchema) GetDatasourceSchema() datasourceSchema.Schema { + // no datasource required, returned as part of project datasource + return datasourceSchema.Schema{} +} + +type BuiltInTriggerResourceModel struct { + ProjectID types.String `tfsdk:"project_id"` + SpaceID types.String `tfsdk:"space_id"` + ChannelID types.String `tfsdk:"channel_id"` + ReleaseCreationPackageStepID types.String `tfsdk:"release_creation_package_step_id"` + ReleaseCreationPackage ReleaseCreationPackageModel `tfsdk:"release_creation_package"` +} + +type ReleaseCreationPackageModel struct { + DeploymentAction types.String `tfsdk:"deployment_action"` + PackageReference types.String `tfsdk:"package_reference"` +} From ef5492c2fe9071e062c6e91f136ce1c4b596b727 Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Fri, 27 Dec 2024 14:30:48 +1300 Subject: [PATCH 2/4] Add documentation for built_in_trigger --- docs/resources/built_in_trigger.md | 124 ++++++++++++++++++ .../resource.tf | 84 ++++++++++++ ...bult_in_trigger.go => built_in_trigger.go} | 1 + 3 files changed, 209 insertions(+) create mode 100644 docs/resources/built_in_trigger.md create mode 100644 examples/resources/octopusdeploy_built_in_trigger/resource.tf rename octopusdeploy_framework/schemas/{bult_in_trigger.go => built_in_trigger.go} (96%) diff --git a/docs/resources/built_in_trigger.md b/docs/resources/built_in_trigger.md new file mode 100644 index 000000000..24d438a91 --- /dev/null +++ b/docs/resources/built_in_trigger.md @@ -0,0 +1,124 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "octopusdeploy_built_in_trigger Resource - terraform-provider-octopusdeploy" +subcategory: "" +description: |- + This resource manages automatic release trigger based on new version of referenced package. +--- + +# octopusdeploy_built_in_trigger (Resource) + +This resource manages automatic release trigger based on new version of referenced package. + +## Example Usage + +```terraform +resource "octopusdeploy_project_group" "example" { + name = "Example" + description = "Example Group" +} + +resource "octopusdeploy_project" "example" { + name = "Example" + lifecycle_id = "Lifecycles-101" + project_group_id = octopusdeploy_project_group.example.id + default_guided_failure_mode = "EnvironmentDefault" + default_to_skip_if_already_installed = false + description = "Project with Built-In Trigger" + discrete_channel_release = false + is_disabled = false + is_discrete_channel_release = false + is_version_controlled = false + tenanted_deployment_participation = "Untenanted" + included_library_variable_sets = [] + + connectivity_policy { + allow_deployments_to_no_targets = false + exclude_unhealthy_targets = false + skip_machine_behavior = "SkipUnavailableMachines" + } +} + +resource "octopusdeploy_channel" "example" { + name = "Example Channel" + project_id = octopusdeploy_project.example.id + lifecycle_id = "Lifecycles-101" +} + +data "octopusdeploy_feeds" "built_in" { + feed_type = "BuiltIn" + ids = null + partial_name = "" + skip = 0 + take = 1 +} + +resource "octopusdeploy_deployment_process" "example" { + project_id = octopusdeploy_project.example.id + step { + condition = "Success" + name = "Step One" + package_requirement = "LetOctopusDecide" + start_trigger = "StartAfterPrevious" + run_script_action { + condition = "Success" + is_disabled = false + is_required = true + name = "Action One" + script_body = <<-EOT + $ExtractedPath = $OctopusParameters["Octopus.Action.Package[my.package].ExtractedPath"] + Write-Host $ExtractedPath + EOT + run_on_server = true + + package { + name = "my.package" + package_id = "my.package" + feed_id = data.octopusdeploy_feeds.built_in.feeds[0].id + acquisition_location = "Server" + extract_during_deployment = true + } + } + } +} + +resource "octopusdeploy_built_in_trigger" "example" { + project_id = octopusdeploy_project.example.id + channel_id = octopusdeploy_channel.example.id + + release_creation_package = { + deployment_action = "Action One" + package_reference = "my.package" + } + + depends_on = [ + octopusdeploy_project.example, + octopusdeploy_channel.example, + octopusdeploy_deployment_process.example + ] +} +``` + + +## Schema + +### Required + +- `channel_id` (String) The ID of the channel in which triggered release will be created. +- `project_id` (String) The ID of the project the trigger will be attached to. +- `release_creation_package` (Attributes) Combination of deployment action and package references. (see [below for nested schema](#nestedatt--release_creation_package)) + +### Optional + +- `release_creation_package_step_id` (String) The package step ID trigger will be listening. +- `space_id` (String) Space ID of the associated project. + + +### Nested Schema for `release_creation_package` + +Optional: + +- `deployment_action` (String) Deployment action. +- `package_reference` (String) Package reference. + + diff --git a/examples/resources/octopusdeploy_built_in_trigger/resource.tf b/examples/resources/octopusdeploy_built_in_trigger/resource.tf new file mode 100644 index 000000000..fb6c86ebf --- /dev/null +++ b/examples/resources/octopusdeploy_built_in_trigger/resource.tf @@ -0,0 +1,84 @@ +resource "octopusdeploy_project_group" "example" { + name = "Example" + description = "Example Group" +} + +resource "octopusdeploy_project" "example" { + name = "Example" + lifecycle_id = "Lifecycles-101" + project_group_id = octopusdeploy_project_group.example.id + default_guided_failure_mode = "EnvironmentDefault" + default_to_skip_if_already_installed = false + description = "Project with Built-In Trigger" + discrete_channel_release = false + is_disabled = false + is_discrete_channel_release = false + is_version_controlled = false + tenanted_deployment_participation = "Untenanted" + included_library_variable_sets = [] + + connectivity_policy { + allow_deployments_to_no_targets = false + exclude_unhealthy_targets = false + skip_machine_behavior = "SkipUnavailableMachines" + } +} + +resource "octopusdeploy_channel" "example" { + name = "Example Channel" + project_id = octopusdeploy_project.example.id + lifecycle_id = "Lifecycles-101" +} + +data "octopusdeploy_feeds" "built_in" { + feed_type = "BuiltIn" + ids = null + partial_name = "" + skip = 0 + take = 1 +} + +resource "octopusdeploy_deployment_process" "example" { + project_id = octopusdeploy_project.example.id + step { + condition = "Success" + name = "Step One" + package_requirement = "LetOctopusDecide" + start_trigger = "StartAfterPrevious" + run_script_action { + condition = "Success" + is_disabled = false + is_required = true + name = "Action One" + script_body = <<-EOT + $ExtractedPath = $OctopusParameters["Octopus.Action.Package[my.package].ExtractedPath"] + Write-Host $ExtractedPath + EOT + run_on_server = true + + package { + name = "my.package" + package_id = "my.package" + feed_id = data.octopusdeploy_feeds.built_in.feeds[0].id + acquisition_location = "Server" + extract_during_deployment = true + } + } + } +} + +resource "octopusdeploy_built_in_trigger" "example" { + project_id = octopusdeploy_project.example.id + channel_id = octopusdeploy_channel.example.id + + release_creation_package = { + deployment_action = "Action One" + package_reference = "my.package" + } + + depends_on = [ + octopusdeploy_project.example, + octopusdeploy_channel.example, + octopusdeploy_deployment_process.example + ] +} diff --git a/octopusdeploy_framework/schemas/bult_in_trigger.go b/octopusdeploy_framework/schemas/built_in_trigger.go similarity index 96% rename from octopusdeploy_framework/schemas/bult_in_trigger.go rename to octopusdeploy_framework/schemas/built_in_trigger.go index 0dca638da..654307ee9 100644 --- a/octopusdeploy_framework/schemas/bult_in_trigger.go +++ b/octopusdeploy_framework/schemas/built_in_trigger.go @@ -14,6 +14,7 @@ var _ EntitySchema = BuiltInTriggerSchema{} func (r BuiltInTriggerSchema) GetResourceSchema() resourceSchema.Schema { return resourceSchema.Schema{ + Description: "This resource manages automatic release trigger based on new version of referenced package.", Attributes: map[string]resourceSchema.Attribute{ "project_id": util.ResourceString(). Description("The ID of the project the trigger will be attached to."). From eedb5362e7aed06d435a0422ce33e92f986c850f Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Fri, 27 Dec 2024 15:44:48 +1300 Subject: [PATCH 3/4] Add tests for built-in trigger --- .../resource_built_in_trigger_test.go | 215 ++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 octopusdeploy_framework/resource_built_in_trigger_test.go diff --git a/octopusdeploy_framework/resource_built_in_trigger_test.go b/octopusdeploy_framework/resource_built_in_trigger_test.go new file mode 100644 index 000000000..186d503af --- /dev/null +++ b/octopusdeploy_framework/resource_built_in_trigger_test.go @@ -0,0 +1,215 @@ +package octopusdeploy_framework + +import ( + "fmt" + "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/projects" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +func TestAccResourceBuiltInTrigger(t *testing.T) { + localName := acctest.RandStringFromCharSet(50, acctest.CharSetAlpha) + prefix := fmt.Sprintf("octopusdeploy_built_in_trigger.%s", localName) + + resource.Test(t, resource.TestCase{ + CheckDestroy: func(s *terraform.State) error { return testBuiltInTriggerCheckDestroy(s) }, + ProtoV6ProviderFactories: ProtoV6ProviderFactories(), + PreCheck: func() { TestAccPreCheck(t) }, + Steps: []resource.TestStep{ + { + Config: configTestAccBuiltInTrigger(localName, "Action One", "console.one"), + Check: testAssertBuiltInResourceAttributesAreSet(prefix), + }, + { + Config: configTestAccBuiltInTrigger(localName, "Action Two", "console.two"), + Check: testAssertBuiltInResourceAttributesAreSet(prefix), + }, + }, + }) +} + +func testAssertBuiltInResourceAttributesAreSet(prefix string) resource.TestCheckFunc { + return resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(prefix, "project_id"), + resource.TestCheckResourceAttrSet(prefix, "channel_id"), + resource.TestCheckResourceAttrSet(prefix, "release_creation_package.deployment_action"), + resource.TestCheckResourceAttrSet(prefix, "release_creation_package.package_reference"), + testBuiltInTriggerExists(prefix), + ) +} + +func testBuiltInTriggerExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + triggerResource, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("not found: %s", resourceName) + } + + projectId, ok := triggerResource.Primary.Attributes["project_id"] + if !ok { + return fmt.Errorf("no project_id found: %s", resourceName) + } + + project, failure := projects.GetByID(octoClient, octoClient.GetSpaceID(), projectId) + if failure != nil { + return fmt.Errorf("failed to read project(%s) of built-in trigger: %s", projectId, failure.Error()) + } + + if project.AutoCreateRelease == false { + return fmt.Errorf("expected project.AutoCreateRelease not to be false") + } + + if project.ReleaseCreationStrategy == nil { + return fmt.Errorf("expected project.ReleaseCreationStrategy not to be nil") + } + + return nil + } +} + +func testBuiltInTriggerCheckDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "octopusdeploy_built_in_trigger" { + continue + } + + projectId := rs.Primary.Attributes["project_id"] + project, err := projects.GetByID(octoClient, octoClient.GetSpaceID(), projectId) + if err == nil && project != nil { + return fmt.Errorf("project of built-in trigger (%s) still exists", projectId) + } + } + + return nil +} + +func configTestAccBuiltInTrigger(localName string, actionName string, packageReference string) string { + return fmt.Sprintf(` + data "octopusdeploy_lifecycles" "default" { + ids = null + partial_name = "Default Lifecycle" + skip = 0 + take = 1 + } + + resource "octopusdeploy_project_group" "test" { + name = "Test" + description = "Test project group" + } + + resource "octopusdeploy_project" "test" { + name = "Test" + lifecycle_id = data.octopusdeploy_lifecycles.default.lifecycles[0].id + project_group_id = octopusdeploy_project_group.test.id + default_guided_failure_mode = "EnvironmentDefault" + default_to_skip_if_already_installed = false + description = "Project with Built-In Trigger" + discrete_channel_release = false + is_disabled = false + is_discrete_channel_release = false + is_version_controlled = false + tenanted_deployment_participation = "Untenanted" + included_library_variable_sets = [] + + connectivity_policy { + allow_deployments_to_no_targets = false + exclude_unhealthy_targets = false + skip_machine_behavior = "SkipUnavailableMachines" + } + } + + resource "octopusdeploy_channel" "test" { + name = "Test Channel" + project_id = octopusdeploy_project.test.id + lifecycle_id = data.octopusdeploy_lifecycles.default.lifecycles[0].id + } + + data "octopusdeploy_feeds" "built_in_feed" { + feed_type = "BuiltIn" + ids = null + partial_name = "" + skip = 0 + take = 1 + } + + resource "octopusdeploy_deployment_process" "test" { + project_id = octopusdeploy_project.test.id + + step { + condition = "Success" + name = "Step One" + package_requirement = "LetOctopusDecide" + start_trigger = "StartAfterPrevious" + run_script_action { + condition = "Success" + is_disabled = false + is_required = true + name = "Action One" + script_body = <<-EOT + $ExtractedPath = $OctopusParameters["Octopus.Action.Package[console.one].ExtractedPath"] + Write-Host $ExtractedPath + EOT + run_on_server = true + + package { + name = "console.one" + package_id = "console.one" + feed_id = data.octopusdeploy_feeds.built_in_feed.feeds[0].id + acquisition_location = "Server" + extract_during_deployment = true + } + } + } + + step { + condition = "Success" + name = "Step Two" + package_requirement = "LetOctopusDecide" + start_trigger = "StartAfterPrevious" + run_script_action { + condition = "Success" + is_disabled = false + is_required = true + name = "Action Two" + script_body = <<-EOT + $ExtractedPath = $OctopusParameters["Octopus.Action.Package[console.two].ExtractedPath"] + Write-Host $ExtractedPath + EOT + run_on_server = true + + package { + name = "console.two" + package_id = "console.two" + feed_id = data.octopusdeploy_feeds.built_in_feed.feeds[0].id + acquisition_location = "Server" + extract_during_deployment = true + } + } + } + } + + resource "octopusdeploy_built_in_trigger" "%s" { + project_id = octopusdeploy_project.test.id + channel_id = octopusdeploy_channel.test.id + + release_creation_package = { + deployment_action = "%s" + package_reference = "%s" + } + + depends_on = [ + octopusdeploy_project.test, + octopusdeploy_channel.test, + octopusdeploy_deployment_process.test + ] + } + `, + localName, + actionName, + packageReference, + ) +} From 92ae595e64769cfaa6503a761389c90e4b6f8c67 Mon Sep 17 00:00:00 2001 From: "denys.kostynchuk" Date: Mon, 30 Dec 2024 15:37:19 +1300 Subject: [PATCH 4/4] Use value same as returned by the server for tests to avoid "plan is not empty" failure --- octopusdeploy_framework/resource_built_in_trigger_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/octopusdeploy_framework/resource_built_in_trigger_test.go b/octopusdeploy_framework/resource_built_in_trigger_test.go index 186d503af..896d07314 100644 --- a/octopusdeploy_framework/resource_built_in_trigger_test.go +++ b/octopusdeploy_framework/resource_built_in_trigger_test.go @@ -149,6 +149,7 @@ func configTestAccBuiltInTrigger(localName string, actionName string, packageRef is_disabled = false is_required = true name = "Action One" + sort_order = 1 script_body = <<-EOT $ExtractedPath = $OctopusParameters["Octopus.Action.Package[console.one].ExtractedPath"] Write-Host $ExtractedPath @@ -175,6 +176,7 @@ func configTestAccBuiltInTrigger(localName string, actionName string, packageRef is_disabled = false is_required = true name = "Action Two" + sort_order = 1 script_body = <<-EOT $ExtractedPath = $OctopusParameters["Octopus.Action.Package[console.two].ExtractedPath"] Write-Host $ExtractedPath