If clause in run condition comparing two variables


(Soumen Dass) #1

I have below variables:

ENVNAME[machine1]=ABC
ENVNAME[machine2]=XYZ

I also have two deployment targets: machine1 and machine2

In my step template, I am trying to use below run condition:

#{if USER_SUPPLIED_MACHINE_NAME == ENVNAME[#{Octopus.Machine.Name}]}True#{/if}

“USER_SUPPLIED_MACHINE_NAME” is a prompted variable populated via user input.

However, this condition always evaluates to false. I have tried setting OctopusPrintVariables and OctopusPrintEvaluatedVariables to True to debug the evaluation of the run condition but that does not add any additional details about run condition in the logs (which is surprising because run condition evaluation is a totally opaque operation from the point of view of details in deployment log and can actually benefit from logging).

I have also tried minor variations e.g.

#{if USER_SUPPLIED_MACHINE_NAME == #{ENVNAME[#{Octopus.Machine.Name}]}}True#{/if}

However, the condition always evaluates to False.

Also, the variables substitutions page does not have any examples for comparing two variables in “if” condition.


(Mark Siedle) #3

Hi Soumen,

Thanks for getting in touch.

If we’re understand this correctly, you’re wanting the step to only run when the step is scoped to the user-supplied/prompted machine name variable.

Is there a reason you’re not using the “Include/Exclude Deployment Targets” fields when deploying your release?

Your syntax of variable substitutions is correct. However, at the point of the step’s execution (when it is determining whether to run based on the run condition), it does not know which machines are available yet. So that Octopus.Machine.Name will not exist at the point that the run condition is evaluated for a step. The step needs to begin execution (and get past any run conditions), then it determines which machines that step should run for based on the role(s) assigned to the step.

In order to achieve what you’re after, you could approach it multiple ways.

Instead of forcing the user to enter a machine name and relying on run conditions, you could instead select the specific deployment targets when deploying your release. For example, see the “Preview and customize” section of the deployment screen:

This way, your deployment is guaranteed to only execute on the included machines.

Alternatively (if you need to keep the prompted machine variable approach), then assuming the steps you’re attempting to execute are script steps, you could write the run condition logic in script (so use it as an early-exit condition before the rest of your script). For example:

$machineName = $OctopusParameters["Octopus.Machine.Name"]
if (USER_SUPPLIED_MACHINE_NAME -ne $machineName) {
  write-host "Skipping this machine $machineName"
  Exit
}

"Running script for machine $machineName as this matches our prompted variable..."
#TODO: The rest of your script here.

But we’d definitely recommend using the “Include/Exclude Deployment Targets” fields when deploying your release if possible, but if this doesn’t suit your scenario, we’d love some more details.

In regards to specifying multiple variable run conditions, you can achieve this, but you need to use nesting:

#{if 1 == 1}#{if 2 == 2}true#{/if}#{/if}

Hope this helps.

Cheers
Mark


(Soumen Dass) #4

Hi Mark,

Thanks for the detailed reply. I did consider the deployment target inclusion/exclusion but didn’t go that route from support point of view. It is not a mandatory field that must be chosen and is mainly optional - that means the deployment initiator may miss-out/forget to select the specific target and the deployment would get executed for all targets. So this approach is technically cleaner but practically risky.

I ended up using the 2nd approach you mentioned with a variation. I created a prompted variable with list of values that are more descriptive than machine names. Then I attached same values to another variable with each value scoped to a target. Finally I just compare the values in the step template and exit early if value for target machine != user supplied value.The advantage of this approach is that a) machine names are not relevant and changing them has no bearing on the workflow b) the entries in the drop-down can be as user friendly as we want. Disadvantage is that adding a new machine requires variable value addition but that is an infrequent low-effort activity.

Any idea if there is any plans for lazy evaluation of the run condition i.e. only when the step begins to execute? That would mean I can keep my setup + avoid polluting the step templates with the comparison check.

Thanks,
Soumen


(Mark Siedle) #5

Hi Soumen,

Thanks for the additional details. We’re glad you got something working :slight_smile:

Re. Lazy run conditions. We have an existing Github issue here that I think describes what you’re looking for. But there’s no ETA on when that will be available (it’s been low on the priority list for some time now). We’d recommend adding a comment describing your scenario/use-case to that issue and that may help bump it up the priority list.

Cheers
Mark