Disclaimer: Using D365 with git is not supported officially! What I describe here is how we got it to work despite that fact, no more, no less. Use these instructions at your own risk.
Problems
Yeah, right, first that depressing disclaimer and now we start this post with problems...should I even keep on reading? Yes, please bear with me 😉
Working with D365 basically forces us to use Visual Studio Team Services and its proprietary version control system TFVC. At the same time, the tooling and processes available in VSTS when using git are far more powerful and convenient to use than those for TFVC (case and point: Pull Requests vs. Code Reviews).
The question is: What do we lose when using git instead of TFVC?
There are mainly three issues I can think about:
Versioned hotfixes and .gitignore
Build definitions that are created when you deploy a build server are not capable to be used with git out of the box. In our case, we have not worked with those standard build definitions basically since we started with AX 7.0, simply because we require a few customizations in those definitions, anyway. Ususally, when there is a new platform update, we import the most recent build definition from the DynamicsSDK folder into our VSTS and look at what's new.
Working with D365 basically forces us to use Visual Studio Team Services and its proprietary version control system TFVC. At the same time, the tooling and processes available in VSTS when using git are far more powerful and convenient to use than those for TFVC (case and point: Pull Requests vs. Code Reviews).
The question is: What do we lose when using git instead of TFVC?
There are mainly three issues I can think about:
- The code upgrade service in LCS only works with TFVC.
- In versions older than 8.0 installing and versioning hotfixes in packages that you can overlayer might result in a quite massive .gitignore file that is hard to maintain.
- Out-of-the-box build definitions do not work with git.
So before we go into how we can use git with D365, let's look at those issues:
Code upgrade service
Probably the biggest reason why git is not supported officially. Until Microsoft modifies the code upgrade service to work with git, there is nothing you can do about it. So when there is a new update that requires you to run the code upgrade service, you will have to download your git repository and check in all files into a TFVC repository, run the code upgrade service against this one, and copy the files back into your git repository.
I know, not perfect, but not that tragic, either.
Versioned hotfixes and .gitignore
I do not have a solution for this in versions older than 8.0. But if from now one there really will not be hotfixes, but rather more frequent updates for the applicaton as it is done for the platform, this should not be a problem. But, yes, 8.0 and later is the way to go.
Build definitions
So, whether this is a problem for you depends on how you handle build definitions in general.
To recap, in order to work with git at this point of time, you should
- be working with version 8.0 or later.
- be willing to add a few manual steps into the execution of the upgrade service.
- be willing to put a little more effort into maintaining your build definitions.
If you can live with these prerequisites, let's have a look at how it actually works.
Using git
For the most part, I will presume that you are familiar with git and its terminology, so I will mainly focus on the actual part of integrating D365 development in VSTS with git. Furthermore, I assume you are working with exension packages/models only.
Tooling
Since you are working with Visual Studio, you do not have to use third-party git tools, but I highly recommend it, since I am not really fond of the git integration with Visual Studio 2015. On our development machines we usually install git for Windows and Git Extensions.
Of course, in daily business we are using git tools in Visual Studio, but for more insights into the state of your local repository other tools have proven to be more valuable. Theoratically, you can manage almost all of your interactions with version control with git tools outside of Visual Studio.
If you are working on local machines behind a corporate proxy, you probably need to create the environment variables http_proxy and https_proxy with the URL to your proxy server (it's the little things that drive you crazy...).
Repository
Create a new repository
Of course, the first thing to do is to create a new, empty git repository in VSTS. You can use a test team project in your VSTS. If you like working with git you can simply import that test repository into your productive team project at a later point of time.
When creating the repository you are offered to use a predefined .gitignore file. Simply choose the one for Visual Studio development. That way you have handled other .NET solutions you may have in your repository. We deal with the D365 specific additions to the .gitignore file later on.
Repository structure
When creating the repository you are offered to use a predefined .gitignore file. Simply choose the one for Visual Studio development. That way you have handled other .NET solutions you may have in your repository. We deal with the D365 specific additions to the .gitignore file later on.
Repository structure
When working with D365 and TFVC we have two folders in our repository by default: Metadata and Projects. We map the Metadata folder into the PackagesLocalDirectory folder and only add our own package folders to version control. The projects folder can be mapped onto a folder anywhere else.
There are two major issues if you try to do this with git:
- You cannot clone parts of a git repository into different folders on your local machine, so separating your Metadata and Projects folder is not an option. That means, your whole PackagesLocalDirectory folder would be the local root directory of your repository. Might work, but really does not feel right.
- The first point also implies that your .gitignore file would need to exclude all Microsoft package folders from your repository or only include your own folders, which makes it more difficult to exclude other certain folders inside your package and model folders. All in all, the .gitignore file (or files) would become quite a mess.
- Create a local folder into which you can clone your repository (or repositories...spoilers), e.g. C:\Repos
- Clone your repository into that folder using any tool you like, so you end up with a root directory like C:\Repos\MyD365Repo that should only contain your .gitignore file at this point.
- Create the folders C:\Repos\MyD365Repo\Metadata and a C:\Repos\MyD365Repo\Projects folder in your repository.
- Now copy your package folders into the Metadata folder and your projects into the Projects folder.
The result should be a repository structure that looks something like this:
- MyD365Repo
--- Metadata
------ MyD365Package
--------- Descriptor
--------- MyD365Model
--- Projects
------ SomeSolutionFolder
Visual Studio
If you did not clone your git repository using Visual Studio, open it and connect to your VSTS project as you would normally do. In the Connect window of the Team Explorer, click Add and specify the path to the folder hosting your repository, in our case C:\Repos
Visual Studio will recognize your repository inside that folder and you can use the Visual Studio git integration.
.gitignore
Currently we are able to manage with a single .gitignore file in the repository root. Click here, to see what you would probably need to add to the default Visual Studio .gitignore file. The last two lines are only necessary for third-party binary packages that you install and then commit to version control.
.gitignore
Currently we are able to manage with a single .gitignore file in the repository root. Click here, to see what you would probably need to add to the default Visual Studio .gitignore file. The last two lines are only necessary for third-party binary packages that you install and then commit to version control.
Hook up D365 and your repository
That is some nice repository you have over there, but my Visual Studio is not aware of my D365 packages, let alone the IIS...
Symbolic links to the rescue!
I admit, that sounds far more confident, than I felt about this at first. If you are like me and have only heard about symbolic links but never used them in Windows before, you might be as skeptic about this as I was when a colleague first suggested to use symbolic links to solve the problems mentioned above. But it works like a charm...
So what we did is to create a symbolic link for every one of our package folders in the PackagesLocalDirectory folder (with Visual Studio closed), which looks something like this:
![]() |
Example of how your Metadata folder might look with two sample packages |
![]() |
Symbolic links of your package folders in the PackagesLocalDirectory folder |
Now, if you open your Visual Studio, you will see your packages in the Application Explorer, so you can build them and synchronize the database. When you open up the D365 UI your customizations should be there.
Using symbolic links this way has a few perks:
- The local representation of your repository is well structured and tidy. You can see all your folders (Metadata, Projects and whatever you might want to store in your repository) at one glance in your local repository folder (and in VSTS for that matter).
- You don't have to dive into the PackagesLocalDirectory folder in order to navigate to your package folders.
- You can have multiple independent repositories for different solutions and simply switch back and forth between them, by creating and removing symbolic links (I talk about making that part more convenient later on). You don't even have to build every time you switch between repositories that way. The only thing you might have to do is to synchronize the database. Of cource, if there are no conflicting package folder names in your repositories you can create symbolic links for all your repositories at once. Fun fact: while you can only have one TFVC repository in your team project, you can have as many git repositories as you like!
- And last but not least: It works!
Depending on how many packages you maintain in your D365 solution, creating (and maybe deleting) symbolic links all the time, might be a bit annoying. To make this part more convenient, we created a powershell script, that you can place into the root folder of your repository. You can find that script by clicking here (I am too dumb to get the indentation correct with GitHubGist, so no comments on that...). Running that script from your root repository folder as administrator with the switch -Map will create symbolic links and will remove them with the switch -Unmap.
Build definitions
Of course, you have to change the verson control system to use when getting sources. So choose VSTS Git, your team project, repository and your branch (usually master).
The only remaining issue now is the location of the build project (AXModulesBuild.proj). In order to build your solution correctly, that project has to be in a certain location relative to your Metadata folder. To solve this problem, we added the following build step between the steps Set Model Versions and Build the solution:
What it does is copying the project file, that is present in the Dynamics SDK folder (in its latest version) to the root folder of your repository that the build agent cloned during build execution. Now in the task Build the solution, change the Project property to $(Build.SourcesDirectory)/AXModulesBuild.proj.
Summary
At this point of time it takes a bit more effort to make git work with D365, though with the use of symbolic links that extra effort boils down to a slightly less comfortable code upgrade service process and minor changes to default build definitions.
In my opinion the payoff of using git with D365 makes up for this extra effort, mainly because
- git is much, much more widely used as a version control system. Therefore, the tooling and information you get for it is much more comprehensive than for TFVC. That way, it is simply fun to work with git 😀
- managing multiple solutions with multiple git repositories inside a single VSTS team project (to keep a grasp on all the work items) has proven to be very efficient so far.
- local repositories become much neater.
- Branching! Using branches is very lightweight in git and you can enforce branch policies on your master branch, e.g. to force a ceratin number of reviewers. In our case, our review process for new or changed application objects has become much more efficient with Pull Requests.
So, if at this point you are still interested in trying git with D365, happy experimenting!
No comments:
Post a Comment