Skip to content

Commit

Permalink
Add deployment freeze override flags
Browse files Browse the repository at this point in the history
  • Loading branch information
bec-callow-oct committed Jan 9, 2025
1 parent fadb278 commit 7b882d8
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 65 deletions.
99 changes: 57 additions & 42 deletions pkg/cmd/release/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ const (

FlagUpdateVariables = "update-variables"
FlagAliasUpdateVariablesLegacy = "updateVariables"

FlagDeploymentFreezeNames = "deployment-freeze-names"
FlagDeploymentFreezeOverrideReason = "deployment-freeze-override-reason"
)

// executions API stops here.
Expand All @@ -90,38 +93,42 @@ const (
// DESIGN CHOICE: We are not going to show servertask progress in the CLI.

type DeployFlags struct {
Project *flag.Flag[string]
ReleaseVersion *flag.Flag[string] // the release to deploy
Environments *flag.Flag[[]string] // multiple for untenanted deployment
Tenants *flag.Flag[[]string]
TenantTags *flag.Flag[[]string]
DeployAt *flag.Flag[string]
MaxQueueTime *flag.Flag[string]
Variables *flag.Flag[[]string]
UpdateVariables *flag.Flag[bool]
ExcludedSteps *flag.Flag[[]string]
GuidedFailureMode *flag.Flag[string] // tri-state: true, false, or "use default". Can we model it with an optional bool?
ForcePackageDownload *flag.Flag[bool]
DeploymentTargets *flag.Flag[[]string]
ExcludeTargets *flag.Flag[[]string]
Project *flag.Flag[string]
ReleaseVersion *flag.Flag[string] // the release to deploy
Environments *flag.Flag[[]string] // multiple for untenanted deployment
Tenants *flag.Flag[[]string]
TenantTags *flag.Flag[[]string]
DeployAt *flag.Flag[string]
MaxQueueTime *flag.Flag[string]
Variables *flag.Flag[[]string]
UpdateVariables *flag.Flag[bool]
ExcludedSteps *flag.Flag[[]string]
GuidedFailureMode *flag.Flag[string] // tri-state: true, false, or "use default". Can we model it with an optional bool?
ForcePackageDownload *flag.Flag[bool]
DeploymentTargets *flag.Flag[[]string]
ExcludeTargets *flag.Flag[[]string]
DeploymentFreezeNames *flag.Flag[[]string]
DeploymentFreezeOverrideReason *flag.Flag[string]
}

func NewDeployFlags() *DeployFlags {
return &DeployFlags{
Project: flag.New[string](FlagProject, false),
ReleaseVersion: flag.New[string](FlagReleaseVersion, false),
Environments: flag.New[[]string](FlagEnvironment, false),
Tenants: flag.New[[]string](FlagTenant, false),
TenantTags: flag.New[[]string](FlagTenantTag, false),
MaxQueueTime: flag.New[string](FlagDeployAtExpiry, false),
DeployAt: flag.New[string](FlagDeployAt, false),
Variables: flag.New[[]string](FlagVariable, false),
UpdateVariables: flag.New[bool](FlagUpdateVariables, false),
ExcludedSteps: flag.New[[]string](FlagSkip, false),
GuidedFailureMode: flag.New[string](FlagGuidedFailure, false),
ForcePackageDownload: flag.New[bool](FlagForcePackageDownload, false),
DeploymentTargets: flag.New[[]string](FlagDeploymentTarget, false),
ExcludeTargets: flag.New[[]string](FlagExcludeDeploymentTarget, false),
Project: flag.New[string](FlagProject, false),
ReleaseVersion: flag.New[string](FlagReleaseVersion, false),
Environments: flag.New[[]string](FlagEnvironment, false),
Tenants: flag.New[[]string](FlagTenant, false),
TenantTags: flag.New[[]string](FlagTenantTag, false),
MaxQueueTime: flag.New[string](FlagDeployAtExpiry, false),
DeployAt: flag.New[string](FlagDeployAt, false),
Variables: flag.New[[]string](FlagVariable, false),
UpdateVariables: flag.New[bool](FlagUpdateVariables, false),
ExcludedSteps: flag.New[[]string](FlagSkip, false),
GuidedFailureMode: flag.New[string](FlagGuidedFailure, false),
ForcePackageDownload: flag.New[bool](FlagForcePackageDownload, false),
DeploymentTargets: flag.New[[]string](FlagDeploymentTarget, false),
ExcludeTargets: flag.New[[]string](FlagExcludeDeploymentTarget, false),
DeploymentFreezeNames: flag.New[[]string](FlagDeploymentFreezeNames, false),
DeploymentFreezeOverrideReason: flag.New[string](FlagDeploymentFreezeOverrideReason, false),
}
}

Expand Down Expand Up @@ -162,6 +169,8 @@ func NewCmdDeploy(f factory.Factory) *cobra.Command {
flags.BoolVarP(&deployFlags.ForcePackageDownload.Value, deployFlags.ForcePackageDownload.Name, "", false, "Force re-download of packages")
flags.StringArrayVarP(&deployFlags.DeploymentTargets.Value, deployFlags.DeploymentTargets.Name, "", nil, "Deploy to this target (can be specified multiple times)")
flags.StringArrayVarP(&deployFlags.ExcludeTargets.Value, deployFlags.ExcludeTargets.Name, "", nil, "Deploy to targets except for this (can be specified multiple times)")
flags.StringArrayVarP(&deployFlags.DeploymentFreezeNames.Value, deployFlags.DeploymentFreezeNames.Name, "", nil, "Override this deployment freeze (can be specified multiple times)")
flags.StringVarP(&deployFlags.DeploymentFreezeOverrideReason.Value, deployFlags.DeploymentFreezeOverrideReason.Name, "", "", "Reason for overriding a deployment freeze")

flags.SortFlags = false

Expand Down Expand Up @@ -202,20 +211,22 @@ func deployRun(cmd *cobra.Command, f factory.Factory, flags *DeployFlags) error
}

options := &executor.TaskOptionsDeployRelease{
ProjectName: flags.Project.Value,
ReleaseVersion: flags.ReleaseVersion.Value,
Environments: flags.Environments.Value,
Tenants: flags.Tenants.Value,
TenantTags: flags.TenantTags.Value,
ScheduledStartTime: flags.DeployAt.Value,
ScheduledExpiryTime: flags.MaxQueueTime.Value,
ExcludedSteps: flags.ExcludedSteps.Value,
GuidedFailureMode: flags.GuidedFailureMode.Value,
ForcePackageDownload: flags.ForcePackageDownload.Value,
DeploymentTargets: flags.DeploymentTargets.Value,
ExcludeTargets: flags.ExcludeTargets.Value,
Variables: parsedVariables,
UpdateVariables: flags.UpdateVariables.Value,
ProjectName: flags.Project.Value,
ReleaseVersion: flags.ReleaseVersion.Value,
Environments: flags.Environments.Value,
Tenants: flags.Tenants.Value,
TenantTags: flags.TenantTags.Value,
ScheduledStartTime: flags.DeployAt.Value,
ScheduledExpiryTime: flags.MaxQueueTime.Value,
ExcludedSteps: flags.ExcludedSteps.Value,
GuidedFailureMode: flags.GuidedFailureMode.Value,
ForcePackageDownload: flags.ForcePackageDownload.Value,
DeploymentTargets: flags.DeploymentTargets.Value,
ExcludeTargets: flags.ExcludeTargets.Value,
DeploymentFreezeNames: flags.DeploymentFreezeNames.Value,
DeploymentFreezeOverrideReason: flags.DeploymentFreezeOverrideReason.Value,
Variables: parsedVariables,
UpdateVariables: flags.UpdateVariables.Value,
}

// special case for FlagForcePackageDownload bool so we can tell if it was set on the cmdline or missing
Expand Down Expand Up @@ -250,6 +261,8 @@ func deployRun(cmd *cobra.Command, f factory.Factory, flags *DeployFlags) error
resolvedFlags.GuidedFailureMode.Value = options.GuidedFailureMode
resolvedFlags.DeploymentTargets.Value = options.DeploymentTargets
resolvedFlags.ExcludeTargets.Value = options.ExcludeTargets
resolvedFlags.DeploymentFreezeNames.Value = options.DeploymentFreezeNames
resolvedFlags.DeploymentFreezeOverrideReason.Value = options.DeploymentFreezeOverrideReason

didMaskSensitiveVariable := false
automationVariables := make(map[string]string, len(options.Variables))
Expand Down Expand Up @@ -281,6 +294,8 @@ func deployRun(cmd *cobra.Command, f factory.Factory, flags *DeployFlags) error
resolvedFlags.DeploymentTargets,
resolvedFlags.ExcludeTargets,
resolvedFlags.Variables,
resolvedFlags.DeploymentFreezeNames,
resolvedFlags.DeploymentFreezeOverrideReason,
)
cmd.Printf("\nAutomation Command: %s\n", autoCmd)

Expand Down
8 changes: 8 additions & 0 deletions pkg/cmd/release/deploy/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,8 @@ func TestDeployCreate_AutomationMode(t *testing.T) {
"--update-variables",
"--target", "firstMachine", "--target", "secondMachine",
"--exclude-target", "thirdMachine",
"--deployment-freeze-names", "freeze 1", "--deployment-freeze-names", "freeze 2",
"--deployment-freeze-override-reason", "Testing",
"--variable", "Approver:John", "--variable", "Signoff:Jane",
"--output-format", "basic", // not neccessary, just means we don't need the follow up HTTP requests at the end to print the web link
})
Expand Down Expand Up @@ -1505,6 +1507,8 @@ func TestDeployCreate_AutomationMode(t *testing.T) {
"Approver": "John",
"Signoff": "Jane",
},
DeploymentFreezeNames: []string{"freeze 1", "freeze 2"},
DeploymentFreezeOverrideReason: "Testing",
},
}, requestBody)

Expand Down Expand Up @@ -1540,6 +1544,8 @@ func TestDeployCreate_AutomationMode(t *testing.T) {
"--update-variables",
"--target", "firstMachine", "--target", "secondMachine",
"--exclude-target", "thirdMachine",
"--deployment-freeze-names", "freeze 1",
"--deployment-freeze-override-reason", "Testing",
"--variable", "Approver:John", "--variable", "Signoff:Jane",
"--output-format", "basic", // not neccessary, just means we don't need the follow up HTTP requests at the end to print the web link
})
Expand Down Expand Up @@ -1576,6 +1582,8 @@ func TestDeployCreate_AutomationMode(t *testing.T) {
"Approver": "John",
"Signoff": "Jane",
},
DeploymentFreezeNames: []string{"freeze 1"},
DeploymentFreezeOverrideReason: "Testing",
},
}, requestBody)

Expand Down
50 changes: 27 additions & 23 deletions pkg/executor/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,22 @@ func releaseCreate(octopus *client.Client, space *spaces.Space, input any) error
// ----- Deploy Release --------------------------------------

type TaskOptionsDeployRelease struct {
ProjectName string // required
ReleaseVersion string // the release to deploy
Environments []string // multiple for untenanted deployment, only one entry for tenanted deployment
Tenants []string
TenantTags []string
ScheduledStartTime string
ScheduledExpiryTime string
ExcludedSteps []string
GuidedFailureMode string // ["", "true", "false", "default"]. Note default and "" are the same, the only difference is whether interactive mode prompts you
ForcePackageDownload bool
DeploymentTargets []string
ExcludeTargets []string
Variables map[string]string
UpdateVariables bool
ProjectName string // required
ReleaseVersion string // the release to deploy
Environments []string // multiple for untenanted deployment, only one entry for tenanted deployment
Tenants []string
TenantTags []string
ScheduledStartTime string
ScheduledExpiryTime string
ExcludedSteps []string
GuidedFailureMode string // ["", "true", "false", "default"]. Note default and "" are the same, the only difference is whether interactive mode prompts you
ForcePackageDownload bool
DeploymentTargets []string
ExcludeTargets []string
Variables map[string]string
UpdateVariables bool
DeploymentFreezeNames []string
DeploymentFreezeOverrideReason string

// extra behaviour commands

Expand Down Expand Up @@ -140,15 +142,17 @@ func releaseDeploy(octopus *client.Client, space *spaces.Space, input any) error

// common properties
abstractCmd := deployments.CreateExecutionAbstractCommandV1{
SpaceID: space.ID,
ProjectIDOrName: params.ProjectName,
ForcePackageDownload: params.ForcePackageDownload,
SpecificMachineNames: params.DeploymentTargets,
ExcludedMachineNames: params.ExcludeTargets,
SkipStepNames: params.ExcludedSteps,
RunAt: params.ScheduledStartTime,
NoRunAfter: params.ScheduledExpiryTime,
Variables: params.Variables,
SpaceID: space.ID,
ProjectIDOrName: params.ProjectName,
ForcePackageDownload: params.ForcePackageDownload,
SpecificMachineNames: params.DeploymentTargets,
ExcludedMachineNames: params.ExcludeTargets,
SkipStepNames: params.ExcludedSteps,
RunAt: params.ScheduledStartTime,
NoRunAfter: params.ScheduledExpiryTime,
Variables: params.Variables,
DeploymentFreezeNames: params.DeploymentFreezeNames,

Check failure on line 154 in pkg/executor/release.go

View workflow job for this annotation

GitHub Actions / test

unknown field DeploymentFreezeNames in struct literal of type deployments.CreateExecutionAbstractCommandV1
DeploymentFreezeOverrideReason: params.DeploymentFreezeOverrideReason,

Check failure on line 155 in pkg/executor/release.go

View workflow job for this annotation

GitHub Actions / test

unknown field DeploymentFreezeOverrideReason in struct literal of type deployments.CreateExecutionAbstractCommandV1
}

b, err := strconv.ParseBool(params.GuidedFailureMode)
Expand Down

0 comments on commit 7b882d8

Please sign in to comment.