Skip to content

Instantly share code, notes, and snippets.

@rpresser
Forked from nshenoy/TransformOctopusConfig.ps1
Last active May 15, 2020 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rpresser/3ac793695d4755a8ad1277e2b8985f6a to your computer and use it in GitHub Desktop.
Save rpresser/3ac793695d4755a8ad1277e2b8985f6a to your computer and use it in GitHub Desktop.
<#
.Synopsis
"take in a variable JSON file from a drop target, a web.config, and a web.foo.config transform file and spit out a transformed file with the final substitutions."
.DESCRIPTION
This script is for previewing the common workflow of substituting OctopusDeploy variables within a *.foo.config transform file, then applying that transform file
to a *.config file.
.NOTES
Name: Transform-OctopusConfig
Author: Nithin Shenoy
Author: Ross Presser (commenting, modified for cmdlet use)
Version: 0.2
DateOriginal: 2016-06-09
DateUpdated: 2020-05-15
.REMARKS
Nithin Shenoy's version was delivered as a function, not a self-contained Powershell script.
Nithin Shenoy's version applied the transform to the config, then substituted variables in the output of that transform. This version does the reverse, substituting variables in
the transform then applying that to the config. This better fits ARI's workflow.
.LINK
https://gist.github.com/rpresser/3ac793695d4755a8ad1277e2b8985f6a
forked from https://gist.github.com/nshenoy/79ac16c84edcc65485dff263d1e2781f
.PARAMETER json
Path to a JSON file containing variable definitions.
.PARAMETER xml
Path to an XML file containing the original *.config.
.PARAMETER xdt
Path to an XDT file containing the *.foo.config transform.
.PARAMETER output
Path to the fully transformed output config file.
.EXAMPLE
.\Transform-OctopusConfig variables.json web.config web.release.config output-web.config
Description:
Will substitute variables from variables.json into web.release.config, then apply web.release.config to web.config, writing the result to output-web.config
#>
param(
[CmdletBinding()]
[Parameter(Mandatory=$true, Position=0)] [string]$json,
[Parameter(Mandatory=$true, Position=1)] [string]$xml,
[Parameter(Mandatory=$true, Position=2)] [string]$xdt,
[Parameter(Mandatory=$true, Position=3)] [string]$output
)
if (!$json -or !(Test-Path -path $json -PathType Leaf)) {
throw "File not found. $json";
}
if (!$xml -or !(Test-Path -path $xml -PathType Leaf)) {
throw "File not found. $xml";
}
if (!$xdt -or !(Test-Path -path $xdt -PathType Leaf)) {
throw "File not found. $xdt";
}
$xdtTemp = $xdt + ".tmp"
del $xdtTemp -ErrorAction Ignore -Force
$octopusValues = (Get-Content $json | ConvertFrom-Json)
$lines = Get-Content $xdt
foreach($line in $lines)
{
$line = substitute $line $octopusValues
$line | Out-File -filePath $xdtTemp -Append
}
transform $xml $xdtTemp $output
function transform($xml, $xdt, $output)
{
Add-Type -LiteralPath "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\NuGet\Microsoft.Web.XmlTransform.dll"
$xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
$xmldoc.PreserveWhitespace = $true
$xmldoc.Load($xml);
$transform = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt);
if ($transform.Apply($xmldoc) -eq $false)
{
throw "Transformation failed."
}
$xmldoc.Save($output)
}
function substitute($line, $octopusValues)
{
$regex = [regex] "(#\{\b[a-zA-Z0-9-_.]+\})"
$groups = $regex.Matches($line)
if ($groups.Count -eq 0)
{
return $line
}
foreach($group in $groups)
{
$octVariable = $group.Value.Trim("#{").Trim("}")
write-host "[DEBUG] group.Value:" $octVariable
Try
{
$token = $octopusValues | select -ExpandProperty "$octVariable" -ErrorAction Stop
$token = substitute $token $octopusValues
$line = $line.Replace($group.Value, $token)
}
Catch
{
Write-Host "[WARNING] Could not find value of $octVariable"
Break
}
}
return $line
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment