-
Notifications
You must be signed in to change notification settings - Fork 649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GitVersionTask Parallel restore issue when multi targeting #1381
Comments
This might be down to an error in my PR branch, I'll reopen once I know for sure it's an issue in master. |
This issue seems only relevant to dotnet build, if you use msbuild /t:build or msbuild /t:Restore its fine. I beleive this is because dotnet build now implictly does a dotnet restore. And dotnet restore is done in parralel unless you opt out using --disable-parallel. This causes a problem for our build task, libgit2sharp keeps locks and doesn't like to be used concurrently. Therefore in my sample repo in order to work around this I have had to use |
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. |
This should probably result in a docs change - i.e gitversiontask doesn't support building projects in parallel, which is a build switch that should be disabled |
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. |
Not supporting parallel build is often a show-stopper for big solutions. Turning parallel build off easily makes 3-minutes build into 15-minutes. Do you take votes on what is the most important? Count mine here ;) |
There is actually another related issue: when a repository contains more than one solution and those are built in parallel - GitVersion sometimes fails like this:
|
My thoughts on a possible solution to this..
We could make a change to gitversionask so that it no longer does this prepare logic, and just assumes that the git preparer logic has already been run. Then, at the start of your build process you'd need to run some gitversion command to ensure this this initialisation logic was done first. I'm not sure it this is the sole cause of the locking issue but it is certainly one of them. |
@dazinator, sounds like an interesting solution. I have my own solution. The first run of the task will cache it's results, and the next executions will just use the cache. We need to figure out a mechanism to make sure the task will run once and the others will use the cache |
@arturcic yeah, I was thinking along those lines to begin with - the trouble is, you have multiple instances of the task (one for each project in a solution) - potentially all running at the same time, and also accross multiple solutions and processes (as msbuild likes to spawn multiple worker processes). Therefore to get this to work, we'd need to implement our own locking mechanism, so that the first task can grab the lock, run, and then all the other tasks wait for the lock to be released - and this lock would need to work accross process boundaries. We could use something like a named Mutex to achieve this (i.e OS level locking) - more on that here: https://stackoverflow.com/questions/46302756/in-dotnet-core-how-can-i-ensure-only-one-copy-of-my-application-is-running It's a viable solution for sure - but I can see it opening up issues on various platforms if it's not done correctly. Therefore I am thinking it might be better to go with priming the cache at the start of your CI build (as a seperate step) - potentially just by running gitversion (i.e outside the msbuild process) then simplifying the msbuild tasks to just use the cache - (and possibly throw an informative exception if there is no cached value - saying you need to run gitversion in the working directory atleast once?). |
@dazinator priming the cache adds friction to usage versus adding one-time effort for developing, so if there's a way to avoid priming and make sure GitVersion just works - I think it is the best. About locking - git uses lock file. Can GitVersion do the same? I mean, the process starts, checks in shared read-only mode if the files are up to date; if not - tries to create a lock file (e.g. under Of course, it won't work if GitPreparer needs write access to the repository. But I don't see as a user I'd expect GitVersion to do any changes to my repo (at least without an explicit direction/command to do so). After all, I'm trying to figure out the version based on my current state, not change the state. |
@ivan-danilov that's exactly the way I was thinking it should be implemented, with a lock file and watching for the cache file changes. We need to prototype this idea. Do you mind giving a try? |
🙏 Would greatly appreciate this feature! |
I had similar thoughts about using a lock file ;-) I agree that asking a user to run gitversion on the repo first, before doing a build does add friction and isnt ideal but it would atleast allow gitversion task to work in parallel builds with probably the least amount of effort. If someone wants to have a crack at the rolls Royce solution though that would be awesome. The way I saw this solution evolving was something like the following:
|
We have tons a problems since we updated our buildserver from 1 to 2 core. We get all the Warnings and Errors mentioned here. We trying now some workarounds. But a real solution to that problem with be nice. |
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. |
Ping, the issue is still there as far as I'm aware. |
Please greenlight #2410 ASAP please :) This is a blocker for my team. |
A good Workaround is set the Version on the BuildServer with running GitVersion al as Standalone tool after checking out the source code, so that Environment Variables with the Current Version Numbers will be set for that build. For Azure DevOps we use. https://marketplace.visualstudio.com/items?itemName=gittools.gitversion (seems deprecated, works here). We disabled the AssemblyInfo Version File Update. For your other build server you may do this manually after the checkout of the git repository in your build script. Then add this into your root <PropertyGroup Condition=" '$(GitVersion_MajorMinorPatch)' != ''">
<DisableGitVersionTask>true</DisableGitVersionTask>
<Version>$(GitVersion_FullSemVer)</Version>
<FileVersion>$(GitVersion_AssemblySemFileVer)</FileVersion>
<AssemblyVersion>$(GitVersion_AssemblySemVer)</AssemblyVersion>
<AssemblyInformationalVersionAttribute>${GitVersion_InformationalVersion}</AssemblyInformationalVersionAttribute>
</PropertyGroup> This will be picked up by every project build, and if a GitVersion is set (e.g. the Build Task above) then GitVersion MS Build Task will be disabled and also set the Build Version Properties to the wanted version (your Version Numbers needs may vary). With that you need no other work around, it just works on the build server, and locally the build task will be run. Also you will notice that the build will be faster with large solution, or tons of branches. GitVersion runs ONCE with the Build Task from the Marketplace, not multiple times in different, builds, unit tests, publish etc. And even if this issue will be fixed eventually, there is no need to change this. |
My team places a lot of value in doing as much as possible in the csproj/msbuild file because it goes father to ensure the same build result independent of build environment or workflow. We consider versioning to be an integral part of the build process which should be handled consistently through any build workflow such as through Visual Studio or using an automated build script. I appreciate your workaround, but I feel like it falls short of capturing the value added by an MsBuild task. Perhaps my view is a bit too dogmatic? Getting a proper fix in soon would really be appreciated. |
As @DerAlbertCom already said, we do it the same way to avoid <?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Authors>foo</Authors>
<Company>foo</Company>
<PackageProjectUrl>foo</PackageProjectUrl>
<RepositoryUrl>foo</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<NoWarn>CS0618;CS1591;CS1701;CS8618;CS8632;NU5048;NU5105;NU5125</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(GitVersion_SemVer)' != ''">
<GetVersion>false</GetVersion>
<WriteVersionInfoToBuildLog>false</WriteVersionInfoToBuildLog>
<UpdateAssemblyInfo>false</UpdateAssemblyInfo>
<GenerateGitVersionInformation>false</GenerateGitVersionInformation>
<Version>$(GitVersion_FullSemVer)</Version>
<VersionPrefix>$(GitVersion_MajorMinorPatch)</VersionPrefix>
<VersionSuffix Condition=" '$(UseFullSemVerForNuGet)' == 'false' ">$(GitVersion_NuGetPreReleaseTag)</VersionSuffix>
<VersionSuffix Condition=" '$(UseFullSemVerForNuGet)' == 'true' ">$(GitVersion_PreReleaseTag)</VersionSuffix>
<PackageVersion Condition=" '$(UseFullSemVerForNuGet)' == 'false' ">$(GitVersion_NuGetVersion)</PackageVersion>
<PackageVersion Condition=" '$(UseFullSemVerForNuGet)' == 'true' ">$(GitVersion_FullSemVer)</PackageVersion>
<InformationalVersion Condition=" '$(InformationalVersion)' == '' ">$(GitVersion_InformationalVersion)</InformationalVersion>
<AssemblyVersion Condition=" '$(AssemblyVersion)' == '' ">$(GitVersion_AssemblySemVer)</AssemblyVersion>
<FileVersion Condition=" '$(FileVersion)' == '' ">$(GitVersion_AssemblySemFileVer)</FileVersion>
<RepositoryBranch Condition=" '$(RepositoryBranch)' == '' ">$(GitVersion_BranchName)</RepositoryBranch>
<RepositoryCommit Condition=" '$(RepositoryCommit)' == '' ">$(GitVersion_Sha)</RepositoryCommit>
</PropertyGroup>
</Project> |
+1 Trying to convert my build server (TeamCity) from the Visual Studio toolset (msbuild?) to the dotnet toolset and encountering this lock file exception too, which is kind of a block in the conversion process. Is this not a normal method to use GitVersionTask nuget to stamp git versioning information to the assembly? This issue is open since nearly 3 years already, what's the hold up? |
@Dunge hold up from my perspective and I suspect many other contributors, is I have no real incentive to fix this - not that I am the sole maintainer of this repo. I've found workarounds for this issue which I am happy with. It needs someone with an incentive to see this fixed to push it over the line. A lot of people simply don't have time! There has been plenty of discussion for workarounds and even work in progress on this issue to add locking. I prefer to call That said, in an ideal world, GitVersionTask would be fixed. It has a lot of history and originated for legacy .NET framework - such a lot has changed since then, including parallel builds now being enabled by default etc - it's been neglected a bit. One last note: GitVersionTask code is complicated. It needs to execute on a mutitude of different environments, with potentially different version of MsBuild in play. MsBuild has had breaking changes itself, and there is lots of code (reflection etc) to allow GitVersionTask to run on .NET Core and legacy .NET. That's to say, making changes to it is not trivial. The test suite we have has way more coverage than it used to, but the GitVersionTask coverage wasn't in place last time I checked so it was hard to be sure that changes to code actually worked everywhere. |
@dazinator Thank you. Sorry for my somewhat rude comment yesterday (after a long day of configuration I ended up with this issue and wasn't too happy). I was surprised to see such a breaking issue on a nuget with so many daily downloads. I used the aforementioned Otherwise I think I can just call gitversion.exe and send the result to |
@Dunge calling GitVersion.exe with You can the usage here: Here you can see what happens in the GitHub Action: In the new csproj project you can exclude the version field when using GitVersion and delete the |
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. |
This is definitely still a problem when using the GitVersion.MsBuild package, including the 5.6.8 package. Yes, there are options to workaround it, but I think that it makes sense to fix things so that the package works without requiring everyone to disable parallel builds or otherwise alter how GitVersion.MsBuild works by default. |
I was facing no problems with 5.6.7, but 5.6.8 seems to do some things differently again. |
I have opened #2669 with my attempt to fix this problem. |
Closed by #2669 |
🎉 This issue has been resolved in version 5.6.9 🎉 Your GitReleaseManager bot 📦🚀 |
Nice work, I can confirm that the issue is now solved 👍 |
We should thank @bording for the fix |
I am noticing this issue in my NETSTANDARD PR branch, but I think it might impact master as well (although not tested master directly I am inferring it is a problem)
The issue is, the following target runs when restoring:
The
WriteVersionInfoToBuildLog
msbuild task ends up callingExecuteGitVersion
which ends up usinglibgit2sharp
.If you are restoring a solution with dotnet restore (I am not sure about /T:Restore but I assume it's the same?) restoration happens in parallel unless you opt out via
dotnet restore --disable-parallel
switch.Because of this, I am seeing libgit2sharp throw errors about locking as it's being used in parallel to inspect the same repo:
https://ci.appveyor.com/project/dazinator/gitversion-pr1269/build/0.1.1+5.build.1#L32
The text was updated successfully, but these errors were encountered: