One reader asked in my Octo.exe deep dive if I had published how to setup continuous deployments. I had mentioned it in the deep dive and while I’d rather do a comprehensive piece to see how many different ways we could set up a continuous deployment, a simple post on how to setup continuous deployments in TFS is just as effective for the mean time. Let’s jump right in.
Whether you’re using your own TFS 2013 server or Visual Studio online (VSO), you can use the octo.exe to continuously deploy and fire off a release after your build is finished. In principle, it’s very easy to kick off a release in Octopus Deploy.
1. Create a PowerShell script and have it call the Octo.exe. Make sure to use the create-release command as it can fire off a release using the latest NuGet packages – which is of course what you want.
2. Within your CI tool of choice, execute said script after the build, test and NuGet push have executed.
Sounds pretty simple, right? It is. One of the great aspects of the octo.exe is that it doesn’t matter where the octo.exe is being called, primarily because the server and apikey parameters allows you to specify the server to create the release on any machine. This allows for a great deal of flexibility. The location of the octo.exe is mostly irrelevant however in the case of continuous deployments, the primary concern is not where the octo.exe is but a matter of when it fires.
Edit: Note that this solution is for Octopus users that are not using the built-in NuGet feed within the Octopus Deploy server. We use the NuGet.Server that’s distributed on NuGet.org within IIS on separate servers as we deal with tens of thousands of packages. If you use Octopus Deploy’s internal feed, it’s easy to enable continuous deployments (CD) per their instructions – just know that it’s referred to CD as “Automatic Release Creation“, not continuous deployments.
For TFS (and Visual Studio Online (VSO)) simplest way we do this is:
1. Create a root level folder in your solution. For my example, I’ve named it “Tools” but call it what you want.
2. Inside my “Tools” folder, add the Octo.exe (download it from the Octopus Deploy site). I’ve also copied the Octo.exe.config file into my
3. Create a PowerShell script – call it whatever you want. To be overly-obvious, I’ve named mine: CreateAndDeployNewRelease.ps1.
4. Our PowerShell script looks something like this:
$scriptpath = split-path -parent $PSCommandPath $octopath = resolve-path "#scriptpath/Octo.exe" # parameters should all be on the same line & $octopath create-release --server=https://myoctopusserver --releasenotes="Deploy triggered from CI Build for Dev environment" --project="MyProject" --deployTo="MyDevEnvironment" --apiKey=API-123456...
This code is very simple. We’re simply getting the full path of the octo.exe executable that’s within the your solution and creating a new release with the create-release option. Note, if you use create-release and don’t specify a version number, the deployment will use the latest version of the NuGet packages. Keep this in mind. This is why versioning is important – especially in Octopus Deploy.
5. Add the PowerShell script into your Tools folder within your solution. Your folder in Visual Studio should look something like this:
6. Check these changes into your TFS solution. This is very important as the file and executable need to be on the build filesystem after the build is completed.
7. Next, within your build template, under section 2. Build, sub-section 5. Advanced, look for the Post-build script path field. Note: this field may not exist within your template.

The template I’m using in this example is the TfvcTemplate.12.xaml which (I believe) is the default template for TFS 2013 servers.

You may have more templates at your disposal. As long as there is a step similar to “Post-build script path”, that should be fine.
8. Once you’ve saved your build template – any time you queue a build using said template, Octopus will be called to do a deployment. The best evidence is to typically leave a release note for the –releasenotes parameter. You’ll see your releases with that text like such:

Inside of the Release itself, you’ll see the release notes too.

Setting up continuous deployments isn’t difficult, but there are a some hurdles to overcome. There are also some possible improvements to make with this method however, it’s effective enough for a start. The first improvement that comes to mind is to have the octo.exe setup on each build server itself. Ideally, we could cut out the octo.exe being checked into each solution and come up with a standard location for PowerShell scripts to look on all build servers and execute the octo.exe. Why include it in the source if it’s going to be on a build server? Well, we have a lot of build servers and frankly, not everyone does continuous deployments. The octo.exe is small and this method works just fine for either TFS on-premise or VSO.
As far as continuous deployments are concerned, I’ve slowly had a change of heart. While continuous deployments make perfect sense, they leave a plethora of NuGet packages in your feed. Without some automated NuGet package management, NuGet packages become a problem in and of themselves to manage. If you have an automated process to keep a feed relatively clean – I’m in favor of continuous deployments. Theoretically, having hundreds or thousands of NuGet packages should not be a problem, but in our experience that depends on the NuGet server you use. Just be aware of this side effect; continuous deployments can make NuGet package management an issue for you to deal with.
I hope this helps answer the question on how to setup continuous deployments with TFS 2013/VSO and Octopus Deploy. I imagine this same process will work with TFS 2015 assuming that the default build template includes the post-build script path parameter. I’m sure there are other techniques that can provide this same level of functionality, but this approach works for us very well and translates across to Visual Studio Online. We don’t use VSO, however I have tested it using this exact method.
Leave a Reply