Just a quick blog post to share my latests findings on the content delivery topic. I recently presented this mechanism at one of the SUGNL meetings and received positive feedback from fellow developers, so I thought it would be nice to get into detail some more with this blog post. When you are not using solutions like TDS, keeping track of all content that was changed by developers and needs to be deployed with your code changes as well, can be an error-prone and challenging task. After looking at all possible solutions, I hooked up multiple free (and Open Source) utilities to automate this process. It turned out to be rather easy to setup and we do have a lot of benefit from it in our development and deployment process.
In the past, we all used the same central Sitecore database located in our company network. This lead to conflicts once in a while, if you were making breaking changes. Also, all developers had to be connected to the company’s network via VPN at all times. For this new technique, we switched to working with local databases only. Each developer machine (laptop in our case) becomes a stand alone development environment with their own database, IIS instance and Git repository. Now we can develop disconnected, share versions in content changes as well and are more flexible in our branching strategy!
How does it work?
We embedded Unicorn into our solutions, a tool that serializes all content changes to disk. Accordingly, these content changes are committed into our Git repositories along with the code changes they accompany. Upon pulling a new version of another branch, we deserialize this content back into our local database (synchronization process) to get the database state that corresponds to the code of that specific version. That is very cool, because now we can not only retrieve each others database states when working on different feature branches without getting conflicts, but we also can browse through history, checking out old branches and getting the database state that was active back then. This is very useful while debugging and using the Git bisect functionality.
So we can exchange content changes, but how do we deploy the latest changes to our test, acceptance or production environments? Well, to know what has changed, we need to make a diff. And to make this delta, we need an old and a new version of the serialized data. So I’ve created a very simple Git command that copies the complete serialized data folder to another folder called ‘initial’, that stores our initial state of our release branch, before starting the merge.
echo “removing old initial copy”
mkdir -p Data/initial
rm -f -r *
echo “creating new initial copy”
xcopy Data/serialization/* Data/initial /E
echo “ready for merging feature branches”
After that we start merging in our feature branches that need to be deployed. This will also merge in serialized changes into the Data/serialization folder, creating the updated version that is a merge of all feature branches that we are going to deploy. And now comes the magic: using Sitecore Courier we can very easily generate a diff package based on those two folders. I included this into an admin page within our solution, which can be loaded by TeamCity automatically. Courier creates an Update package (not the regular Sitecore package with a .zip-extension) that is recognizable by the .update-extension. Update packages can also update only one field within an item and they can delete content too, something that’s not possible with the regular Sitecore packaging functionality.
Installing these Update packages is very easily done via the /sitecore/admin/UpdateInstallationWizard.aspx page, but because I didn’t want any manual intervention I added one last utility to the mechanism: Sitecore Ship. This utility allows us to automatically install an Update package with TeamCity.
So now we’re all good to go! We don’t need to keep track of our changes (only be careful what to commit, no test content please!) and everything is deployed automatically. Both content and code. And we can even browse through history and switch to each others database states of different feature branches. I think it’s a cool alternative to TDS, it’s fully Open Source, you can extend it in any way you want and it only takes about one day to setup and configure.
What are the pitfalls?
Of course, there are a few things to take into account. If you include all Sitecore content, including media items that are stored in the database, your serialization folder will grow beyond sizes that are manageable with most version control systems. And you cannot merge blob data either. So I decided to exclude media items from this mechanism. If you ever need to deploy media items as a part of your development changes, you will need to do this manually. But for the rest, I absolutely did not have any performance issues with a serialization folder containing over 46,000 files and being close to 200 MB in size.
The other drawback is the need to synchronize whenever you pull new changes or check out another branch. This takes a few minutes for large solutions and sometimes a conflict in your serialization files will appear. But in general, it works very well and those few minutes waiting are well worth the ‘effort’, looking at what you get back from it.