Building a Continuous Integration Environment for Sitecore Part 2 – Octopus Deploy

This is part 2 of the series of post that I am doing about building a Continuous Integration Environment using Sitecore, TeamCity, Octopus Deploy, and Unicorn.

Part 1 – Setting Up TeamCity
Part 2 – This post
Part 3 – Setting up SQL Server for Sitecore
Part 4 – IIS
Part 5 – Octopus Environment and Deployment Configuration
Part 6 – TeamCity Project
Part 7 – OctopusDeploy Project
Part 8 – Sitecore Item Synchronization using Unicorn
Part 9 – Displaying Build number on Sitecore Home Page & Tagging Git
Part 10 – config transformations using Octopus Deploy
Part 11 – Deploying to a Sitecore Multi-Instance Configuration

Assumptions

Just a quick reminder

All the servers are running Windows Server 2012 R2.All the servers are stand alone, and are not part of a domain. All servers have C and D drives.

Everything that is documented here and on subsequent posts are based on freshly installed Windows Servers.

As detailed in part 1, you will need to modify the Local Security Policy so that password don’t expire after 42 days

Getting Started

Before starting download the following software. It will be used during this setup

Create the following drives as they will be needed later

  • D:\SQLBackup
  • D:\SQLData
  • D:\Octopus
  • D:\Tools

Preparation

SysInternals Handle

This is handy little utility that is used to release locks on files. Previousy I have experienced problems whereby even if stopped the AppPool and an IIS Site, locks where still being held on files, and you could not do a deployment. Using this utility it would force all handles that are still open on a file to be closed. It will be used later as a deployment step with Octopus. For now just Extract the downloaded zip file to D:\tools\Handle

Sidewalk Package Installer

This handy utility on GitHub allows you to install Sitecore Packages from the Command Line. Perfect for when you want to automatically deploy using powershell. However you do need to do a bit of work in that you need to clone the repo and build the executable using the correct Sitecore dll’s as the sitecore solution you want to deploy. After that is completed just copy the bin folder. As I am using a solution Sitecore 7.2 I copied the binary to D:\Tools\SidewalkPackageInstaller.7.2

System Accounts

As with TeamCity, I want to ensure that Octopus runs under an Administrator account

From Control Panel select User Accounts | Manage another Account

o_acc1

Click Add a user Account

o_acc2

You can pick whatever name you want, but I decided on TeamCity-Admin.
For the password, I used https://www.passwordgenerator.com to generate a strong password.

o_acc3

Once the account has been created, click on “Change the account type”

o_acc4

Change the account type to be an Administrator, and click the “Change Account Type” button

All Network Access

I have found that if you do not allow Network Access, you will experience all number of weird and wonderful errors messages when trying to get Octopus and TeamCity communicating. Therefore from Control Panel, run Network and Sharing Centre | Change advanced sharing settings

o_n1

For All Networks select
Select Turn off password protected sharing

Save changes

SQL Server

For this, I am going to be using SQL Server Express. What version you eventually end up using should have no impact on Octopus

From the software downloaded, run SQLEXPRWT_x64_ENU.exe

o_sql01

Select New SQL Server stand-alone installation or add features to an existing installation

o_sql02

Accept the license terms and click Next

o_sql03

Accept default to include SQL Server product updates, and click Next

o_sql04

Let the SQL Server setup files install

o_sql05

For Feature Selection leave as default, click Next

o_sql06

Leave instance configuration with default options and click Next

o_sql07

Change the SQL Server Browser to Automatic Startup Type.
Leave the collation as default.

Click Next

o_sql08

I prefer mixed mode instead of only Windows authentication mode. Generate a secure random password to be assigned to the SA account. Click the Add button as want to add the OctopusAdmin account created earlier as an administrator account

Switch to Data Directories tab:

o_sql09

Set Data root dictionary, User database directory, User database log directory, Temp DB directory, and Temp DB Log directory to D:\SQLData
Set Backup Directory to D:\SQLBackup

o_sql10

No changes are necessary on the User Instances tab

o_sql11

No changes are necessary on the FILESTREAM tab. Click Next

o_sql12

Click Next to install SQL Server

o_sql13

Allow SQL Server to complete installation

o_sql14

Click Close

Run SQL Management Studio

Log in using either Windows Authentication, or using the SA account

run the following SQL script

CREATE DATABASE [OctopusDeploy]
 CONTAINMENT = NONE
 ON  PRIMARY 
( 
    NAME = N'OctopusDeploy', 
    FILENAME = N'D:\SQLData\OctopusDeploy.mdf' , 
    SIZE = 256000KB , 
    FILEGROWTH = 51200KB )
 LOG ON 
( 
    NAME = N'OctopusDeploy_log', 
    FILENAME = N'D:\SQLData\OctopusDeploy.ldf' , 
    SIZE = 102400KB , 
    FILEGROWTH = 10240KB )
GO

Sitecore

As this is going to be used for deploying Sitecore solutions, and Octopus is designed to work with NuGet packages, I needed to create a NuGet packages for the version of Sitecore I am using to be using.

I have looked at the Sitecore Instance Manager but that solutions does not work with the way that I want to.

So what I am doing may involve some extra work, but I am happier with how it works in my environment. Feel free to disagree in the comments.

Download the version of Sitecore you are working with. 8.0 and above, download from dev.sitecore.net and for versions prior to 8.0 download from sdn.sitecore.net

Just remember, only a Certified Sitecore Developer will be able to access these sites and have the ability to download files.

Download the zip file of the relevant version of Sitecore, and extract the zip file to a relevant location on disk. e.g. c:\inetpub\wwwroot\

For the project I am working on that is based on currently using 7.2 rev 140526

The Sitecore password recovery page has hard coded values as to who the email is from. someone@example.com. When I am deploying Sitecore using Octopus I want to replace this during the deployment process. Therefore the following need to be done
Open file \sitecore\login\passwordrecovery.aspx
Replace someone@example.com with #{email.from}

#{email.from} will be defined as a variable within an Octopus project, and will be replaced during the deployment process. I will detail how this is done.

Now its time to build the NuGet package.

Build NuGet Package

I have tried in the past to create a NuGet file using a simple .nuspec file, but Sitecore has empty folders defined within the blank solution, and there is no easy way to ensure that blank folders are created, so I have found that the quickest way to create Nuget files is to run the NuGet Package Explorer.

o_nuget01

Once the app starts, click Create a new package

o_nuget02

Select Edit | Edit Metadata

o_nuget03

Configure the metadata as required but I usually set the Id to the version of Sitecore, and the Version to the Actual version. Therefore Sitecore_7.2_140526 and 7.2.140526 respectivelty and a description of Vanilla Sitecore Website

Click green tick to save the Metadata

o_nuget04

Once back to the main editor, select Content | Add | Existing File

o_nuget06

From Windows Explorer, navigate to the folder where saved Sitecore, and select all files within the Website root. Drag and Drop all files onto the Package Contents on the NuGet Package Explorer. This may take several seconds to complete. You will get a warning about including files in the package root.

o_nuget07

Ensure that “Do this for the next 6 file(s)” and click No

Select File | Save.

Keep the default name, but make a note of where the file is created, as this file will be uploaded to Octopus in later steps.

This step will take some time to complete.

Install Octopus

Run the Octopus installation exe that was downloaded previously. At the time Iused Octopus.3.3.1-x64.msi

o_01

Click Next

o_02

Accept the License Agreement and click Next

o_03

Use the default folder and click Next

o_04

Click Install.

o_05

Once the installation is complete click Finish

The installation will verify that the prerequisites required are installed

o_06

And present you with the Welcome screen

o_07

Click “Get Started”

o_08

Enter your details to start a free trail. Don’t worry you can continue to use Octopus after 45 days. You only need to pay for a licence when you reach a threshold of projects

Once complete click Activate. You will need to use a valid email address as Octopus will send you a licence key to that address

o_09

Change the Home directory to D:\Octopus, click Next

o_10

Use a Custom Domain Account, selecting the Administrative user created earlier. The wording is misleading you can use a local account with no problems.

Click Next

o_11

To select the SQL Server instance created earlier, click on the server name drop down and it will be discovered automatically. Once it has selected the server, click the database drop down, and select the database created during the installation of SQL Server

Click Next

o_12

Leave the default port as default value of 80 and click Next

o_13

Change the authentication mode to Username/passwords stored in Octopus, and then create a new user. To keep consistent I created Octopus-Admin account. Ensure you create the account using a strong password

Click Next

o_14

Click Install

If you want you can clock on Show Script and Octopus will show you the powershell script that I will be using

Wait until the installation is completed, and click Finish

o_15

The Octopus Manager should start automatically.

o_16

Just click “Open in browser”

o_17

Community Edition

Now that Octopus has been deployed its time to switch it to the free Community Edition

Select Configuration | Licence

Select “I want to the use free Community Edition”

o_18

Click Save

Additional Users

As with TeamCity I don’t want to use the Administrator account for day to day work.

Select Configuration Users

o_19

Insert details and click Create User

o_20

The user account just created still needs to be configured

Select Configuration | Teams

o_21

Click Octopus Administrators

o_22

Click Add Members

o_23

Start typing in the name of account you created. Once the account has been selected click Add

o_24

Once back on the Teams configuration, click Save

Api Key

As we will need to push to Octopus, the artifacts that TeamCity produces, we need to create an API key

Select User | Profile API Keys

o_25

Click New API Key

o_26

Enter the purpose of the API Key. I entered “For TeamCity to push packages for deployment”

Click Generate new

o_27

Make a note of the key as it will be required later. Be aware of the warning from Octopus that keys cannot be retrieved once they are created.

Click Close

Global Library Packages

As I have continually mentioned I am building all this for Sitecore solutions. Now its time to add in the Sitecore NuGet package created earlier to the Octopus’s built in package repository.

Select Library | Packages

o_29

Click on Upload Package

o_30

For Choose file select the Sitecore nupkg file that was created earlier

As this is the first time that this action is being performed you don’t need to tick Replace this version if it exists

Click Upload

Next Image shows the package successfully uploaded into Octopus

o_31

Global Variable Sets

Select Library | Variable Sets

As detailed Variable sets are collections of variables that can be included in multiple projects.

o_32

I use this to store paths for tools / utilities that will be needed for all projects.

Click Add variable set

o_33

For the Name, External Software Path, and for the Description, you can enter what is relevant

o_34

Click Save

This will take you to where you can define the variables to be used within the set

o_35

Click within the name to create a new row

The variable I want to create is to the path for the SysInternals tool handle.exe which can be used to free any locks that are on a file, The Sidewalk Package Installer which can be used to install Sitecore packages from the command line, and MicroChap, which is used by Unicorn for authentication

o_36

Variable Name Variable Value
handle.path D:\Tools\Handle\handle.exe
SidewalkPackageInstaller.path D:\Tools\SidewalkPackageInstaller.7.2\Sidewalk.SC.PackageInstaller.Client.exe
MicroChap.path D:\Tools\UnicornSync\MicroCHAP.dll

None of the values needed to be limited in scope

Step Templates

Octopus has the Community Library and I want to install several libraries that are supplied by the community

When you first visit the site, it will list all current contributions

o_38

To select for a script, just type away, and the list will be automatically filtered

This is the page when filtered for “iis apppool – start”

o_39

Its extremely simple to install a script. After filtering and finding the script you want, then click on it to description page. All sample screen shots are from IIS AppPool – Start script

o_40

Click Copy to clipboard

Within Octopus, to go Library | Step templates, and click Import.

o_41

Just paste the contents of the clipboard into JSON Object

o_42

Click Import

o_43

You are presented with the standard Step template dialog. Generally there is nothing that needs to be altered, so just click Save

For my solution, I imported the following step templates from the community

  • IIS AppPool – Stop
  • Variables – Substitute in Files
  • File System – Create Folder
  • IIS Website – Create
  • IIS AppPool – Create
  • Windows – Ensure Hosts File Entry Exists

Custom Step Template – Close Process

As mentioned earlier, I have witnessed previously where even after stopping a website and the AppPool, the O/S is still keeping locks on files within the site. The only way to solve this is to force the release as the O/S will keep the files in a locked state until a reboot. So this script will be used to force all open handles on any file within the deployment folder to be released

From Library | Step Templates, clck Add Step Template

o_44

From the Choose step type dialog, click Run a Script

This will take you to the Setting of the Step template

o_45

I just gave this a name of Close process locking deployment folder

Switch to the Step

The script source should be Source code, and the script is a powershell script


$pathToHandle = $OctopusParameters['handle.path']
$pathToWebsite = $OctopusParameters['rootFolder']

#Make sure handle is registered before using it
& reg.exe ADD "HKCU\Software\Sysinternals\Handle" /v EulaAccepted /t REG_DWORD /d 1 /f

$data = (& $pathToHandle $pathToWebsite)
$lenData = $data.Length - 1

for($index = 5; $index -le $lenData; $index++) {
	#split data ignoring blanks
	$splitData = $data[$index].ToString().split(": ") | where {$_ -ne ""}
	
	#get process id for each open file
	$procId = $splitData[2]
	
	#get hex data for each open file
	$hexId = $splitData[5]
	
	#close the file if any
	if($hexId)
	{
		(& $pathToHandle -c $hexId.toString() -p $procId.toString() -y) #|out-null
	}
	write-host $hexId
}

o_46

Click Parameters

o_47

Click Add parameter

o_48

Variable name: rootFolder
Label: Folder where deploy website

Click Apply

o_49

Click Save to save the template

Here is the json package to easily import

{
  "Id": "ActionTemplates-1",
  "Name": "Close process locking deployment folder",
  "Description": null,
  "ActionType": "Octopus.Script",
  "Version": 2,
  "Properties": {
    "Octopus.Action.Package.NuGetFeedId": "feeds-builtin",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.RunOnServer": "false",
    "Octopus.Action.Script.ScriptBody": "$pathToHandle = $OctopusParameters['handle.path']\r\n$pathToWebsite = $OctopusParameters['rootFolder']\r\n\r\n#Make sure handle is registered before using it\r\n& reg.exe ADD \"HKCU\\Software\\Sysinternals\\Handle\" /v EulaAccepted /t REG_DWORD /d 1 /f\r\n\r\n$data = (& $pathToHandle $pathToWebsite)\r\n$lenData = $data.Length - 1\r\n\r\nfor($index = 5; $index -le $lenData; $index++) {\r\n\t#split data ignoring blanks\r\n\t$splitData = $data[$index].ToString().split(\": \") | where {$_ -ne \"\"}\r\n\t\r\n\t#get process id for each open file\r\n\t$procId = $splitData[2]\r\n\t\r\n\t#get hex data for each open file\r\n\t$hexId = $splitData[5]\r\n\t\r\n\t#close the file if any\r\n\tif($hexId)\r\n\t{\r\n\t\t(& $pathToHandle -c $hexId.toString() -p $procId.toString() -y) #|out-null\r\n\t}\r\n\twrite-host $hexId\r\n}\r\n"
  },
  "Parameters": [
    {
      "Name": "rootFolder",
      "Label": "Folder where website deploy to",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {}
    }
  ],
  "$Meta": {
    "OctopusVersion": "3.3.1",
    "Type": "ActionTemplate"
  }
}

This step will use the handle.path template defined in the global Variable set, and rootFolder which you will configure when the step is used within a deployment process

Custom Step Template – Deploy Base Sitecore Website

This step is used to deploy the base vanilla Sitecore NuGet package that a deployment uses. When it is being used the deployment process will need to supply the version number of the Nuget package to be deployed


{
  "Id": "ActionTemplates-21",
  "Name": "Deploy Base Sitecore Website",
  "Description": "Deploy Vanilla Sitecore site, as supplied from dev.sitecore.net ( Sitecore v8 or above ) or sdn.sitecore.net ( Sitecore 7.5 or below ) and created as a NuGet package.",
  "ActionType": "Octopus.TentaclePackage",
  "Version": 9,
  "Properties": {
    "Octopus.Action.EnabledFeatures": "Octopus.Features.CustomDirectory,Octopus.Features.SubstituteInFiles",
    "Octopus.Action.Package.AutomaticallyRunConfigurationTransformationFiles": "False",
    "Octopus.Action.Package.AutomaticallyUpdateAppSettingsAndConnectionStrings": "False",
    "Octopus.Action.Package.DownloadOnTentacle": "False",
    "Octopus.Action.Package.NuGetFeedId": "feeds-builtin",
    "Octopus.Action.Package.NuGetPackageId": "#{sitecore.version}",
    "Octopus.Action.Package.CustomInstallationDirectory": "#{website.root}",
    "Octopus.Action.Package.CustomInstallationDirectoryShouldBePurgedBeforeDeployment": "True",
    "Octopus.Action.SubstituteInFiles.Enabled": "True",
    "Octopus.Action.SubstituteInFiles.TargetFiles": "sitecore\\login\\passwordrecovery.aspx"
  },
  "Parameters": [
    {
      "Name": "website.root",
      "Label": "Folder where to deploy website to",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "$Meta": {
    "OctopusVersion": "3.3.1",
    "Type": "ActionTemplate"
  }
}

This step is based on Deploy a Package step template.
However, it has has custom features:

  • Custom installation directory
  • Substitute variables in files

It does not have the following preselected configurations

  • Configuration Variables
  • Configuration transforms

The custom installation directory is determine by a variable named #{website.root}

Custom Step Template – Copy Sitecore Licence Key

The Deployment process that is going to be built can be used on a freshly installed server running just the Octopus Tentacle and having IIS installed. This step, will do as the name suggests and will copy the Sitecore Licence file from a central location to the web site.

This is based on the Run a script step type


{
  "Id": "ActionTemplates-26",
  "Name": "Copy Sitecore Licence File",
  "Description": "Copy the sitecore licence file",
  "ActionType": "Octopus.Script",
  "Version": 11,
  "Properties": {
    "Octopus.Action.Package.NuGetFeedId": "feeds-builtin",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.RunOnServer": "false",
    "Octopus.Action.Script.ScriptBody": "$sourcePath = $OctopusParameters['sourcePath']\r\n$destinationPath = $OctopusParameters['destinationPath']\r\n\r\nWrite-Output \"sourcePath: \" $sourcePath\r\nWrite-Output \"destinationPath: \" $destinationPath\r\n\r\ncopy-item -Path $sourcePath\\License.xml -Destination $destinationPath"
  },
  "Parameters": [
    {
      "Name": "sourcePath",
      "Label": "Location where Licence Key is stored",
      "HelpText": null,
      "DefaultValue": "\\\\172.16.201.11\\NetworkShare\\SitecoreLicenceFile",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "destinationPath",
      "Label": "Location where the Licence Key is to be copied to",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "$Meta": {
    "OctopusVersion": "3.3.1",
    "Type": "ActionTemplate"
  }
}

All that will be required is to specify the location of the licence file when this template is used.

Custom Step Template – Deploy Site

This is step is based on Deploy a package step type.

This step is used to deploy the actual custom solution build. It will deploy the artifect that is produced by TeamCity


{
  "Id": "ActionTemplates-22",
  "Name": "Deploy Site",
  "Description": "Step used to deploy  the NuGet sent from TeamCity",
  "ActionType": "Octopus.TentaclePackage",
  "Version": 16,
  "Properties": {
    "Octopus.Action.EnabledFeatures": "Octopus.Features.CustomDirectory,Octopus.Features.ConfigurationVariables,Octopus.Features.ConfigurationTransforms,Octopus.Features.SubstituteInFiles",
    "Octopus.Action.Package.AutomaticallyRunConfigurationTransformationFiles": "True",
    "Octopus.Action.Package.AutomaticallyUpdateAppSettingsAndConnectionStrings": "True",
    "Octopus.Action.Package.DownloadOnTentacle": "False",
    "Octopus.Action.Package.NuGetFeedId": "feeds-builtin",
    "Octopus.Action.Package.NuGetPackageId": "#{packageName}",
    "Octopus.Action.Package.CustomInstallationDirectory": "#{website.root}",
    "Octopus.Action.SubstituteInFiles.Enabled": "True",
    "Octopus.Action.SubstituteInFiles.TargetFiles": "App_Config\\Include\\Z_#{Octopus.Project.Name}.#{Octopus.Environment.Name}.config\nApp_Config\\Include\\SiteDefinition.#{Octopus.Environment.Name}.config\nWeb.#{Octopus.Environment.Name}.config"
  },
  "Parameters": [
    {
      "Name": "website.root",
      "Label": "Folder where to deploy website to",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {}
    }
  ],
  "$Meta": {
    "OctopusVersion": "3.3.1",
    "Type": "ActionTemplate"
  }
}

For this template it will

  • Install to a Custom installation directory
  • Transform Configuration variables
  • Configuration transforms
  • Substitute variables in files

Sitecore’s best practice now appear to be that when creating your custom patch file to prefix it with Z_ to ensure that it is run last. As part of the deployment still want to have the sitecore .config files transformed, hence why the Substitute variables in files is set to

App_Config\Include\Z_#{Octopus.Project.Name}.#{Octopus.Environment.Name}.config

There is only one parameter defined that is where the website is to be deployed to

Custom Step Template – Load Site

This step is based on Run a Script step type


{
  "Id": "ActionTemplates-42",
  "Name": "Load Site",
  "Description": "Used to preload load a site",
  "ActionType": "Octopus.Script",
  "Version": 0,
  "Properties": {
    "Octopus.Action.Package.NuGetFeedId": "feeds-builtin",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.RunOnServer": "false",
    "Octopus.Action.Script.ScriptBody": "Begin {\r\n    $counter = 1\r\n    $web = New-Object System.Net.WebClient\r\n    $flag = $false\r\n    $retries = 20\r\n    $websiteName = $OctopusParameters['website.name']\r\n    $delay = $OctopusParameters['website.delay']\r\n}\r\nProcess {\r\n    While ($flag -eq $false -and $counter -le $retries) {\r\n        Try {\r\n            Write-Output \"$counter/$retries waiting for website $websiteName\"\r\n            $html = $web.DownloadString(\"http://$websiteName/\")\r\n            $counter++\r\n            Start-Sleep -Milliseconds $delay\r\n            $flag = $True\r\n        }\r\n        Catch {\r\n            $counter++\r\n        }\r\n    }\r\n}\r\nEnd {\r\n    Write-Host -fore Green \"$websiteName is available\"\r\n}"
  },
  "Parameters": [
    {
      "Name": "website.delay",
      "Label": "Website Load interval",
      "HelpText": "The delay, in milliseconds, between each attempt to query the website",
      "DefaultValue": "500",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "$Meta": {
    "OctopusVersion": "3.3.1",
    "Type": "ActionTemplate"
  }
}

With .net, and especially Sitecore, the first time the site is accessed there is a delay. This script will load the site so that it is ready, and all subsequent requests will not be delayed while the solution is loaded. This is especially useful when deploying sitecore packages from the command line so that those tasks do not time out

The script will try 20 times to load a site.

Custom Step Template – Load Site

This step is based on Run a Script step type


{
  "Id": "ActionTemplates-41",
  "Name": "Deploy Sitecore Module-Package",
  "Description": "Deploy a sitecore module. Ie package downloaded from Sitecore Marketplace https://marketplace.sitecore.net/",
  "ActionType": "Octopus.Script",
  "Version": 3,
  "Properties": {
    "Octopus.Action.Package.NuGetFeedId": "feeds-builtin",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.RunOnServer": "false",
    "Octopus.Action.Script.ScriptBody": "$sourcePath = $OctopusParameters['sourcePath']\n$destinationPath = $OctopusParameters['destinationPath']\n$packageInstaller = $OctopusParameters['SidewalkPackageInstaller.path']\n$websitePath = $OctopusParameters['website.folder']\n$websiteName = $OctopusParameters['website.name']\n$packageName = $OctopusParameters['package.name']\n\nWrite-Output $sourcePath\nWrite-Output $destinationPath\nWrite-Output $packageInstaller\nWrite-Output $websitePath\nWrite-Output $websiteName\nWrite-Output $packageName\n\nWrite-Host copy-item -Path \"$sourcePath\\$packageName\" -Destination $destinationPath\n\ncopy-item -Path \"$sourcePath\\$packageName\" -Destination $destinationPath\n\nWrite-Output $packageInstaller -sitecoreUrl \"http://$websiteName\" -sitecoreDeployFolder \"$websitePath\" -packagePath $destinationPath\\$packageName -connector \"sitecore\"\n\n& $packageInstaller -sitecoreUrl \"http://$websiteName\" -sitecoreDeployFolder \"$websitePath\" -packagePath $destinationPath\\$packageName -connector \"sitecore\"\n\nRemove-Item $destinationPath\\$packageName\n"
  },
  "Parameters": [
    {
      "Name": "sourcePath",
      "Label": "Location where the Sitecore Module is stored",
      "HelpText": null,
      "DefaultValue": "\\\\172.16.201.11\\NetworkShare\\Sitecore.Modules",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "destinationPath",
      "Label": "Where to copy the zip file",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "package.name",
      "Label": "Sitecore Module Name",
      "HelpText": null,
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "$Meta": {
    "OctopusVersion": "3.3.1",
    "Type": "ActionTemplate"
  }
}

One of the issues that I have experienced in the past is when you install a Sitecore package when you develop, the dll’s and Sitecore items should not be included within your Visual Studio solution. In later posts I will detail a command line application that will install Sitecore Packages. This step is used to call Sidewalk Package Installer.

This step will call this utility passing in the location of the Sitecore Package to install.

External Feeds

We need to configure Octopus to inform it of the location of the TeamCity server so it knows where to pull the artifacts from

Select Library | External Feeds

o_96

Click Add Feed

o_97

Enter the ip address of the TeamCity NuGet server, and enter the TeamCity-Admin credentials created earlier when configurating the TeamCity server.

Click Save and test

You will be asked to specify a Package Name. If you leave the package name blank it will list every Nuget package currently on TeamCity.

Lifecycle

I prefer to create a custom lifecycle for each deployment solution created, rather than having multiple projects use the Default Lifecycle. This way it is much easier to customize if required later

Select Library | Lifecycles

ol01

Click Add lifecycle

ol02

Base the name for the project to be created.

I like to have a default retention policy of three releases.

This is set via Change on the Default retention policy

ol03

Click Apply, and the Save on the lifecyle

ol05

Next Steps

This is the minimum configuration needed to get Octopus ready.

The next steps will be to build and configure the solution environment, the IIS server that Sitecore will run on, and the DB server that Sitecore will use. The solution environment needs to be configured now because you cannot create a deployment solution without first making sure that the Octopus Tentacle is installed.

How these are setup and configured will be detailed in the next post. Building a Continuous Integration Environment for Sitecore Part 3 – SQL Server

Advertisements

My musing about anything and everything

Tagged with: , , , ,
Posted in CI, Continuous Integration, Octopus, Octopus Deploy
4 comments on “Building a Continuous Integration Environment for Sitecore Part 2 – Octopus Deploy
  1. MJ says:

    Hi Darren,

    Many thanks for this thorough illustration.

    I have a question, Do you have any suggestions or previous experiencing in performing this set up for multiple Sitecore projects/clients? that is to utilize a template set up to be used on separate servers when provisioning a whole new environment for another project.

    • Darren Guy says:

      Unfortunately this is a shortcoming from Octopus whereby you cannot create a project template. All that can be done is to clone an existing project. And this is what I have ended up doing. Problems occur when you want to add a step, you have to create a step template and then add it to every deployment process. Remembering to include any new variables that may be required.

      It would be great if in a future version of Octopus, they introduced templates, similar to what can be done with TeamCity. Maybe this is something to be recommended on https://octopusdeploy.uservoice.com/ if not already done

  2. alisuleymantopuz says:

    Hi,

    Firstly, thanks for these blog series.

    At this chapter, I’m getting an error from a script block which written in `Close process locking deployment folder`

    + $data = (&$pathToHandle $pathToWebsite)

    Message: `The expression after ‘&’ in a pipeline element produced an object that was not
    valid. It must result in a command name, a script block, or a CommandInfo
    object.`

    Do you have an idea about this ?

    • Darren Guy says:

      What I would normally do in this instance is make sure that somewhere I am outputting all the variables to the log, and then I would try and execute the command manually from within powershell. Most of the problems I have discovered in the past relate to having the variable value being incorrect and attempting to manually execute a command directly in powershell has helped highlight the problem.

      You can also set these variables in your process
      OctopusPrintEvaluatedVariables
      OctopusPrintVariables
      to true, and the next time you create a release it will include a log more logging information to assist with debugging.

      Doing this should help

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

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 12 other followers

%d bloggers like this: