Need deployment path and application approach for custom step template

Greetings,

I am building a custom step for our build. The build contains three .NET ASP deployment steps. The custom step I am building is to verify the final transformed values set in the web configs. I have PowerShell set to do the checks, what I am not sure about is the best approach to use the custom step. The difficulty comes in determining where to execute the step (child or not) and accessing the actual deploy location of each of the deploy steps.

If I setup the step as a child with each of the deploys, which system variable do I use to access the installation directory path? Is it still this: Octopus.Action[name].Output.Package.InstallationDirectoryPath or is there another, more specific variable available?

If I setup the step at the same level (not using child steps) and after the deployment steps, will have access to the installation directory paths of all three of my deployment steps? I found this variable, Octopus.Action[name].Output.Package.InstallationDirectoryPath. It isn’t clear from the documentation, is "Action[name] the step name (where name is the name of the deployment step), or something else? Would I be able to iterate over all the available InstallationDIrectoryPath’s from the current deployment run so name doesn’t need to be explicitly set?

My last question is one of advice. As this is the first custom step template I am building I want to make sure I am going about this the correct way. As I think over this more, it appears using the custom step in a child step with the deployment step is NOT a good approach. To me it seems having the custom step run after all deployment steps run is the better approach. If any of this makes sense to you please let me know your opinion on the best approach.

Hi,
From what I understand you are trying to loop over all the installation directories at the end of your deployment so that you can perform some extra processing? If that is the case then you can use the variable substitution syntax to loop over all the actions as follows.

function DoStuff { param( [string]$Action, [string]$InstallPath )
 if($InstallPath.StartsWith("##{")) {
    Write-Verbose "No Installation path was substituted, probably not an installation step"
    return
 }
    Write-Host "I Will Use $InstallPath For $Action"

}

# The following will loop over all actions
#{each step in Octopus.Action}
 DoStuff -Action "#{step}" -InstallPath "#{step.Output.Octopus.Action.Package.InstallationDirectoryPath}"
#{/each}

Notice that since the variable uses the index notation (Octopus.Action[_stepname_]...) you can use the each keyword to loop over each one. Since this loop will include the script step itself (and any other steps you have in the deployment), the DoStuff function does a quick check to make sure the InstallationDirectoryPath variable has been substituted. If not then the value of InstallPath in that function will be the un-substituted variable string. In this way you wouldn’t need to hard-code the list of step names but automatically loop over all of them.

I’m not entirely clear on your last question however. If you have several child steps that involve deployments and all run on the same machine, I see no reason you couldn’t include the above script step at the end of the children steps, as this would doubly ensure that it runs on the same machine as those where the deployment took place. Could you please clarify if it looks like I’m misunderstanding the problem that you are seeing?

I hope this deploy gives you some tips on how to move forward with your deployment. Let me know if I can be of any further assistance.
Cheers,
Rob

Thank you. Useful but still a little confusing as there is a lot going on during a deployment.

So if I use this each loop, it will loop through every machine in every step as well?

# The following will loop over all actions
#{each step in Octopus.Action}
 DoStuff -Action "#{step}" -InstallPath "#{step.Output.Octopus.Action.Package.InstallationDirectoryPath}"
#{/each}

I hadn’t considered all the different machines before. Probably because if it is wrong for one it will be wrong for all of them.

From what I understand you are trying to loop over all the installation directories at the end of your deployment so that you can perform some extra processing?

Yes, that is exactly it. So based on that need, am I better using the step once or adding it to a child step with the deployment step? I currently don’t use any child steps but will use them if it a better way to approach this.

The script step will run on whatever machines you scope that step role to. The variables for the action output variables will then be automatically scoped to that machine.
To work see what variables are available, I would advise try running the deployment with OctopusPrintEvaluatedVariables and OctopusPrintVariables variables set to True as defined in the docs. All the variables will then be printed to the logs.
I see no reason why you couldn’t include this step once per deployment, and have it run on all the relevant machines where the deployments are taking place. Give it a try and let me know if you run into any difficulties. Sometimes the best way to solve these sorts of problems is through trial and error, tweaking of the scripts bit by bit.
Cheers,
Rob

Thank you Rob,

I was trying to avoid unnecessary trail and error if a known/recommended approach is already known. Thank you for the OctopusPrintEvaluatedVariables information, that will be helpful.

Thank you for your time and assistance,

Brett

Hi,
Assuming that you also saw a CustomAppInstallDirectory = 'C:\blah\blah', then yes it should replace with the real value when a deploy runs.
Cheers,
Robert