Release Strategy for Dynamics CRM - Part 4 - Versioning

In this post I detail my approach to implement an automated versioning strategy in CRM solutions and its custom assemblies with the help of Visual Studio Team Services.

Although I originally only intended it to be a 3 part series I think I will continue to add to it as I keep making improvements. To recap, I previously prepared the project structure to host a CRM solution with the aid of the nullfactory-xrm generator and created a build and release definitions for it. You can find the previous posts here:

There were two aspects of versioning that I wanted to automatically increment with each release. Firstly the CRM Solution itself and then the custom assemblies included as part of the solution. I also wanted the flexibility to version the two independently of each other (I don't think its a very common scenario, but I would still like to have it as an available option).

As with my previous posts, the instructions in this are specific to Visual Studio Team Services (VSTS), but can be adapted to work with other build and release systems.


  • Ideally, a solution structure generated using version 1.3 (or better) of the nullfactory-xrm generator as the template includes the versioning script as part of it - for the sake of simplicity, the post assumes that this is true. More Info.
  • All solution and custom code artifacts and checked-in into source control in VSTS.
  • Basic build definition that builds the artifacts and generates a CRM solution using the SolutionPackager.exe. More info

Integrating with the Team Build

  1. Start off by creating a standard build definition for the solution as described in Part 2.

    Build Definition

  2. Next we need to define a pair of variables for each set of version numbers we want to maintain. In this scenario I only want one version number to be shared between the custom assemblies and CRM solution. Let's do this by navigating to the Variables tab and creating the SuperSolutionMajorVersion and SuperSolutionMinorVersion variables.

    Define Build Variables

  3. I want to keep the artifact build number consistent with the name of the actual build, so navigate to the General tab and set the Build number format to $(SuperSolutionMajorVersion).$(SuperSolutionMinorVersion).$(Build.BuildId).0.

    Notice that I intentionally hard coded the release version to 0. Tweak this format to suit your own needs, but ensure that the number generated is compatible with the versioning scheme used by CRM - or

    Set Build Number Format

  4. Create a PowerShell task which invokes the ApplyVersionToArtifact.ps1 against the assemblies.


    ApplyVersionToAssemblies -BuildSourcePath $(Build.SourcesDirectory) -BuildBuildNumber "$(SuperSolutionMajorVersion).$(SuperSolutionMinorVersion).$(Build.BuildId).0"

    Apply Assembly Version PowerShell

  5. Similarly create a second PowerShell task that applies the version number to the CRM Solution.

    . .\Nullfactory.Xrm.Tooling\Scripts\ApplyVersionToArtifact.ps1

    ApplyVersionToCrmSolution -BuildSourcePath $(Build.SourcesDirectory) -BuildBuildNumber "$(SuperSolutionMajorVersion).$(SuperSolutionMinorVersion).$(Build.BuildId).0"

    Apply Crm Solution Version PowerShell

  6. Finally, lets queue a new build to make sure that everything works as expected. In the Queue build dialog, manually provide a Major and Minor version for the new release. The Major and Minor versions would act as the "public product" number, were as the build number would be the actual iteration.

    Queue New Build

  7. Verify that the build completed successfully - notice that it created using new build number formatting.

    Build Results

  8. Open up the packaged solution and verify that the Solution.xml has the updated version number. Also ensure that the assembly within the solution has been updated as well.

    Empty release template

Final Thoughts

While there were many implementations on the web I based mine off this one

If the project structure was not generated using the nullfactory-xrm generator, then download the latest version of the ApplyVersionToAssemblies.ps1script into your own project structure.

The versioning script can be run manually on developers machine, but its most effective when used together with an automated build and release suite like VSTS.

I had considered using a tokenization as a possible approach to replacing the version numbers, but the problem with that is that solution packager does not like tokens embedded in the solution.xml file. This means that a developer cannot build the solution in their own development environment.


comments powered by Disqus