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
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
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!