Skip to content

Instantly share code, notes, and snippets.

@michaelnoonan
Created January 16, 2013 01:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save michaelnoonan/4543891 to your computer and use it in GitHub Desktop.
Save michaelnoonan/4543891 to your computer and use it in GitHub Desktop.
Deploying releases using Octopus Deploy from TeamCity
param
(
[string] $EnvironmentName,
[string] $Version,
[string] $ProjectName,
[string] $OctopusApiKey,
[string] $OctopusServerUrl,
[string] $ReleaseNotes
)
Add-Type -Assembly System.ServiceModel.Web,System.Runtime.Serialization
$libPath = (Split-Path -Parent $MyInvocation.MyCommand.Definition)
. $libPath\OctoLib.ps1
$OctoExecutable = Join-Path $libPath -ChildPath "Octo.exe"
# ensure Octo.exe exists
if (-not (Test-Path -Path $OctoExecutable)) {
Throw "$OctoExecutable does not exists.";
}
$baseUrl = $OctopusServerUrl
if ($OctopusServerUrl.EndsWith("/")) {
$baseUrl = $OctopusServerUrl.Remove($OctopusServerUrl.LastIndexOf("/"), 1)
}
# run deployment and wait for it to finish
$node = Get-ProjectNode $baseUrl $ProjectName
$releasesRelativeUrl = $node.Links.Releases.InnerText
$deployedReleases = Get-DeployedReleaseVersions ($baseUrl + $releasesRelativeUrl)
if ($deployedReleases.Length -gt 0) {
$result = $deployedReleases | ? { $_ -eq $Version }
if ($result) {
Deploy-OctopusRelease $OctoExecutable $OctopusServerUrl $EnvironmentName $OctopusApiKey $ProjectName $Version
} else {
Create-OctopusRelease $OctoExecutable $OctopusServerUrl $EnvironmentName $OctopusApiKey $ProjectName $Version $ReleaseNotes
}
} else {
Create-OctopusRelease $OctoExecutable $OctopusServerUrl $EnvironmentName $OctopusApiKey $ProjectName $Version $ReleaseNotes
}
# check if deployment succeeded
$releaseNode = Get-ReleaseNode $baseUrl $releasesRelativeUrl $Version
$releaseDeploymentsRelativeUrl = $releaseNode.Links.Deployments.InnerText
Ensure-LastDeploymentSucceeded $baseUrl $releaseDeploymentsRelativeUrl
function Get-ProjectNode {
param
(
[string] $baseUrl,
[string] $projName
)
$projectsRelativeUrl = "/api/projects"
$xml = Get-XmlData ($baseUrl + $projectsRelativeUrl)
$nodes = $xml.SelectNodes("//item")
$nodes | ? { $_.SelectSingleNode("Name").InnerText -eq $projName }
}
function Get-DeployedReleaseVersions([string] $url) {
$xml = Get-XmlData ($url)
$xml.SelectNodes("root/item/Version") | % { $_.innertext }
}
function Get-ReleaseNode {
param
(
[string] $baseUrl,
[string] $releasesRelativeUrl,
[string] $version
)
$xml = Get-XmlData ($baseUrl + $releasesRelativeUrl)
$nodes = $xml.SelectNodes("root/item")
$nodes | ? { $_.Version.InnerText -eq $version }
}
function Ensure-LastDeploymentSucceeded {
param
(
[string] $baseUrl,
[string] $deploymentsRelativeUrl
)
$xml = Get-XmlData ($baseUrl + $deploymentsRelativeUrl)
$nodes = $xml.SelectNodes("root/item")
$status = "Failed"
# Note: we are using the status of last deployment to determine if deployment succeeded or not
$nodes | foreach {
$taskRelativeUrl = $_.Links.Task.InnerText
#$_.Links.Task.InnerText
$taskXml = Get-XmlData ($baseUrl + $taskRelativeUrl)
$status = $taskXml.SelectSingleNode("//State").InnerText
#$status
}
if ($status -ne "Success") {
throw "Deployment failed."
} else {
Write-Host "Deployment succeeded." -ForegroundColor Green
}
}
function Create-OctopusRelease {
param
(
[string] $octoExecutable,
[string] $serverUrl,
[string] $environment,
[string] $apiKey,
[string] $projName,
[string] $version,
[string] $releaseNotes
)
Write-Host "Creating and deploying '$projName' to '$environment'..."
& $octoExecutable create-release --server=$serverUrl --project="$projName" --deployto=$environment --apiKey=$apiKey --version="$version" --releasenotes="$releaseNotes" --waitfordeployment --force | Write-Host
Write-Host "Completed deployment."
}
function Deploy-OctopusRelease {
param
(
[string] $octoExecutable,
[string] $serverUrl,
[string] $environment,
[string] $apiKey,
[string] $projName,
[string] $version
)
Write-Host "Deploying '$projName' to '$environment'..."
& $octoExecutable deploy-release --server=$serverUrl --project="$projName" --deployto=$environment --apiKey=$apiKey --version="$version" --waitfordeployment --force | Write-Host
Write-Host "Completed deployment."
}
function Get-XmlData {
param
(
[string] $url
)
$webClient = New-Object System.Net.WebClient
$webClient.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$data = $webClient.DownloadString($url)
$webClient.Dispose()
if (-not $data) {
throw "Error retrieving Json data from $url"
}
$xml = [xml] (Convert-JsonToXml $data)
$xml
}
function Convert-JsonToXml([string]$json) {
$bytes = [byte[]][char[]]$json
$quotas = [System.Xml.XmlDictionaryReaderQuotas]::Max
$jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($bytes,$quotas)
try {
$xml = new-object System.Xml.XmlDocument
$xml.Load($jsonReader)
$xml
}
finally {
$jsonReader.Close()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment