Continuous Integration with Gulp and Sitecore Powershell Extensions Part 1

Sitecore development and code deployment is quite different than normal ASP.Net Web Application development because of the fact that we need to deal with the versioning of Sitecore items. In this regard Team Development for Sitecore (TDS) is a huge help. There are two main things that TDS does, it publishes the files to the application folder and deploys Sitecore items in the application. Actually, TDS does lot more than that, but those two things are most important to me.

Last few days I was contemplating if can I achieve these two deployment functionalities using Gulp and Sitecore Powershell Extensions (SPE), because, Gulp is great for publishing project files and SPE is great for dealing with Sitecore items. So, the journey started and I am happy that it works. This is going to be a blog series. This one is for deployment of Sitecore application in developer’s local environment.

Sitecore Setup

This is easy. I used SIM to install Sitecore 8.1 and 3.3 version of SPE from Sitecore Marketplace. To work on this, I need a real Sitecore application. I named it ‘Cobbler’. For local environment the hostname is cobbler.local. After setup is done, I had to create the templates and items for my application. Below is a screenshot from the content editor. All the items are available in Github along with the source code.

pic1

Only change I made in the default installation, I changed the serialization folder in the Sitecore.config. I did this because I want to version control the serialized Sitecore items. Following line changed

<setting name=”SerializationFolder” value=”C:\Github\Cobbler\data\serialization” />

Project Setup

Following is a screenshot of the Cobbler solution in Visual Studio.

pic2

 

By no means it is a fully working solution. I mean, after setting up everything and do the deployment, a nice website will not be launched. The idea is to show how deployment works. Being said that, I tried to add different kinds of projects in the solution to represent how a real application solution looks like. We have two website projects. Cobbler.Web is the main web application and Elf.WebApi is a restful API project. Cobbler talks Elf via restful API. Cobbler.Design project contains all UI design related files (css, font etc.). I separated it to show that files from project other than the Cobbler.Web can be published in Cobbler website. In real life this is often the case. The Elf website is a separate IIS site and deployment process recognize that and publishes to that website.

Gulp Setup

To use Gulp in Visual Studio solution you first need to install Node and npm. Visit nodejs.org and click on the big green button to download and then install. Npm comes with the Node and separate installation is not needed. After installation you can run following two command in the command prompt window to see if they were installed properly. This will show you the version.

node -v

npm -v

Once Node is installed, open Package Manager Console in the Cobbler Visual Studio solution and run following two commands. Since the solution already has a package.json, all gulp packages used in the gulp scripts will be downloaded.

npm install -g gulp

npm install –save-dev gulp

You will also need to install Task Runner Explorer to run the gulp tasks. You can down load from here. After installing Task Runner Explorer, close of Visual Studio and launch again. I found that the gulp tasks doesn’t show up in Task Runner unless I relaunch again. At this point if you right click on the gulpfile.js and click on Task Runner Explorer, you should see all the gulp tasks on the left.

pic3.png

Sitecore Powershell Extension Setup

Other than installing SPE Package in Sitecore, you need to download Remoting for SPE 3.3 Package from Marketplace. Copy the files in C:\Users\<username>\Documents\WindowsPowershell\Modules\SPE folder. The script Invoke-RemoteScript.ps1 in this folder will be use to run scripts remotely in the Cobbler Sitecore application.

Scripts

That should be all for setup. Let’s look at the scripts.

Powershell Scripts

SerializeItems.ps1
This script reads the items path from the SitecoreItemPath.txt file and serialize the files in the Serialization folder C:\Github\Cobbler\data\serialization. If a line in the SitecoreItemPath.txt marked as -DeployOnce, that item will be skipped if it already exists.


#Change the Powershell Execution Policy so that script can be run from Visual Studio
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
$session = New-ScriptSession -Username &quot;admin&quot; -Password &quot;b&quot; -ConnectionUri &quot;http://cobbler.local&quot;
$RootFolder=&quot;C:\Github\Cobbler\data\serialization\master&quot;
$ItemPaths=Get-Content &quot;C:\Github\Cobbler\SitecoreItemPath.txt&quot;
$ItemExtn=&quot;.item&quot;
foreach($ItemPath in $ItemPaths)
{
$ItemPath=$ItemPath.Trim()
$ItemPath=$ItemPath -replace &quot;/&quot;, &quot;\&quot;
if($ItemPath.Length -gt 0)
{
if(-not (($ItemPath.ToLower().Contains(&quot;-deployonce&quot;)) -and (Test-Path &quot;$($RootFolder)$($ItemPath.ToLower().TrimEnd(&quot;-deployonce&quot;).Trim())$($ItemExtn)&quot;)))
{
if($ItemPath.ToLower().Contains(&quot;-deployonce&quot;))
{
$ItemPath=$ItemPath.ToLower().TrimEnd(&quot;-deployonce&quot;).Trim()
}
Write-Host &quot;Serializing Item: $ItemPath&quot;
$script = {
Get-Item -path $params.Path | export-item -ItemPathsAbsolute -Root $params.RootFolder
}
$args = @{
&quot;Path&quot; = &quot;master:$($ItemPath)&quot;
&quot;RootFolder&quot; = &quot;$RootFolder&quot;
}
Invoke-RemoteScript -ScriptBlock $script -Session $session -ArgumentList $args
}
}
}

DeserializeItems.ps1
This script is opposite to SerializeItems.ps1 script. It reads the items path from the SitecoreItemPath.txt and create or update the items in Sitecore. Similar to the other script, this script also skips the item if the item is marked as -DeployOnce.


#Change the Powershell Execution Policy so that script can be run from Visual Studio
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
$session = New-ScriptSession -Username &quot;admin&quot; -Password &quot;b&quot; -ConnectionUri &quot;http://cobbler.local&quot;
$RootFolder=&quot;C:\Github\Cobbler\data\serialization\master&quot;
$ItemPaths=Get-Content &quot;C:\Github\Cobbler\SitecoreItemPath.txt&quot;
$ItemExtn=&quot;.item&quot;
foreach($ItemPath in $ItemPaths)
{
$IsDeployOnceItem = $FALSE
$ItemPath=$ItemPath.Trim()
#$ItemPath=$ItemPath -replace &quot;/&quot;, &quot;\&quot;
if($ItemPath.Length -gt 0)
{
if($ItemPath.ToLower().Contains(&quot;-deployonce&quot;))
{
$IsDeployOnceItem = $TRUE
$ItemPath=$ItemPath.ToLower().TrimEnd(&quot;-deployonce&quot;).Trim()
}
Write-Host $ItemPath
$script = {
if(Test-Path $params.Path)
{
if(-not ($Params.DeployOnceFlag))
{
Get-Item -path $params.Path | Import-item -ForceUpdate
}
else
{
Write-Log &quot;Skipped&quot;
}
}
else
{
$Path=$params.Path
$ParentPath=$Path.Substring(0,$Path.LastIndexOf(&quot;/&quot;))
Get-Item -path $ParentPath | Import-item -Recurse
}
}
$args = @{
&quot;Path&quot; = &quot;master:$($ItemPath)&quot;
&quot;DeployOnceFlag&quot; = $IsDeployOnceItem
}
Invoke-RemoteScript -ScriptBlock $script -Session $session -ArgumentList $args
}
}

Gulp Scripts

I am not going to paste all the gulp script here but just describe the purpose of the scripts.

Publish-Cobbler-Local –> Publishes code to the Cobbler website

Publish-Elf-Local –> Publishes code to the Elf webapi site

Publish-Cobbler-Design-Local –> Publishes design files to Cobbler website

Serialize-Cobbler-Items-Local –> Runs SerializeItems.ps1

Deserialize-Cobbler-Items-Local –> Runs DeSerializeItems.ps1

DeployAll-Local –> Runs multiple scripts to deploy files and Sitecore Items to the website. Full Deployment.

Deploy-Projects-Local –> Publishes only the deployment files. No Sitecore item gets deployed.

Following scripts runs when solution is launched in Visual Studio and watch changes in the css, javascripi and MVC Views. As soon as file(s) change, they get deployed to the website.

Auto-Publish-Css-Local
Auto-Publish-js-Local
Auto-Publish-Views-Local

Final Word

This is working fine for me in most cases. What this does not provide that I get from TDS is the Sync functionality and interactive way to serialize items in Visual Studio. In the next part, I will integrate this deployment process with Team City and deploy application to remote server.

Links

 

 

 

 

 

Advertisements

About Himadri Chakrabarti

I am a software developer architect and a Sitecore MVP. My professional interest is everything and anything related to Software Architecture, .NET, Sitecore, Node.js, NoSQL etc. Outside of my profession, I am a hobbyist photographer. Link to my photography site http://himadriphotography.com/
This entry was posted in Gulp, Powershell, Sitecore and tagged , , , . Bookmark the permalink.

2 Responses to Continuous Integration with Gulp and Sitecore Powershell Extensions Part 1

  1. michaellwest says:

    Fantastic work!

  2. Pingback: Continuous Integration with Gulp and Sitecore Powershell Extensions Part 2 – TeamCity Integration | Himadri's Technical Blog

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s