TFS Build with GitVersion in a multi-project repo

Doing a TFS hosted agent build on a repository with multiple Nuget packages in separate folders. Each with its own GitVersion.yml

Georgi Parlakov
4 min readOct 29, 2018

--

I’d like to share my experience with trying to take one (TfsGit) repository that contains a bunch of solutions that result in one or more Nuget package(s) each and:

  • trigger certain build on a certain folder code changes
  • manage versions via GitVersion task with each solution/package having own GitVersion.yml

TLDR:

  1. GitVersion build task uses env variable $(Build.SourcesDirectory) to locate the source. (Proof ).
  2. We can change this variable at build run time using logging commands i.e. set the sources directory to be the one package folder that you are trying to build.
  3. Then GitVersion uses the GitVersion.yml from the project folder $(Build.SourceDirectory)

Details

Agent

First I want to mention agent install gotcha I ran into: When installing an agent (that will do the TFS* server’s bidding on a particular machine) there 2 sets of permissions(details) involved:

  1. TFS user with permissions to manage agent pool
  2. OS user with permissions to do all the operations you’d expect from that agent: copy and delete files, start and stop application pools (IIS) etc.

The first set of permissions is only used at the time of agent registration with the server and are NOT used at any time after that. What’s used is an OAuth token (base*) and then for each session a new token specific for that session is issued using the *base token.
And the second set of permissions concern the operations on the machine where agent lives and does its job — build stuff. I.e. folder permissions etc.

*TFS — read also TFS/VSTS/Azure Dev Ops i.e. on prem or in cloud — it’s the same agent. And TFS is essentially Azure DevOps (formerly known as VSO/VSTS) just 3 months old. Details here.

**There are some similarities with my blog about TFS deployment

Environment variables

I needed to change the environment variable $(Build.SourcesDirectory) [which is actually Build_SourcesDirectory if you do cmd set ]after the start of build, because I wanted to agent to download the sources in the original $(Build.SourcesDirectory) and then trick GitVersion that the sources directory is one folder deeper i.e. $(Build.SourcesDirectory)=$(Build.SourcesDirectory)\$(ProjectName)

It turns out that doing
set Build_SourcesDirectory=$(Build_SourcesDirectory)\$(ProjectName) does not work. Or at least does not “persist” the environment variable into the following tasks. So I couldn’t actually use that. What I ended up doing is vso commands:

#powershell
Write-Host "##vso[task.setvariable variable=Build_SourcesDirectory;]$(Build_SourcesDirectory)\$(ProjectName)"

Nuget restore issue

Turns out the when restoring packages depending on other packages Nuget has some issues (cryptic errors with “invalid token” and such). I found the issue on version 4.1.0 and updating to version 4.7.1 (manually i.e. nuget update -self ) seems to fix that.

I’ve noticed that on TFS 2018 the build templates (ASP.NET template) starts with a task that will update Nuget to 4.4.1 — so it seems to be a known issue. (Take that with a grain of salt — I’ve not actually tested with version 4.4.1)

Build drafts

A very nice feature that helps to sketch out changes — test them and when and if you are satisfied — publish the draft which changes the original to the draft.

Target platform

So when I needed to build a single project (classic .net full framework ASP.NET app .csproj) there is an issue with the following:
On a fresh new build template the build platform is set as any cpu:

And when building the project it tries to match against AnyCPU (ignores case):

The error talks about OutputPath not being set and in the screenshot on the left you can see that it gets set when the PropertyGroup Condition matches.

Warning : The OutputPath property is not set for project ‘MyProject’. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration=’debug’ Platform=’any cpu’. You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Configuration or Platform that doesn’t exist for this project.

So either set the environment variable to anycpu or in the build task add the following argument to msbuild:
/p:platform=anycpu

Thanks for making it all the way.

--

--

Georgi Parlakov

Angular and DotNet dev. RxJs explorer. Testing proponent. A dad. Educative.io course author. https://gparlakov.github.io/