TFS 2015 Build system

Long time since NAVTechDays 2015, I am trying to start the posts about building NAV under TFS. Today I found some time to look at it and there is first article from the post series...

How to begin with TFS 2015 Build

Creating TFS Project

After you install TFS 2015 on your server (I will not go through the How to install TFS, I think you are able to do that or there are other posts regarding that, it is same for usage with NAV or anything else), you need to create at least one Project on it. Good news is, that you can do that through web administration and you do not need Visual Studio for that anymore. Just open your TFS web portal (url will be something like http://<servername>:8080/tfs ), on the right click "Manage server" icon, this will open the control panel.


Select the collection you want to administer (DefaultCollection is the default one, you can create own collection - it means different DB on SQL server and separate set of Projects etc.) and click "View the collection administration page".


From there use the "New team project" button to create the project. Of course, you need to have enough permissions on the TFS to do that.


On the dialog, enter name of the project, select the template (Agile or Scrum, difference is in naming of elements like User Story or Product backlog item etc.) and choose the version control system you want to use (I am using GIT but someone could stick on TFVC). Than just click "Create project".

Now question is - what is the project, how to name it? You have few choices here, I do not know the answer for you, but I am using "generic" project like "NAV" to keep all in one place (and different project e.g. for our SharePoint department). It means I am using one TFS Project for all our NAV customer projects and own products. You can split the thing inside the TFS project by using separate GIT Repositories for each customer/product, separate Areas to separate work items into groups etc. Make it easy, I think that having one project for everything is enough for you. If you will see that you need something different, you can add new projects as you want.


Creating Code epository (GIT)

In case you are using GIT as your version control system, you can create separate repository for each customer or product to keep them isolated from others. Of course, you can use one repository and have each customer as separate Branch etc., but than you will need to work with all of this together even when you need to work only with one customer. Separating them into repositories allows you to clone only what you are interested in, but still you can merge between repositories in GIT without problems, because you can clone two or more repos into your one working folder if needed (adding more remote repositories).

Just open the TFS web portal, click "Code" tab and you can create New repository or manage th repositories from there.


On same page you can see info how to clone the repo or how to push some existing repo into it, you can see content, history, you can switch branches, see the build result for selected branch (after you setup the builds) etc. It means, you can look into the code or download commited objects directly from this web portal when you need...

How to work with GIT and push the code into the server repository is another story and I will try to touch that in another post.

Creating your first Build Definition

Again open the TFS web portal, click Build tab. There you can add new definition by clicking the + icon.


System will open list of templates you can use to create your definition. Because you do not have any template for NAV yet, select "Empty". After we will create own template, you will find it on the Custom tab. Click Next...


On next step, select for which repository you want to create the definition and which branch you want to build within it as default. You can build repository from the TFS Project, some external GIT Repository or even Subversion repository. Let it be on NAV Team project for our case, select the repository, default branch, you can select "Continuous integration" if you want to build automatically each commit pushed into the repo. Last part is to select default agent queue on which you want to build this definition (you can have more queues, but the default one is enough for now). Create...


Defining build steps

In the build tab you need to add build step as you want to do them. Click + icon, select the task (mostly it will be PowerShell), click add (in our case, click add 4 times). Another step you can use is "Copy and Publish Build Artifacts". Add one at the end. After that, you can select the step and edit the properties on the right.

Steps should looks like this:

1) PowerShell - running script to create the environment (restore DB, create Service tier, import needed FOB files to create all needed objects and fields)

2) PowerShell - running script to import the object files from the repository (default folder where the script is started is the repository root, or you can read the repository path from environment variables which are automatically created when running the script)

3) PowerShell - running script to compile the objects (depends on you if you will compile all or only not compiled etc., could be driven by parameters of the definition - see later)

4) PowerShell - running script to export all into FOB file (or creating anything else you want to have as a output of the build, e.g. DB backup, build notes, installers...)

5) Copy and Publish Build Artifacts - Will take selected files and publish them as output of the build - should take files from the previous step and publish them.


You can name the steps to have clear "step by step" build definition.

PowerShell steps are running in a way, that each PowerShell error is taken as error of the step and the error will break the build, unless you select "continue on error" on the step. In this case, the build will end as "Partially succeeded" if there is error in such a step. It is on you what is breaking error, and what is not.

What and when and how you will run the scripts is on you. You can use my scripts from the or Waldo's scripts from or your own. Does not matter.

Options tab

On options tab you can check the "Create Work Item on Failure" if you want to create Bug into your Work item in case the build will fail. Try to use it after you will have working builds, because else you will end with Work Items full of bugs you need to resolve and close...

Repository tab

On this tab you are selecting for which repository and branches you want to build this definition. Since TFS 2015 update 2 you can even label the source when the build succeeded or failed with some label (e.g. with build name). It could help you to mark versions in the repository by different tags. And if you are using submodules (like I am for my PowerShell scripts, more may be later), you can choose to Checkout the submodules too during the build.

Variables tab

On this tab, you can define your own variables with some values, which you can then use inside your scripts. If you define new variable e.g. "NAV.ForceNewDB", it will be available in the script as $env:NAV_FORCENEWDB. Checking the "Allow at queue time" for the variable will add this variable as option to the dialog, when you are queuing new build. It means you will be able to set the value before you queue the build. If the build is queued automatically, the default value will be used.

By clicking the "List of predefined variables" you can see the system variables you can use in your scripts (like different paths, build name etc.). In some cases you can even change the variables in the script and it will have effect to your build (like changing the build name).

Triggers tab

On this tab you can choose how you want to trigger the build. Using the Continuous integration you will trigger new build for each pushed commit (unless you check the Batch changes, which will build more commits together), you can select for which branches you want to do that (I am using only one for each definition to have clear overview and separate definition for each branch). Using Scheduled condition is good e.g. to run nightly builds.

General tab

and last tab we need to check is telling system how to generate the build name, build job time out (it is good to make it longer, because the build could take 2 hours easily), enable the Badge (to generate badges for the builds, see Demand section could be used to limit which build agent could be used for this definition by defining conditions which must fulfill the agent to be selected to build it (are set on the Agent, see the sections about agents in next aticles). 

Now, your definition is completed. You can save it and name it.

Creating Template

After you have created your first build definition and after you will test it and all will be as you want, you can create Build Definition template from it from the Build definition list. Just look at the list, click the small arrow on the left from the definition name, an in the menu select "Save as Template". Name it and you are done! Now, next time, you can select Custom template when creating new definition and all will be created for you. Just change the settings and variables and you have brand new definition... (or you can Clone the definition if you want...)


To be continue...

next time we will look at how to use the Build Agents to run the builds...