In my first blog post I am going to describe my approach to setup a Jenkins job to remotely synchronize Sitecore items with Unicorn. In my setup I used Unicorn 3.3 with Jenkins 1.580.1.

Jenkins

Jenkins is an open source server application that can be used to automate all sorts of tasks such as building, testing and deploying software. Jenkins is a powerful application that allows continuous integration and continuous delivery of projects, regardless of the platform you are working on.

Unicorn

Unicorn is an open source application for Sitecore that makes it easy for developers to keep in sync and deploy Sitecore items between Sitecore instances. Unicorn offers two options for automated deployment of item changes: using Transparent Sync or using its Automated Tool API. The Transparent Sync feature, when enabled, uses a data provider to map serialized items stored in the file system directly into the Sitecore content tree, completely bypassing the database. The Automated Tool API allows to invoke Unicorn commands from a script.

In my setup I am using the Automated Tool API because I wanted my synced Sitecore items to be stored in the database at all times. Another reason to keep in mind when choosing between the Transparent Sync and the Automated Tool API is that the Transparent Sync doesn’t follow the normal sync process, skipping the execution of any customization associated with the sync process, like the Auto Publish processors hooked to the sync event pipelines.

Setup Steps

The following steps describe the setup process of Unicorn and Jenkins to execute a remote sync using robocopy, NAnt and a custom Powershell script.

Step 1 – Configure Unicorn Parameters

In my setup I decided to use NAnt to parameterize the Unicorn configuration files. In particular I created the following three NAnt properties:

  • Unicorn.EnableDataProvider – To enable/disable the Unicorn.DataProvider.config configuration file.
  • Unicorn.EnableSitecoreAlerts – To enable/disable the Unicorn.Deployed.config configuration file.
  • Unicorn.SharedSecret – To set the shared secret (more than 30 characters long!) used by the Automated Tool API.

The DataProvider configuration should be disabled in any environment that is not a development environment. The Deployed configuration should be enabled on a deployed environment, to alert content editors and developers when an item is synced and managed with Unicorn.

For the Shared Secret, I preferred to use a parameter to manage it, because the shared secret is stored in the Unicorn.SharedSecret.config file, but it is also passed as an input parameter to the PowerShell script responsible to invoke the Unicorn sync.

Step 2 – Configure the Unicorn Powershell Script

Unicorn provides a PowerShell module to invoke the sync via its API. This module and its supporting files can be copied from the Unicorn Git repository in the doc\PowerShell Remote Scripting folder. In my setup, I extended the provided sample.ps script to introduce input parameters (the Shared Secret and the Unicorn Control Panel url) and to manage any execution failure to return an exit code different than zero. This last modification was required by Jenkins in order to make the job fail when the sync fails.

This is my custom PowerShell script code:

param([string]$ControlPanelUrl,[string]$SharedSecret)

$ErrorActionPreference = 'Stop'

if(!$SharedSecret)
{
    Write-Host "Shared Secret parameter cannot be empty!"
    Exit 1
}

if(!$ControlPanelUrl)
{
    Write-Host "Control Panel Url parameter cannot be empty!"
    Exit 1
}

$ScriptPath = Split-Path $MyInvocation.MyCommand.Path

Try
{
    Import-Module $ScriptPath\Unicorn.psm1

    # SYNC ALL CONFIGURATIONS
    Sync-Unicorn -ControlPanelUrl $ControlPanelUrl -SharedSecret $SharedSecret

    Write-Host "Unicorn sync completed!"
}
Catch
{
    Write-Host "Encountered an error while syncing."
    Exit 1
}

Step 3 – Create a NAnt Target

I decided to execute my custom PowerShell script, called sync.ps1, using a NAnt target. In this way I could pass the Unicorn NAnt variables (described in Step 1) as input parameters for my custom PowerShell script. This is the XML code of the unicorn NAnt target that I created:

<target name="unicorn" description="Runs the Unicorn powershell script to sync items">
    <echo message="Running unicorn sync..." />
    <exec program="powershell" verbose="true" workingdir="${dir.tools}\Unicorn" failonerror="true">
        <arg value="-executionpolicy"/>
        <arg value="bypass"/>
        <arg value="-File"/>
        <arg value="sync.ps1"/>
        <arg value="-ControlPanelUrl"/>
        <arg value="http://${Website.Hostname}/unicorn.aspx"/>
        <arg value="-SharedSecret"/>
        <arg value="${Unicorn.SharedSecret}"/>
    </exec>
</target>

Step 4 – Setup Jenkins Job

There are 3 main steps that I needed to create in my Jenkins job in order to execute a remote Unicorn synchronization.

Step 4.1 – Robocopy of Serialized Files in Unicorn Serialization Folder

alt text

This first step is configured using an Execute Windows batch command build step. Here Robocopy takes care of copying all serialized files in source control from the Jenkins job workspace to the Unicorn serialization folder on the destination deployed environment. By default this folder is called Unicorn and located in the Data Sitecore folder.

robocopy web\Data\Unicorn \\destination_server\inetpub\wwwroot\deployed_instance\Data\Unicorn /E /PURGE /S

This particular syntax sets robocopy to copy files in the source directory (web\Data\Unicorn) and in any subdirectory (/S), including empty directories (‘/E’). It will also delete destination files and directories that no longer exist in the source (/PURGE'). The /PURGE copy option helps solve the problem of deleting Sitecore items that are deleted from the code repository or items that are removed when performing a code rollback.

Step 4.2 – Web Page Request of the Deployed Instance

If new code has been deployed or not on the destination server, it is a good practice to verify that the deployed instance is up and running correctly, before executing any post deployment task. In my setup I decided to perform a check on the deployed instance and verify that the website homepage (or any other page) is not returning an error, executing a simple web page request using cURL in an Execute Windows batch command build step.

"C:\Program Files\cURL\bin\curl" -s -I --max-time 900 http://your_instance_domain/

Step 4.3 – NAnt Target Execution

alt text

The final build step is an Execute NAnt build step and it is used to execute the NAnt Unicorn target described before in Step 3. This step is responsible for the actual Unicorn synchronization, triggering the execution of my sync.ps1 PowerShell script.

Conclusion

In this blog post I presented my personal approach on how to setup Jenkins to execute a Unicorn synchronization. If you have any questions, or want to share your setup, please don’t hesitate to comment on this post.

Thank you for reading!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s