Using Sitecore TDS with Azure Pipelines

Sitecore TDS allows developers to serialize Sitecore items into a file format which enables them to be stored in source control. These items can then be turned into a Sitecore update package to be deployed into a Sitecore solution.

With tools like Team City it was possible to install the TDS application on the server, and MSBuild would pick it up in the same way that Visual Studio would when you create a build locally. However, with build tools like Azure Piplelines that are a SAAS service you do not have any access to install components on a server.

If your solution contains a TDS project and you run an Azure Pipeline, you will probably see this error saying that the target ‘Build’ does not exist in the project.

Fortunately, TDS can be added to a project as a NuGet package. The documentation I found on Hedgehogs site for TDS says the package is unlisted on NuGet.org but can be installed in the normal way if you know what it’s called. When I tried this is didn’t work, but the NuGet package is also available in the TDS download so we can do it a different way.

Firstly download TDS from Hedgehogs website. https://www.teamdevelopmentforsitecore.com/Download/TDS-Classic

Next create a folder in the root of your drive called LocalNuGet and copy the nuget package from the download into this folder.

Within Visual Studio go to Tools > NuGet Package Manager > Package Manager Settings, and in the window that opens select Package Sources on the left.

Add a new package source and set it to your LocalNuGet folder.

From the package manager screen select your local nuget server as the package source and then add the TDS package to the relevant projects.

When you commit to source control make sure you add the hedgehog package in your projects packages folder. Normally this will be excluded as your build will try and restore the NuGet packages from a NuGet feed rather than containing them in the repo.

If you run your Azure Pipleine now you should get the following error:

This is a great first step as we can now see TDS is being used and we’re getting an error from it.

If you’re not getting this, then open the csproj file for your solution and check that there are no references to c:\program files (x86)\Hedgehog Development\ you should have something like this:

<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\HedgehogDevelopment.TDS.6.0.0.10\build\HedgehogDevelopment.TDS.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\HedgehogDevelopment.TDS.6.0.0.10\build\HedgehogDevelopment.TDS.targets'))" />
  </Target>
  <Import Project="..\packages\HedgehogDevelopment.TDS.6.0.0.10\build\HedgehogDevelopment.TDS.targets" Condition="Exists('..\packages\HedgehogDevelopment.TDS.6.0.0.10\build\HedgehogDevelopment.TDS.targets')" />

To fix the product key error we need to add our license details.

Edit your pipeline and then click on the variables button in the top right. Add two new variables:

  • TDS_Key – Which should be set to your license key
  • TDS_Owner – Which should be set to the company name the key is linked to

Now run your pipleline again and the build should succeed

Team Development for Sitecore (TDS) with Github

If your using Team Development for Sitecore (TDS) and Github or Git as your source control you may experience an issue where TDS is unable to create/update some of the items in Sitecore, due to a content length issue.

The error will look something like this:

Failed to load version 1 for language en
Length of field content does not match the content-length attribute. File name: name, field id: {id}

What’s happening comes down to how Github encodes line ending. If your item contains a Rich Text field you can end up with data that has been serialized with both CRLF and LF as the line feed. This will have been included in the content length. However when you push to Git, the CRLF value will have been removed making the content length value incorrect.

To overcome this issue you need to update your .gitattributes file to treat these files differently. Just add this to your file:

# TDS files should be treated as binary
*.item -text

How do I create a .gitattributes file?

If you don’t have a .gitattributes file you may run into an issue with windows where it won’t let you create it, due to requiring a file-name rather than just an extension.

To create the file:

  1. Create the text file gitattributes.txt
  2. Open it in a text editor and add your rules, then save and close
  3. Hold SHIFT, right click the folder you’re in, then select Open command window here
  4. Then rename the file in the command line, with ren gitiattributes.txt .gitattributes

Alternatively you can download my .gitattributes file here

Sitecore Continuous Integration with Team City and TDS

CIProcess

There are a lot of articles around on how to do automated deployments / continuous integration with Sitecore, which if you’re new to the tools will likely leave you slightly baffled. This article will hopefully show you exactly what you need to do and explain why.

Solution Overview

  1. TDS is used by developers to serialize their Sitecore item changes and push them into source control
  2. Team City is used to detect the changes and run a build script
  3. Team City uses Web Deploy to push the code changes to the web server
  4. Team City calls MSBuild which will trigger TDS which is installed on the server to deploy Sitecore items to the destination server

Prerequisites

  • You have a build server with Team City installed and know how to set it up to do a web deploy
  • You are already using TDS and have your Sitecore items serialized in source control
  • Essentially you know how to do the first 3 steps and just need help with Step 4

Step by Step

UNC Share

On your web server you need to set up a UNC Share on your website’s folder. When TDS does a deploy it will install a web service on your website through this share, do the item deployment and then remove the web service again.

The share needs to give permission to the user that your Team City Build Agent runs as. To find out which user your Build Agent is using:

  1. open the list of services and find TeamCity Build Agent in the list
  2. right click and select “Properties”
  3. in the “Log On” tab you will be able to see which Windows User is being used

Team City Config

In your Team City’s build configuration settings for your project, add a new build step with the following config:

Runner Type: MSBuild
Step Name: Publish TDS Items (or some other identifier)
Build file path: Path to your projects .sln file
Command line parameters:

  • SitecoreDeployFolder: TDS will use this file path to install a web-service on your site to publish the items through.
  • SitecoreWebUrl: This is the url of the site you are going to update. TDS will use this when it tries to call the web service it installed.
  • IsDesktopBuild: false
  • GeneratePackage: false
  • RecursiveDeployAction: Delete
/p:IsDesktopBuild=false;GeneratePackage=false;RecursiveDeployAction=Delete;SitecoreWebUrl=URL OF SITE;SitecoreDeployFolder=&quot;UNC PATH TO YOUR SITECORE SITE&quot;

Setting the command line parameters here will take precedence over any that have been included in your TDS projects solution file (which are liable to be overwritten by a developer).

TDS Build Settings

That’s it!

It’s that easy. If you run your build script now your items should all be published to Sitecore.

Alternatives

This certainly isn’t the only way to setup automated deployments and nor is it without issues. The fact a share needs to be set up between the Web Server and the Build Server, could cause an issue with security and may just not be possible if you’re using a cloud server.

Rather than using TDS to deploy the Sitecore items you could use TDS to create a .update package. These would normally be installed through an admin webpage (not great for CI) but there is an open source project called Sitecore Ship that will expose a REST endpoint for the package to be posted to. Brad Curtis has written an excellent guide to this setup here (http://www.bradcurtis.com/sitecore-automated-deployments-with-tds-web-deploy-and-sitecore-ship/), however at the time of writing Sitecore Ship isn’t compatible with Sitecore 7.5 or 8.

Another alternative to installing the update package is to use the TDS Package Installer. This is a tool Hedgehog provide alongside TDS for installing the update package. In this scenario you would need the tool installed on your web server and some way to call it. Jason Bert has written a setup guide for this example (http://www.jasonbert.com/2013/11/03/continuous-integration-deployment-with-sitecore/) however as well as Team City, you will also need Octopus Deploy to call the package installer. Octopus Deploy works by having what it calls Tentacles on each server you deploy to, making it easy to set up scripts to call programs on that server.

Sticking with the example using just TDS, you could also use TDS to deploy the solutions files as well as Sitecore items rather than using Web Deploy. However the downside here is that TDS is unable to modify your Web.Config file, which is one reason to stick with Web Deploy.