Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: panic using project_verisoning_strategy without donorpackage #859

Merged
merged 4 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/integration-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
OCTOTESTRETRYCOUNT: 1
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: junit-test-summary-${{ matrix.index }}
path: node-summary.xml
Expand All @@ -117,7 +117,7 @@ jobs:
- uses: actions/setup-node@v3

- name: Download artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4

- name: Install junit-report-merger
run: npm install -g junit-report-merger
Expand All @@ -142,7 +142,7 @@ jobs:
"junit-test-summary-14/*.xml"

- name: Upload test artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: junit-test-summary
path: ./junit-test-summary.xml
Expand Down
22 changes: 18 additions & 4 deletions docs/resources/project_versioning_strategy.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,21 @@ resource "octopusdeploy_deployment_process" "process" {
depends_on = [octopusdeploy_project.tp]
}

resource "octopusdeploy_project_versioning_strategy" "tp" {
######
# NOTE: You can use either template or donor_package, not both
######
resource "octopusdeploy_project_versioning_strategy" "using_template" {
project_id = octopusdeploy_project.tp.id
space_id = octopusdeploy_project.tp.space_id
# See https://octopus.com/docs/releases/release-versioning for variable syntax
template = "#{Octopus.Version.LastMajor}.#{Octopus.Version.NextMinor}-alpha"
depends_on = [
octopusdeploy_project_group.tp,
octopusdeploy_deployment_process.process
]
}

resource "octopusdeploy_project_versioning_strategy" "using_donor_package" {
project_id = octopusdeploy_project.tp.id
space_id = octopusdeploy_project.tp.space_id
donor_package_step_id = octopusdeploy_deployment_process.process.step[0].run_script_action[0].id
Expand All @@ -80,19 +94,19 @@ resource "octopusdeploy_project_versioning_strategy" "tp" {

### Required

- `donor_package` (Attributes) Donor Packages. (see [below for nested schema](#nestedatt--donor_package))
- `project_id` (String) The associated project ID.
- `space_id` (String) Space ID of the associated project.

### Optional

- `donor_package` (Attributes) Donor Packages. (see [below for nested schema](#nestedatt--donor_package))
- `donor_package_step_id` (String) The associated donor package step ID.
- `space_id` (String) Space ID of the associated project.
- `template` (String)

<a id="nestedatt--donor_package"></a>
### Nested Schema for `donor_package`

Optional:
Required:

- `deployment_action` (String) Deployment action.
- `package_reference` (String) Package reference.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,21 @@ resource "octopusdeploy_deployment_process" "process" {
depends_on = [octopusdeploy_project.tp]
}

resource "octopusdeploy_project_versioning_strategy" "tp" {
######
# NOTE: You can use either template or donor_package, not both
######
resource "octopusdeploy_project_versioning_strategy" "using_template" {
project_id = octopusdeploy_project.tp.id
space_id = octopusdeploy_project.tp.space_id
# See https://octopus.com/docs/releases/release-versioning for variable syntax
template = "#{Octopus.Version.LastMajor}.#{Octopus.Version.NextMinor}-alpha"
depends_on = [
octopusdeploy_project_group.tp,
octopusdeploy_deployment_process.process
]
}

resource "octopusdeploy_project_versioning_strategy" "using_donor_package" {
project_id = octopusdeploy_project.tp.id
space_id = octopusdeploy_project.tp.space_id
donor_package_step_id = octopusdeploy_deployment_process.process.step[0].run_script_action[0].id
Expand Down
40 changes: 25 additions & 15 deletions octopusdeploy_framework/resource_project_versioning_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ package octopusdeploy_framework

import (
"context"
"log"
"net/http"

"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core"
"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/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"log"
"net/http"
)

var _ resource.Resource = &projectVersioningStrategyResource{}
var _ resource.ResourceWithConfigValidators = &projectVersioningStrategyResource{}

type projectVersioningStrategyResource struct {
*Config
Expand All @@ -31,6 +32,10 @@ func (r *projectVersioningStrategyResource) Schema(_ context.Context, _ resource
resp.Schema = schemas.ProjectVersioningStrategySchema{}.GetResourceSchema()
}

func (r *projectVersioningStrategyResource) ConfigValidators(context.Context) []resource.ConfigValidator {
return schemas.ProjectVersioningStrategySchema{}.GetResourceConfigValidators()
}

func (r *projectVersioningStrategyResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
r.Config = ResourceConfiguration(req, resp)
}
Expand Down Expand Up @@ -164,27 +169,32 @@ func (r *projectVersioningStrategyResource) Delete(ctx context.Context, req reso
}

func mapStateToProjectVersioningStrategy(state *schemas.ProjectVersioningStrategyModel) *projects.VersioningStrategy {
var donorPackageStepID *string
donorPackageStepIDString := state.DonorPackageStepID.ValueString()
if donorPackageStepIDString != "" {
donorPackageStepID = &donorPackageStepIDString
projectVersioningStrategy := &projects.VersioningStrategy{}
if !(state.Template.IsNull()) {
projectVersioningStrategy.Template = state.Template.ValueString()
}

return &projects.VersioningStrategy{
Template: state.Template.ValueString(),
DonorPackageStepID: donorPackageStepID,
DonorPackage: &packages.DeploymentActionPackage{
if !(state.DonorPackageStepID.IsNull()) {
projectVersioningStrategy.DonorPackageStepID = state.DonorPackageStepID.ValueStringPointer()
}
if !(state.DonorPackage == nil) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am guessing you do this to match the above line over != nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, consistency of... polarity?... of the check, so that it's easy to scan down and understand. I would've preferred an IsNull() method, but it doesn't exist on the DonorPackage struct versus the String above.

projectVersioningStrategy.DonorPackage = &packages.DeploymentActionPackage{
DeploymentAction: state.DonorPackage.DeploymentAction.ValueString(),
PackageReference: state.DonorPackage.PackageReference.ValueString(),
},
}
}

return projectVersioningStrategy
}

func mapProjectVersioningStrategyToState(versioningStrategy *projects.VersioningStrategy, state *schemas.ProjectVersioningStrategyModel) {
if versioningStrategy.DonorPackageStepID != nil {
state.DonorPackageStepID = types.StringValue(*versioningStrategy.DonorPackageStepID)
}
// Template and Donor Package are mutually exclusive options. We won't always have DonorPackage information.
state.Template = types.StringValue(versioningStrategy.Template)
state.DonorPackage.PackageReference = types.StringValue(versioningStrategy.DonorPackage.PackageReference)
state.DonorPackage.DeploymentAction = types.StringValue(versioningStrategy.DonorPackage.DeploymentAction)

if !(versioningStrategy.DonorPackage == nil) {
state.DonorPackage.PackageReference = types.StringValue(versioningStrategy.DonorPackage.PackageReference)
state.DonorPackage.DeploymentAction = types.StringValue(versioningStrategy.DonorPackage.DeploymentAction)
}
}
6 changes: 6 additions & 0 deletions octopusdeploy_framework/schemas/entity_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ package schemas

import (
datasourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource"
resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
)

type EntitySchema interface {
GetResourceSchema() resourceSchema.Schema
GetDatasourceSchema() datasourceSchema.Schema
}

type EntitySchemaWithResourceValidators interface {
EntitySchema
GetResourceConfigValidators() []resource.ConfigValidator
}
40 changes: 30 additions & 10 deletions octopusdeploy_framework/schemas/project_versioning_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ package schemas

import (
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/octopusdeploy_framework/util"
"github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator"
datasourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
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 ProjectVersioningStrategySchema struct{}

var _ EntitySchema = ProjectVersioningStrategySchema{}
var _ EntitySchemaWithResourceValidators = ProjectVersioningStrategySchema{}

const ProjectVersioningStrategyResourceName = "project_versioning_strategy"

Expand All @@ -24,7 +27,7 @@ func (p ProjectVersioningStrategySchema) GetResourceSchema() resourceSchema.Sche
Build(),
"space_id": util.ResourceString().
Description("Space ID of the associated project.").
Required().
Optional().
Build(),
"donor_package_step_id": util.ResourceString().
Description("The associated donor package step ID.").
Expand All @@ -35,34 +38,51 @@ func (p ProjectVersioningStrategySchema) GetResourceSchema() resourceSchema.Sche
Computed().
Build(),
"donor_package": resourceSchema.SingleNestedAttribute{
Required: true,
Optional: true,
Description: "Donor Packages.",
Attributes: map[string]resourceSchema.Attribute{
"deployment_action": util.ResourceString().
Description("Deployment action.").
Optional().
Required().
Build(),
"package_reference": util.ResourceString().
Description("Package reference.").
Optional().
Required().
Build(),
},
},
},
}
}

func (p ProjectVersioningStrategySchema) GetResourceConfigValidators() []resource.ConfigValidator {
return []resource.ConfigValidator{
resourcevalidator.RequiredTogether(
path.MatchRoot("donor_package"),
path.MatchRoot("donor_package_step_id"),
),
resourcevalidator.Conflicting(
path.MatchRoot("template"),
path.MatchRoot("donor_package"),
),
resourcevalidator.Conflicting(
path.MatchRoot("template"),
path.MatchRoot("donor_package_step_id"),
),
}
}
Comment on lines +58 to +73
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🆒


func (p ProjectVersioningStrategySchema) GetDatasourceSchema() datasourceSchema.Schema {
// no datasource required, returned as part of project datasource
return datasourceSchema.Schema{}
}

type ProjectVersioningStrategyModel struct {
ProjectID types.String `tfsdk:"project_id"`
SpaceID types.String `tfsdk:"space_id"`
DonorPackageStepID types.String `tfsdk:"donor_package_step_id"`
Template types.String `tfsdk:"template"`
DonorPackage DonorPackageModel `tfsdk:"donor_package"`
ProjectID types.String `tfsdk:"project_id"`
SpaceID types.String `tfsdk:"space_id"`
DonorPackageStepID types.String `tfsdk:"donor_package_step_id"`
Template types.String `tfsdk:"template"`
DonorPackage *DonorPackageModel `tfsdk:"donor_package"`
}

type DonorPackageModel struct {
Expand Down
Loading