Getting information back from deployment

I am using TeamCity in conjunction with Octopus deploy.

What I would like to do is to return information back to TeamCity after the deployment.

I am using the following checkbox:
Show deployment progress:
“If checked, the build process will only succeed if the deployment is successful. Output from the deployment will appear in the build output.”

Is there a way for me to return information back to TeamCity that I can then use in that context? I want to return the proper URL that I have generated for my website in Octopus Deploy back to TeamCity.

Hi, thanks for reaching out.

The easiest solution is to add a script step to your Octopus project and print out any variables that you wish to consume from Team City. The output of the script step will be saved in the Team City log file, which you can inspect in the Team City build. For example, adding a Powershell step to the Team City build with the script source of

$content = Get-Content -Path "%teamcity.agent.home.dir%/logs/teamcity-build.log"
$content = $content -join "`r`n"
Write-Host $content

will read the agent log file into a variable and then print that variable. However you would replace the code to reprint the log file with some logic to extract the output you are looking for. You can find more information on the Team City agent log files at https://confluence.jetbrains.com/display/TCD9/Agent+Home+Directory.

If you are not sure how to reference a variable in an Octopus script step, you can enable variable debugging using the instructions at https://octopus.com/docs/support/debug-problems-with-octopus-variables#DebugproblemswithOctopusvariables-Writethevariablestothedeploymentlog. By setting the OctopusPrintVariables variable to true, the Octopus log file will contain all the variables that can be consumed by the Octopus steps.

Regards
Matthew Casperson

This way you don’t have to re-add the line endings. :slight_smile:

$content = Get-Content "%teamcity.agent.home.dir%/logs/teamcity-build.log" -Raw
Write-Host $content

Can you clarify how you print out the variables in the powershell script in Octopus so that they show up in the output?

I tried:
Write-Host “https://$EXTERNAL_IIS_SITE_NAME/$OctopusParameters[“Octopus.Project.Name”]$OctopusParameters[“Octopus.Environment.Name”]”

In the Octopus log side I see:

Unpacking Calamari version 4.2.4 to ‘C:\Octopus\Calamari\Local\4.2.4’
April 2nd 2018 17:38:45
Info
Calamari upgrade successful
April 2nd 2018 17:38:51
Info
https:///System.Collections.Generic.Dictionary2[System.String,System.String][ Octopus.Project.Name]System.Collections.Generic.Dictionary2[System.String,System.String][Octopus.Environment.Name]

Nothing shows up on the TeamCity log side, though

Hi,

To print out dictionary values in a Write-Host statement, you’ll need to nest them in $() like this:

Write-Host "https://$EXTERNAL_IIS_SITE_NAME/$($OctopusParameters["Octopus.Project.Name"])$($OctopusParameters["Octopus.Environment.Name"])"

These logs should be shown in the TeamCity agent log files after you’ve added that Team City build step that Matthew mentions above. If not, could you please show us screenshots of your build process for us to investigate?

Thanks
Mark

This is very close to working.
The part that confuses me slightly is the suggested step by Matthew.
This would read my entire build log in which includes previous builds in addition to the current one.
It seems like it would be hard to parse this since there would potentially end up being multiple instances of the output.

I was able to get the output to show up in the TeamCity log output by using the progress feature of the Octo.exe create-release function, but it is just text and I don’t see a way to get the log for ONLY the current build in powershell.

Hi,

Regarding the code snippet that Matthew posted earlier … he’s on holidays currently, so I’m just filling in sorry :slight_smile:

However you would replace the code to reprint the log file with some logic to extract the output you are looking for.

I believe he’s suggesting you trim the contents of the log file to only include the output from your most recent deployment. So you’d be looking for some marker that identifies a deployment, or your step specifically, and trim from that point to the end, then just parse that (rather than the entire log file).

Alternatively, TeamCity includes a REST API that you could investigate. If it has an endpoint that allows you to update just the information you need back in TeamCity, you could consider writing a PowerShell script step in Octopus that triggers a call to the TeamCity API with the URL (that may be easier than parsing log output).

We were also wondering if this URL could be generated at build time in TeamCity and passed to Octopus, rather than Octopus having to call back to your build-server. Would that be an option you could consider?

Hope this helps.

Cheers
Mark

The idea here is that we want TeamCity to be completely ignorant about the environments as that is Octopus’ job to manage them. I don’t want to get myself into a situation where I’m having to reconcile a bunch of variables between the two sides through separate maintenance processes. It seems highly undesirable to me to have to maintain that on both sides of the equation. I’ll take a look at the API idea.

To give you some insight into what is going on here, I am trying to pass a URL of an environment that was just generated on the fly. We then run end to end tests against that URL from TeamCity. Part of how we define the name of our environment is dictated by the Environments setup in Octopus deploy. I don’t want to have to manually maintain those on the TeamCity side and then also make sure they stay in sync with the Octopus side. It isn’t flexible and is very brittle.

Hi,

If you have a script step like this in Octopus:

Then this is a rough script that will parse the build log for the last mention of a string My custom URL is.

$content = Get-Content -Path "%teamcity.agent.home.dir%/logs/teamcity-build.log"
$urlLogs = $content | Where-Object {$_ -like "*My custom URL is: *"}
if ($urlLogs -is [array]) {
  $lastRecord = $urlLogs[$urlLogs.Length - 1]
} else {
  $lastRecord = $urlLogs
}
# This is the marker that identifies the start of the custom data
$start = $lastRecord.IndexOf("My custom URL is:")
# status='NORMAL' appears at the end of the log messages, so get rid of them
$end = $lastRecord.IndexOf("' status='NORMAL']")
$length = $end - $start
$cleanedUrlString = $lastRecord.Substring($start, $length)
# This will write out the processed string
Write-Host $cleanedUrlString
# Expose the variable to Team City
Write-Host "##teamcity[setParameter name='cleanedUrlString' value='$cleanedUrlString']"

You can use $cleanedUrlString string here for whatever you need, and it has been created as a Team City parameter called cleanedUrlString as well. See https://confluence.jetbrains.com/display/TCD10/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-changingBuildParameterAddingorChangingaBuildParameterfromaBuildStepAddingorChangingaBuildParameter for details on using service messages to create parameters.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.