Getting started with Application Lifecycle Management (ALM) in CRM – Part II

In my previous blog post, I wrote about the importance of placing every bit of your CRM project under source control, and how we can do that with web resources. In this post we will work with solutions.

Solutions

Why put solutions in souce control? It’s not like the build server is going to build the solution before applying it to a CRM system. Well the answer is twofold:

  1. If your dev servers were to disappear in a puff of smoke – what would happen? In a well-governed CRM project the only setback would be the time it would take you to buy new servers and restore them from TFS. Servers don’t disappear, but they do break down. Version control helps us ensure that we can recover from a disaster without losing completed work.
  2. Keep track of changes and add the ability to rollback those changes. If we have everything in TFS, we can get yesterday’s check-in and undo today’s errors. Or we can experiment with some radical change in our data model and discard it if it turns out bad, etc.

Your solutions is the source code of your project, and as such, you should place unmanaged solutions in TFS. How you ship them is a different discussion for a different time.

So how do we put solutions in TFS? The easiest answer is to manually export them and check them into TFS. That is NOT how you want to do it in a real world scenario, but for now, we go through the process for educational reasons. Once we have seen the process, I will provide a scripted solution.

When reading the following you will be thinking that it wont last a week until someone gets tired of manual processes and stops doing it. Therefore, below the manual process there is an example of how to automate it.

Use Solution Packager to track the changes in your solutions

Having a “backup” version of your solutions in TFS is nice, but sometimes you need to keep track of what was actually changed. You add new fields, remove others, create entities and so forth. Version control of those changes can easily be achieved by exporting your solutions and checking them into TFS.

But if you want to compare version to version you need a little more tooling. The SDK comes with a great tool called the SolutionPackager (SDK\bin\solutionpackager.exe). This tool allows you to extract a solution file to a folder structure and pack it all up again. In our case we will extract a solution to a folder and check the entire folder into TFS. Next time we change something in the solution we will repeat the process and watch how Visual Studio will show the diff in an easily understandable manner.

Here are the steps:

  1. Export your solution (manually) and save it in a folder under source control.
  2. Use solutionpackager.exe to extract the file:
    solutionpackager.exe /zipfile:MyFavoriteSolution_1_0_0_0.zip /action:Extract /folder:MyFavoriteSolution
  3. Use Team Explorer in Visual Studio to add and check the folder and solution file into TFS.
  4. Make your change in CRM. Say change the name of an entity, alter a form, add a field or whatever.
  5. Check the solution and the new folder out for edit with Visual Studio and replace the solution file with a newly exported from CRM.
  6. Repeat the Solutionpackager extract procedure
  7. Check everything into TFS.

solutionpackager
Observe how the solution is extracted into a folder structure and how each xml file (views, entities etc.) is small and understandable.

Now use the history functionality in Visual Studio to identify the changes and observe how TFS filtered out the unchanged files and kept only the ones that had actual change in them. You can double click one of the files and get a diff of the changes.

CompareWithVisualStudio
Observe how the change in the Entity.xml file is highlighted and easily readable

Could we automate it?

The manual procedure not what you want to go with in a real-world scenario. It takes time and soon everyone will stop doing it because they grow tired of tedious manual processes.

Writing a script that automates the procedure is simple. I would recommend using PowerShell for this, and at ProActive where I work we have written a lot of PowerShell CmdLets for doing ALM in CRM. But for now I will keep things really simple, and just do it with a bat file.

Bat file

"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf.exe" checkout MyFavoriteSolution_1_0_0_0.zip
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf.exe" checkout MyFavoriteSolution /recursive
export.exe "MyFavoriteSolution"
solutionpackager.exe /action:Extract /zipfile:MyFavoriteSolution_1_0_0_0.zip /folder:MyFavoriteSolution
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf.exe" add MyFavoriteSolution /recursive
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf.exe" add MyFavoriteSolution_1_0_0_0.zip /recursive
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf.exe" checkin /recursive /comment:"Auto check in of solution" /noprompt

As you can tell from the bat file there is a piece missing: export.exe. The rest is just Visual Studio and CRM SDK stuff. However, we need to be able to automatically export solutions from CRM. In our projects, we use a set of PowerShell CmdLets that we wrote for the purpose. To keep things simple for anyone who don’t know PowerShell I wrote the export.exe program in plain C#.

class Program
    {
        static void Main(string[] args)
        {
            CrmConnection con = new CrmConnection("crm");
            IOrganizationService service = new OrganizationService(con);


            ExportSolutionRequest request = new ExportSolutionRequest
            {
                SolutionName = args[0],
                Managed = false,
                ExportAutoNumberingSettings = false,
                ExportCalendarSettings = false,
                ExportCustomizationSettings = false,
                ExportEmailTrackingSettings = false,
                ExportGeneralSettings = false,
                ExportIsvConfig = false,
                ExportMarketingSettings = false,
                ExportOutlookSynchronizationSettings = false,
                ExportRelationshipRoles = false
            };
            var response = (ExportSolutionResponse)service.Execute(request);
            File.WriteAllBytes(args[0] + "_1_0_0_0.zip", response.ExportSolutionFile);
        }
    }

This program leaves plenty of room for improvements, but it shows the basic idea. You probably want to modify it to fit your needs.

Round up

Automating the export of solutions and checking them in to TFS is a key feature of ALM in any CRM project. It ensures that you have version history of your CRM “source” and it lets you sleep at night knowing that if your CRM dev environments breaks down, it’s just a minor setback – not a disaster.