Automating Sitecore Deployments with TeamCity and TDS
During development, your team makes a lot of changes to fields, templates, presentation details, and various other elements that need to be tracked, verified, and deployed. You need a way to source control those database changes, and then make them available to your team to test. Here’s how to accomplish that using TeamCity and Team Development for Sitecore (TDS)!
Sitecore content items in source control
Our teams use Team Development for Sitecore from Hedgehog Development to create .NET TDS projects to source control the changes we make in the Sitecore database. There’s a great guide from Hedgehog to start with, and I’ve also just written a post on some project configuration basics.
Automating deployments of Sitecore content items
With your content items now in Source Control, you can start getting your database changes deployed along with your build.
Note: This assumes you are automating your file deployments to push code changes out to your environments. If you aren’t yet, you should be! Look for my upcoming posts on setting up deployment build configurations.
In order to get TeamCity to be able to deploy, there are a few things you need:
- Install TDS. The TDS software needs to be on the build server where TeamCity is installed. This does not require an additional license to be purchased as Hedgehog allows your build server to be covered under your existing developer licensing. (Check their FAQs for details).
- Configure Build Settings. Your TeamCity build configuration needs a few parameters in order to ensure the content items are deployed to your review environment.
- SitecoreWebUrl: This specifies the URL of the website you want to update. For example: http://dev.mydomain.com.
- SitecoreDeployFolder: This specifies the UNC path where the Sitecore website folder is located. You should set up a share to push to if the website folder is on a network server separate from the build server (recommended!). For example: //mydevserver/Website
Your Command line parameters on your build step should look something like this:
/p:IsDesktopBuild=false;GeneratePackage=false;RecursiveDeployAction=Delete;SitecoreWebUrl=http://dev.mydomain.com;SitecoreDeployFolder="\\mydevserver\Website"
Publishing after deployment
There are several ways to accomplish this, including using Sitecore Rocks, but we have done this by setting up an ASPX on our internal Sitecore sites to execute a publish. The build configuration has a step with a Powershell call to trigger this. Using TeamCity build steps you can configure a trigger using a Powershell call to the publishing page.
TeamCity Configuration
The configuration for TeamCity uses an additional build step after you’ve deployed files and TDS:
- Runner Type: Powershell
- Step name: Trigger Publish to Web DB
- Powershell run mode: x64
- Working Directory: [no value]
- Script: Source code
- Script Source:$r = [System.Net.WebRequest]::Create(‘http://mywebsite/SomePath/Publish.aspx’); $resp = $r.GetResponse();
- Script execution mode: Put script into Powershell stdin with “-Command -” arguments
Publish.aspx
The code for our Publish page is something like this:
string full = Request.QueryString["full"];
// Set up the publish mode
PublishMode publishMode = PublishMode.Smart;
if (!string.IsNullOrWhiteSpace(full) && (full == "1" || full.Equals("true", StringComparison.InvariantCultureIgnoreCase)) ) {
publishMode = PublishMode.Full;
}
using (new Sitecore.SecurityModel.SecurityDisabler()) {
//We need the target database
var webDb = Sitecore.Configuration.Factory.GetDatabase("web");
//source db
var masterDb = Sitecore.Configuration.Factory.GetDatabase("master");
try {
foreach (Language language in masterDb.Languages) {
//loops on the languages and do a full republish on the whole sitecore content tree
var options = new PublishOptions(masterDb, webDb, publishMode, language, DateTime.Now)
{RootItem = masterDb.Items["/sitecore"], RepublishAll = true, Deep = true};
var myPublisher = new Publisher(options);
myPublisher.Publish();
}
}
catch (Exception ex) {
Sitecore.Diagnostics.Log.Error("Could not publish the master database to the web", ex);
}
}
But I don’t use TeamCity?
The concepts above can apply to almost any build server, be it Jenkins, TFS, or other. In an upcoming post I’ll discuss how to configure this for TFS.
Hi Jason,
You said that TDS should be installed on the build server. If you use Jenkins on a Unix machine, how could this possibly work?
gr,
Robbert
HI Jason,
I’ll be installing a Jenkins Windows version and will continue from there to get this to work with TDS
Robbert, as you may have already guessed, Hedgehog doesn’t support Unix build servers for TDS at this time. I’ve confirmed this with Hedgehog support, and they mentioned that they have several clients working successfully with Windows versions of Jenkins.
You have inspired me, though, to learn a little more about Jenkins and make a post in the future about how to configure TDS with Jenkins!
Hi Jason,
That would be great! Looking forward to it! Great info bydaway! This post finally did trigger me to explore TDS some more. Would also love to see GIT as version control, how that works all together 😉 So you’ve got something to do….
gr,
Robbert
I also don’t use teamcity but after reading your article i was decided i surely install TDS it’s to useful for my developing way.
Interesting article. How do you manage versioning of content in production? Also, if you don’t deploy content to production then how do you manage new content and do you deploy all your templates every time you do a production release?
Deployments to production and version control are often something I recommend based on the clients specific team setup and how operations will be handling their applications. For the most part, content versioning is already present in Sitecore so I’m not worried about the website content itself. So long as new versions are created and go through workflow, Sitecore will handle everything. Templates without versions are a different problem (same for Sublayout definitions).
For a small group where IT is usually still owning the templates, I usually advise having TDS manage some sample website content for a DEV/QA purpose, but excluding these items from deploys to production. The Templates and Sublayouts can still remain under development control and are part of standard deployments to production. This allows for the development team to keep a tight integration between their solution that is being deployed and the templates/sublayouts that map to their solution.
For a larger organization where template editing is encouraged to be distributed to an eComms or website administration team outside of IT, even templates cannot be deployed (which really hampers automated deployments to production of new features). In these cases, templates and sublayouts should be deployed with packages, along with the new code.
The problem we have is although the development team owns the templates the QA team tests against the final content not sample content. QA and BA are very reluctant to learn Sitecore. They just treat it as a black box website.
But, regardless the business units in my organisation who make content changes like to do the content in DEV/QA so that they don’t have to do it all at once in production when the code and templates are updated.
And of course they don’t like redoing the changes in prod in case there are other changes in prod which will be overridden if we deploy a package from QA.
One of the ways we’ve tried is to have a change freeze on content but for long running projects this isn’t practical.
Field level changes rather than item level would fix this issue I think.
If someone makes a change to field 1 in production and then someone else makes a change to field 2 of the same item except in QA as part of a code update then when the updates are made from QA to prod both changes are preserved.
@jonathanparker: Unfortunately, there is no way to automate around a bad process. In your situation, I would recommend the following:
1. Smaller batches. Reduce the size of a shippable unit and you’ll be able to get your content from QA to Production faster, meaning you won’t have to worry about the change freeze.
2. Packages for brand new content. If you have brand new stuff in QA that needs to go to production, package that up and deploy it.
3. Template standard values. If you are using TDS to deploy your templates, new fields will be auto-populated with the standard values on the template. This allows you to easily deploy certain types of fields to production with preset values which can then be altered in production if necessary.
4. RAZL. I haven’t used RAZL much yet, but Hedgehog’s RAZL tool is intended to allow you to compare two databases and then push content much like you would with TDS comparing a project to a database. This will make it easier to do merges.
5. TDS as a poor man’s RAZL. You can use your TDS project to pull a bunch of content from QA to your project temporarily, then change the target to production and push with TDS manually. This will allow you to do merges which can’t be done with the automated deploy.
Is there a way to disable TDS deploys and package generation on CI builds. I just want to build the code after a check-in and see if there are any build errors, and want to just disable TDS deploys/package generation for those builds.
You can set up a new build configuration (let’s say “Compile Only”) and in the configuration manager you can uncheck your TDS projects for both ‘Build’ and ‘Deploy’.
If you need to keep the same build configuration, I usually use MSBuild arguments like the following to keep it from pushing items. It generates the package, but won’t push to your target:
/noconsolelogger /p:VisualStudioVersion=12.0;IsDesktopBuild=false;GeneratePackage=true;SitecoreWebUrl="";SitecoreDeployFolder=""