Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

GitVersionTarget build is very slow, Normalisation step with many branches #1448

Closed
danijam opened this issue Jul 30, 2018 · 8 comments
Closed
Labels

Comments

@danijam
Copy link

danijam commented Jul 30, 2018

Hi, So I'm very keen to use GitVersion in our groups repo to replace some versioning scripts. When I used GitVerion in a test repo to trial it and learn how it works everything was great. Now I've added it into our teams repo I'm starting to encounter performance issues.

Namely our builds without GitVersion (master) take ~1 min with GitVersion (my topic branch) it takes ~3 mins. I was expecting maybe a small overhead but this is took much to accept. The additional time is on the MSBUILD step.

We use VSTS run the build on our established agent build servers. Our solution contains 20 projects each with the GitVersion Targets NuGet Package now installed. When I inspect the logs emitted by the build (MSBuild) I can see GitVersion is spewing lots of INFO events along these lines:

Begin: Normalizing git directory for branch 'refs/heads/JD/GitVersion' (Count 56)

Creating local branch from remote tracking 'refs/remotes/origin/[DevIntial]/[BranchName' (Count 202)

Skipping update of 'refs/remotes/origin/[DevIntial]/[BranchName]' as it already matches the remote ref. (Count 8,327)

Begin: Finding merge base between '[DevIntial]/[BranchName]' and '[DevIntial]/[BranchName]' (Count 1,248)

End: Finding merge base between '[DevIntial]/[BranchName]' and '[DevIntial]/[BranchName]' (Count 1,248)

#1327 Might be similar

I'd like to understand what is going on and why it seems to be spending so much time iterating over all the remote branches if indeed that is where the time is being lost.

I noticed this:
No branch configuration found for branch JD/GitVersion, falling back to default configuration

is this why it is spending so much time doing the merge base operations?

I've attached our GitVerion.yml for reference
GitVersion.txt

@danijam
Copy link
Author

danijam commented Jul 30, 2018

So I've updated the GitVersion.yml to include a branch definition for my topic branch. This has removed the Merge base actions as it now knows how to treat this build (I Guess) as it knows what type of branch it is.

I'm still a fair way off the baseline build time without GitVersion being installed to the projects. Still have a rather large log filled with the normalising messages, creating local branch, and Skipping update of message. What are these doing?

@danijam
Copy link
Author

danijam commented Jul 30, 2018

Also noticing a fair number of random:

MSBUILD : warning : WARN [07/30/18 17:09:36:92] Could not determine assembly version: LibGit2Sharp.LockedFileException: The index is locked. This might be due to a concurrent or crashed process

Is it not possible to run GitVersion against a multi project solution that is building on multiple cores (in parallel)

Seems to be a race condition as repeating the build on the same source can yield different outcomes with regards to the warnings observed

@danijam
Copy link
Author

danijam commented Jul 30, 2018

So we've done some calculations. The repo has 161 branches in the remote. The approx added delta of 60 seconds with GitVersion deployed. So that's 0.372 seconds per branch. I'm sure we can clean up some branches but even so why is there this overhead. I don't see it when I run GetVersion.exe in my local repo?

Why is git version doing these actions?

Begin: Normalizing git directory for branch 'refs/heads/JD/GitVersion' (Count 56)

Creating local branch from remote tracking 'refs/remotes/origin/[DevIntial]/[BranchName' (Count 202)

Skipping update of 'refs/remotes/origin/[DevIntial]/[BranchName]' as it already matches the remote ref. (Count 8,327)

@danijam
Copy link
Author

danijam commented Jul 31, 2018

So I think this boils down to the normalisation step performed by GitVersion Task is slow. If you happen to have only a handful of branches you wont notice the performance hit. #1266 seems to point in this direction. Looks like a comment from @asbjornu mentioned the work @JakeGinnivan in #1243 might improve this. Is this feature near or far from completion I can't tell.

We have 161 branches. Now I can clean some of those up (20 man development team). But we will always have a fair number of branches. We only have master and support branches. Everything else is a topic branch. When we need to patch an old version we find the release tag on the commit in master and open a support branch. We don't delete support branches so this will always grow over time.

Are there any work arounds I can follow? Can I set some configuration to ignore support branches from the normalisation step?

@danijam danijam changed the title GitVersionTarget build is very slow, something I'm doing wrong? GitVersionTarget build is very slow, Normalisation step with many branches Jul 31, 2018
@dazinator
Copy link
Member

Fyi there is an issue open for the parralel build / locking exception. I found i had to disable parallel builds to mitigate this.

@stoopered
Copy link

#1243 was closed?? Is this going to be fixed? I am having this get repeated many times. With a team of 100 developers, and 60 QA, this build times are unacceptable. A commit to master, has references to other branches, is there a way to ignore these so it does not iterate over all of these? On the right side you can see it repeats over and over again.
matchestheremoteref

@LordMike
Copy link

@danijam just chiming in to hopefully help. We wanted to work around the Parallelizaton issue, and decided to completely remove GitVersionTask in favor of the following. What we found, was performance improvements in build times of 50%+

  • C# code (Nuke build script) to run GitVersion CLI, to do version calculation once
  • Using that output, produce a _Generated_Version.targets file, which looks roughly like this:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Generated 2019-01-14T19:02:37.2223356Z -->
  <PropertyGroup Condition="'$(UpdateVersionProperties)' != 'false'">
    <FileVersion>1.2.3.4</FileVersion>
    <InformationalVersion>1.2.3.4-alpha+[..]+sha:b012...</InformationalVersion>
    <AssemblyVersion>1.2.3.4</AssemblyVersion>
    <PackageVersion>1.2.3.4-alpha</PackageVersion>
  </PropertyGroup>
</Project>
  • Include the following in our projects, f.ex. via a common import (ex. Directory.Build.props):
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   ...
  <Import Project="..\_Generated_Version.targets" Condition="Exists('..\_Generated_Version.targets')"/>
   ...
</Project>
  • Ignoring the generated targets file in .gitignore

What we have now, is a process that roughly resembles #1243, in that it produces the required versioning in one go, produces an artifact (similar to a cache) that will dictate the versioning for all affected projects, and then simply using build/pack/publish as usual.

When you build via. VS, you're not guaranteed to have this version info, but building via our script is always guaranteed to produce the version info first. We always only release via. our CI script, so it's a non issue.

We set out to solve parallelization, but we found that we cut our build times for solutions with 40-100 projects by 40-70% (3+ minutes down to ~40 seconds). We didn't expect that much of an improvement ... but this is nuts.

Anyways. I hope this helps you or others. It requires some fiddling and work. But for us, it was definitely worth it.

@stale
Copy link

stale bot commented Jun 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. After 30 days from now, it will be closed if no further activity occurs. Thank you for your contributions.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants