Skip to content

Instantly share code, notes, and snippets.

@piers7
Created December 16, 2015 07:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save piers7/f637240ec8408ae6176c to your computer and use it in GitHub Desktop.
Save piers7/f637240ec8408ae6176c to your computer and use it in GitHub Desktop.
General purpose Octopus Deploy -> Install.ps1 bootstrapper
<#
.Synopsis
General-purpose Octopus Deploy boostrapper
Binds Octopus variables directly on to parameters on an install script, passing the rest as a hashtable
This means your Install script can itself have 'proper' parameters, making local testing easier
#>
param(
$entryPoint = '.\Install.ps1'
)
function GetTypeName($obj){
if($obj){
$obj.GetType().Name;
}else{
'null';
}
}
function ExpandVariables([string] $literalValue, $default){
# This will do for now
# If this becomes an issue, replace with a regex/replace
# intent here is to allow passing of Octopus variables *as strongly typed* into install script
$result = Invoke-Expression $literalValue;
if($default -and !($result)){
$default;
}else{
$result;
}
}
function WriteErrorDetails($errorRecord){
Write-Host "";
Write-Warning "$errorRecord $($errorRecord.InvocationInfo.PositionMessage)"
if($errorRecord.ScriptStackTrace){
Write-Warning $errorRecord.ScriptStackTrace;
}
if($errorRecord.Exception){
Write-Warning $errorRecord.Exception.GetBaseException().ToString();
}
}
$scriptDir = Split-Path $MyInvocation.MyCommand.Path
pushd $scriptDir;
try{
# Make sure required Octopus params are in scope
[void] (Get-Variable -Name:OctopusParameters)
Write-Host "Installing to $OctopusEnvironmentName, using $entryPoint"
# What we want to do is take in whatever Octopus passes us
# map some of it to explicit parameters on deploy.ps1
$scriptParameters = (Get-Command $entryPoint).Parameters;
# Make sure we don't grab more than we want
[void] $scriptParameters.Remove('properties');
$boundArguments = @{};
$otherArguments = @{};
foreach($item in $OctopusParameters.GetEnumerator()){
# Expand variables as required
$value = $item.Value;
if(($value -is [string]) -and ($value.StartsWith('$('))){
$value = ExpandVariables $value;
}
if($scriptParameters.ContainsKey($item.Key)){
#Write-Host -foreground Cyan $item.Key 'in installParameters';
$boundArguments[$item.Key] = $value;
}elseif($item.Key -notlike 'Octopus.*'){
# Some of those dotted variable names that Octopus passes seem to kill psake
# I think it's the ones which also have square brackets
# eg: Octopus.Environment.MachinesInRole[ordw-sql-instance]
# Kills the 'test-path variable:/$key' checks that psake does
# Since we don't use them, filter them out (ie only pass in explicit project variables)
$otherArguments[$item.Key] = $value;
}
}
Write-Host "Setting install parameters:"
foreach($item in $boundArguments.GetEnumerator()){
$typeName = GetTypeName $item.Value;
Write-Host ("`t{0} = {1} ({2})" -f $item.Key,$item.Value,$typeName);
}
Write-Host "Setting install properties:"
foreach($item in $otherArguments.GetEnumerator()){
$typeName = GetTypeName $item.Value;
Write-Host ("`t{0} = {1} ({2})" -f $item.Key,$item.Value,$typeName);
}
$lastexitcode = 0;
& $entryPoint @boundArguments -properties:$otherArguments;
# In case Install doesn't throw, explicitly bubble up exit code if needed
if($lastexitcode -gt 0){
Write-Warning "Failed: exitcode $lastexitcode";
exit $lastexitcode
}
Write-Host "Completed";
}catch{
WriteErrorDetails $_;
exit 1;
}finally{
popd;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment