TeamCity, Octopus, and automated deployments (Artifacts not ready in time)

Hi,

I have setup TeamCity 7 to automatically build and publish artifacts. This works fine.

As part of my build step, I have a ‘Create Release’ build step:

create-release [omitted for brevity] --version=%build.number% --packageversion=%build.number% "--releasenotes=Automatic release created from TeamCity. Git version %custom.branch% / %build.vcs.number.1%"

This is supposed to create a release on Octopus Deploy when the build has succeeded.

Unfortunately, this does not work because we try and create the release (for the being-built build) before the build has finished (or at least published the artifacts). Octopus cannot see this build (yet) in the NuGet feed from TeamCity.

  1. How am I supposed to automatically create a release from this build on Octopus Deploy, using TeamCity?
    There does not seem to be a way to run a build step after the NuGet feed (hosted by TeamCity 7 server) publishes the package for Octopus to consume.

  2. I tried using http://confluence.jetbrains.net/display/TCD7/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-PublishingArtifactswhiletheBuildisStillinProgress which publishes the artifacts earlier; however the NuGet feed is not updated, so this fix is not helpful

I want to automate deployments to a testing environment using this setup. I am nearly there; except for this problem.

Anyone have any ideas or experience in this area?

Cheers,
Andrew

Hi Andrew,

I’ve done this by using two build configurations:

two build configs

Build configuration 1 compiles, tests, and creates a NuGet package

config 1

Build configuration 2 will then use octo create-release via a command line task.

config 2

I then set up a build trigger so that build configuration 2 runs when build configuration 1 finishes.

Hope that helps,

Paul

Hmm, that kind of sucks to have to create 2 builds. I have many builds and deploys. I’ve just started to convert all the deployments into octo and have run into this issue. It seems like Octo should have a switch to not verify the nuget package. Then you can use the packageversion switch to tell it what version.

Thanks Paul.

I was wondering whether we could remove this dependency, and have the Create-Release command accept a ‘Delayed Attempt’ flag, or something, so Octopus receives the deployment job for Version X (which is still being built), and will deploy it when it is made available?

It’s very strange TeamCity have no post-build-complete hook point!

I like that idea, delayed release creation. I believe the deployment is actually a job, no reason the release creation couldn’t be a job as well.

I’m still thinking about this. I really don’t want multiple build configs.

I’m considering having a build step fork an executable that sleeps for 30 seconds at the end (the ran executable by TeamCity will return immediately, to not let the build block).

When 30 seconds have passed, just do the create-release command, as it (should be) ready by now, but thats a bit hacky.

I fixed this (good enough for now) by:

  1. Making a DelayRun script: https://github.com/Plasma/DelayRun
  2. Added a Command Line build step to the end of my TeamCity build steps (see below)
  3. When the DelayRun script runs, it forks itself and returns immediately (so the build step passes in TeamCity immediately). We then wait (as per below) 60 seconds, then run the create-release command.

The 60 seconds seems to be a good enough enough time between when TC finalizes the build (right after the DelayRun command returns after forking), prepares the artifacts and publishes them to the nuget feed.

When the create-release ends up running, the build has had time to have its artifacts published to the nuget feed so Octopus can see them.

Command Line Script:

fork 60 c:\utils\octo.exe create-release %octo.initparam% %octo.extra% --version=%build.number% --packageversion=%build.number% "--releasenotes=Automatic release created from TeamCity. Git version %custom.branch% / %build.vcs.number.1%"

Where:

  • %octo.initparam%: Is defined as “–project=project in Octopus” --server=… -apikey=…
  • %octo.extra%: Is blank (or --deployto=…) on a per-configuration basis
  • %custom.branch%: Marks the custom branch being checked out (eg, master, develop, …)

I hope this is helpful to someone get setup easier.

Ideally Octopus would check for new builds (as Paul suggested in chat) and automatically deploy based on configuration options.

Awesome idea! I took it one better and built it into Octo itself. Just add a --delay=00:01:00 flag and it will do the same thing that your program did.

Paul, let me know if you want a merge request. Attached is a build with the flag added.

Octo.zip (386 KB)

Thanks Paul!

As a side note; I’ve just noticed a problem with all three of our solutions.

When using Git, I pushed 3 changes (say A, B and C, with C being the latest) to the central server.

TeamCity executed a build for the latest of the 3 changes (change C), and ran the deployment step as expected - all good.

What isn’t good, is that TeamCity then went and ran the build process for the two builds prior (A, B) to the latest one ©.

This just meant that right now TeamCity told Octopus to deploy the release for Version B (and soon to be Version A), instead of leaving it at Version C (the latest)!

Eeek!

Is there a way to overcome this limitation, ideally TeamCity shouldn’t run the deployment step if its not running the latest source release (and is merely backdating missed revisions that have only now been pushed).

Hi Andrew,

In the TeamCity Build Triggers section, I suspect you have a VCS trigger already which is what causes the build to run on check in.

Inside the VCS trigger, there’s an option: “Trigger a build on each check in” - this should be OFF .

When I do a push containing 5 git commits, I only get one build (thanks to this setting) instead of 5 builds.

Paul

Paul, that was the problem, thank you!

I had this same problem even though I am using 2 build configs just like Paul mentions. The problem stems from the fact that my build produces 24 NuGet packages as artifacts totaling about 275MB. When the build finishes those artifacts have to be transferred from the build agent back to the build server and then published to the TeamCity NuGet feed. I solved the problem using a delay also however, rather than forking off and returning success to the build server immediately, I built the delay right into my Command Line build step like this:

@@@
echo Sleep for 30 seconds to ensure latest version of packages have been published.
ping -n 30 127.0.0.1 > null
@@@

This just pings local host 30 times and pipes the output to null creating a 30 second delay before the next command is run. The next command, of course, is my call to Octo.exe to create the release. The advantage of this method is that any output from Octo.exe is included in my build log and if the Octo.exe call fails it will fail my build and TeamCity will notify me. I also make use of the -waitfordeployment flag so that if the deployment fails it will fail my build step and I will get a notification from TeamCity and I can even use the TeamCity feature to automatically retry a failed build to retry the deployment.

-Jeff

i have made use of --deployat to schedule my build a couple of minutes after deployment - not a perfect solution, but it works.