Sitecore Utilities: Unicorn Packaging

Reading time ~4 minutes

If you use Unicorn for serialization and create packages manually in old Sitecore way, I think it’s time for a change.

Introduction

I came to the conclusion that I might be doing something wrong more than 2 years ago. I didn’t want to create XML manually, again.

I realized that a huge part of the information about items that I want to package is already in my repository (unicorn configuration).

I decided to leverage that knowledge and create packages like a boss.

Sitecore Utilities: Unicorn Packaging

TL;DR

Unicorn + SPE = Unicorn Packaging

Scripts: UnicornPackaging/Functions

Package: Sitecore.Utilities.Feature.UnicornPackaging.zip

About

Sitecore Utilities

First I need to clarify one thing:

Sitecore Utilities is set of small utilities for Sitecore created by me that I use every day. Each one will be distributed as a separate package. They are to small to create separate repositories but I still want to have them versioned somewhere.

Unicorn Packaging is a utility that I publish today as a part of Sitecore Utilities

Prerequisites

Important thing. The whole thing was written in PowerShell so it should be obvious that this utility has a dependency on SPE.

Regarding Unicorn, later you will see that some things can be made easier in a newer version of Unicorn but the code was created in the middle of 2016 thus it can work on really old versions too.

Hot to use

I assume that you already know Unicorn if you survived that far.

Let’s see some examples.

Example Unicorn configuration

Before we start let’s create an example configuration for Unicorn with default items.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <unicorn>
            <configurations>
                <configuration name="Sitecore.Utilities.Feature.UnicornPackaging.Example" description="" dependencies="Sitecore.Utilities.Foundation.Serialization">
                    <targetDataStore physicalRootPath="$(sourceFolder)\Feature\UnicornPackaging\serialization-example" type="Rainbow.Storage.SerializationFileSystemDataStore, Rainbow" useDataCache="false" singleInstance="true" />
                    <predicate type="Unicorn.Predicates.SerializationPresetPredicate, Unicorn" singleInstance="true">
                        <include name="Content" database="master" path="/sitecore/content/Home"/>
                        <include name="Template" database="master" path="/sitecore/templates/Sample/Sample Item"/>
                    </predicate>
                </configuration>
            </configurations>
        </unicorn>
    </sitecore>
</configuration>

Items include - all items from a configuration

Now let’s say that I want to build a package and include all those items into a package.

I will have to create a new configuration for that.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <packaging>
            <!--
            Include all items from configuration  'Sitecore.Utilities.Feature.UnicornPackaging.Example'
            Use 'Overwrite' as an install option
            -->
            <configuration name="UnicornPackaging.Example.OverwriteEveryItem" unicornConfiguration="Sitecore.Utilities.Feature.UnicornPackaging.Example">
                <unicorn include="*" install="Overwrite"/>
            </configuration>
        </packaging>
    </sitecore>
</configuration>

There is a new section <packaging> in a configuration (an equivalent of unicorn node)

Next, we will just store a set of configuration nodes nested under packaging.

Each configuration node can include many things.

In this example, there is a single node called <unicorn>. It’s responsible for including include node/nodes from particular unicorn configuration.

How does it know which one? Take a look at the configuration node, there is an attribute unicornConfiguration. You have to define which Unicorn configuration corresponds to this packaging configuration.

Install attribute in <unicorn> node defines an installation option that you already know from Sitecore (Merge, Overwrite, Skip, Ask User), of course there is also Merge (not used here).

Asterisk in include attribute means that it will include everything under predicate. This is cool because you can define packaging configuration once and even if you add new items/includes to Unicorn they will be automatically added to the package.

Items include - define installation options

If for some reason you need to treat items separately that’s not a problem, see an example below

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
            <!--
            Include items from configuration  'Sitecore.Utilities.Feature.UnicornPackaging.Example'
            Add include named 'Content' with Merge/Merge options
            Add include named 'Template' with Overwrite option
            -->
            <configuration name="UnicornPackaging.Example.InstallOptions" unicornConfiguration="Sitecore.Utilities.Feature.UnicornPackaging.Example">
                <unicorn include="Content" install="Merge" Merge="Merge" />
                <unicorn include="Template" install="Overwrite"/>
            </configuration>

        </packaging>
    </sitecore>
</configuration>

Instead of including everything, I defined Template to be installed with Overwrite option and Content to be installed with Merge/Merge

Files include

Now, you will learn how to include something from the filesystem.

There are two additional nodes:

  • file - to a include single file, a path is relative to a website folder,
  • dir - to include the whole directory recursively
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
            <!--
            Include files and directories
            Include 'Newtonsoft.Json.dll' from bin folder
            Include all content under 'Website\App_Config\Modules\Sitecore.Utilities'
            -->
            <configuration name="UnicornPackaging.Example.FileSystem">
                <file path="bin\Newtonsoft.Json.dll" install="Overwrite"/>
                <dir path="App_Config\Modules\Sitecore.Utilities" install="Overwrite"/>
            </configuration>
        </packaging>
    </sitecore>
</configuration>

The same as with include nodes you can use installation options here as well.

Packaging

Now the most important thing. How to package all those configurations?

This is a script that I used to prepare a package with this utility.

Import-Function Get-Package -Module "UnicornPackaging"

$packageName = "Sitecore.Utilities.Feature.UnicornPackaging"
[string[]]$include = "Sitecore.Utilities.Feature.UnicornPackaging.Packaging", "Sitecore.Utilities.Foundation.Serialization.Packaging"

# Get all package configurations
[System.Xml.XmlNode[]]$allPackageConfigurationConfigs = [Sitecore.Configuration.Factory]::GetConfigNodes("/sitecore/packaging/configuration")

# Filter package configurations
$allPackageConfigurationConfigs = $allPackageConfigurationConfigs | ? { $include.Contains($_.Name) -eq $true }

# List Configurations
Write-Host "Generating package with following packaging configurations:"
$allPackageConfigurationConfigs | % {Write-Host "`t$($_.Name)"}

# Generate package
$start = Get-Date
$package = Get-Package $allPackageConfigurationConfigs
$package.Metadata.PackageName = $packageName
$package.Metadata.Author = "Alan Płócieniak"
$package.Metadata.Version = "1.0"
$package.Name = $packageName

$start = Get-Date
Export-Package -Project $package -Path "$($SitecorePackageFolder)\$($packageName).zip" -Zip
Write-Host "Package generated [$(((Get-Date)-$start).Milliseconds) ms]"

Installation

Download package from here: Sitecore.Utilities.Feature.UnicornPackaging.zip

This is standard Sitecore package.

Summary

Now you can use Web API from SPE and build packages from Sitecore very easily.

There is an easier alternative (Unicorn-4-Preview-Part-2-5-Generating-Packages-with-SPE), however, it does not provide all the features which UnicornPackaging does.

If you are interested in more utilities like that you should start Sitecore.Utilities project on Github.

I am going to prepare a download page there so you will be able to find all things in one place.

Asset Optimizer configuration

Explanation of different configuration options of SXA Asset Optimizer Continue reading

Items as resources and Unicorn

Published on November 21, 2021

Sitecore Extensions version 3.4 released

Published on November 07, 2020