How To Set-up Your Sitecore Project To Work With Different Developer Config Files
When we work on a Sitecore build, a very common scenario is to allow each developer to develop against a local Sitecore instance with a database to develop against. If you are using tools like TDS then it's easy to share new configurations between development environments by checking files into source control One part of this process that we can't escape is the requirement for each developer to have his/her own database connection strings, application settings checked in. As we work locally, using the standard build transforms in a deployment package won't work, however, we can add build tasks directly into the 'AfterBuild' build process directly from our .csproj file. In today's tutorial, I'm going to cover the steps needed to transform a simple connection string within the App_Config folder. This example is very basic and you will probably want to tinker with it for your individual needs.
Post Build ScriptsIn this example I'm assuming you are using Sitecore defaults and your connection strings are defined in '\App_Config\ConnectionStrings.config'. A Sitecore connection string config might typically look something similar to this:
<?xml version="1.0" encoding="utf-8"?> <connectionStrings> <add name="core" connectionString="user id=dev;password=password;Data Source=DEV\.;Database=Sitecore_Core" /> <add name="master" connectionString="user id=dev;password=password;Data Source=DEV\;Database=Sitecore_Master" /> <add name="web" connectionString="user id=dev;password=password;Data Source=DEV\;Database=Sitecore_Web" /> <add name="analytics" connectionString="user id=dev;password=password;Data Source=DEV\;Database=Sitecore_Analytics" /> </connectionStrings>Now, we obviously don't want these settings that are specific to a single developer to be checked in as 'ConnectionStrings.config' as this will break everyone else's configuration. Instead, we can create a new separate file unique to that developer, say called 'ConnectionStrings.Jon.Jones.config' and use transforms to copy/insert the details we want into 'ConnectionStrings.config'. Using this approach, we could either make sure a developer never checks the file 'ConnectionStrings.config', or, with a bit more msBuild configuration, we could exclude 'connectionstrings.config' from source control entirely! In case, the filename above confuses you... the 'Jon.Jones' part is my windows account log-in. We can access this in MSBuild using $(USERNAME). If you don't want to differentiate by username, another option is to use PC name instead, I personally think the Windows username is good enough, in most circumstances, so I'm sticking with it :) Ok, so now we have the gist of the approach, let's cover the MsBuild script. You need to add the below configuration into your websites .csproj file right at the bottom. Usually, if you open it in notepad and scroll down you can see a commented out section like this:
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target> -->Add the below XML underneath the above commented out section:
<Target Name="AfterBuild"> <Copy SourceFiles="App_Config\ConnectionStrings.config" DestinationFiles="obj\$(Configuration)\Temp.ConnectionStrings.config" /> <TransformXml Source="obj\$(Configuration)\Temp.ConnectionStrings.config" Transform="App_Config\ConnectionStrings.$(USERNAME).config" Destination="obj\$(Configuration)\Transformed.Instant.Settings.local.config" Condition="Exists('App_Config\ConnectionStrings.$(USERNAME).config')" />/> <ReadLinesFromFile File="obj\$(Configuration)\Transformed"> <Output TaskParameter="Lines" ItemName="TransformedConnectionStrings" /> </ReadLinesFromFile> <ReadLinesFromFile File="App_Config\Include\ConnectionStrings.config"> <Output TaskParameter="Lines" ItemName="UnTransformedConnectionStrings" /> </ReadLinesFromFile> <Copy Condition=" @(TransformedConnectionStrings) != @(UnTransformedConnectionStrings)" SourceFiles="obj\$(Configuration)\Transformed.ConnectionStrings.config" DestinationFiles="App_Config\ConnectionStrings.config" OverwriteReadOnlyFiles="True" /> </Target>Ok. so there's quite a lot going on above. Let's talk through it line-by-line. In the first line, MsBuid creates a temporary version of 'ConnectionStrings.config' called 'Temp.ConnectionStrings.config' in the obj folder in the webroot. On the next line MsBuild searches for a configuration file for the logged on username; if it exists, it copies the developers individual connection string setting into the newly created 'Temp.ConnectionStrings.config'. IN the last line if the 'Temp.ConnectionStrings.config' and the original 'ConnectionStrings.config' are different, it overrides 'ConnectionStrings.config' with 'Temp.ConnectionStrings.config'