Skip to content

[Bug] Build with GitVersion.MsBuild fails because GitVersionFileExe is not set #2502

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

Closed
thoemmi opened this issue Jan 4, 2021 · 28 comments · Fixed by #2521
Closed

[Bug] Build with GitVersion.MsBuild fails because GitVersionFileExe is not set #2502

thoemmi opened this issue Jan 4, 2021 · 28 comments · Fixed by #2521
Labels

Comments

@thoemmi
Copy link
Contributor

thoemmi commented Jan 4, 2021

Because GitVersionTask seems to be deprecated, I have switched to the GitVersion.MsBuild package. However, the build of my netstandard2.1 library fails with the message

C:\Users\Thomas.nuget\packages\gitversion.msbuild\5.6.1\tools\GitVersion.MsBuild.targets(3,38): error MSB4022: The result "" of evaluating the value "$(GitVersionAssemblyFile)" of the "AssemblyFile" attribute in element is not valid. [C:\priv\GitVersionMsBuildIssue\src\DemoLib\DemoLib.csproj]

I have noticed that in GitVersion.MsBuild.props, GitVersionFileExe and GitVersionAssemblyFile are not set when the target framework is netstandard2.1. See

<PropertyGroup Condition="'$(MSBuildRuntimeType)' == 'Full' Or '$(MSBuildRuntimeType)' == 'Mono'">
<GitVersionFileExe>$(MSBuildThisFileDirectory)net48/gitversion.exe</GitVersionFileExe>
<GitVersionAssemblyFile>$(MSBuildThisFileDirectory)net48/GitVersion.MsBuild.dll</GitVersionAssemblyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<GitVersionFileExe>dotnet $(MSBuildThisFileDirectory)netcoreapp3.1/gitversion.dll</GitVersionFileExe>
<GitVersionAssemblyFile>$(MSBuildThisFileDirectory)netcoreapp3.1/GitVersion.MsBuild.dll</GitVersionAssemblyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net5.0'">
<GitVersionFileExe>dotnet $(MSBuildThisFileDirectory)net5.0/gitversion.dll</GitVersionFileExe>
<GitVersionAssemblyFile>$(MSBuildThisFileDirectory)net5.0/GitVersion.MsBuild.dll</GitVersionAssemblyFile>
</PropertyGroup>

I've fixed it on my local machine by adding following fallback:

<PropertyGroup Condition="'$(GitVersionFileExe)' == ''">
    <GitVersionFileExe>dotnet $(MSBuildThisFileDirectory)netcoreapp3.1/gitversion.dll</GitVersionFileExe>
    <GitVersionAssemblyFile>$(MSBuildThisFileDirectory)netcoreapp3.1/GitVersion.MsBuild.dll</GitVersionAssemblyFile>
</PropertyGroup>

I have created a repo to reproduce the issue at https://github.com/thoemmi/GitVersionMsBuildIssue

This fixed the build. However, on every build a gitversion.json file is generated in each project folder, which is really annoying. Is there another MsBuild property required to supress that?

Regarding the deprecation of GitVersionTask: The documentation for MSBuild Task still mentions the GitVersionTask package.

@thoemmi thoemmi added the bug label Jan 4, 2021
@thoemmi thoemmi changed the title [Bug] [Bug] Build with GitVersion.MsBuild fails because GitVersionFileExe is not set Jan 4, 2021
@arturcic
Copy link
Member

arturcic commented Jan 4, 2021

Regarding the deprecation of GitVersionTask: The documentation for MSBuild Task still mentions the GitVersionTask package.

Unfortunately the docs are not up to date. There are different areas in the docs that have to be updated. I'll add an issue for that

This fixed the build. However, on every build a gitversion.json file is generated in each project folder
That is on purpose. There is a Target that generats it and the other targets in the GitVersion.MsBuild are consuming it. As a solution would be to have an additional target that removes the file after all the other targets

I've fixed it on my local machine by adding following fallback:

<PropertyGroup Condition="'$(GitVersionFileExe)' == ''">
   <GitVersionFileExe>dotnet $(MSBuildThisFileDirectory)netcoreapp3.1/gitversion.dll</GitVersionFileExe>
   <GitVersionAssemblyFile>$(MSBuildThisFileDirectory)netcoreapp3.1/GitVersion.MsBuild.dll</GitVersionAssemblyFile>
</PropertyGroup>

Wouldn't it be easier if you just add an additional condition for the

<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">

that will also handle the netstandard?

@thoemmi
Copy link
Contributor Author

thoemmi commented Jan 4, 2021

My library targets netstandard2.1. Using the condition '$(GitVersionFileExe)' == '' was must my naive attempt to get my build working. Of course this shouldn't go into production.

@arturcic
Copy link
Member

arturcic commented Jan 4, 2021

Do you mind spending some time for a PR? so that we can review and eventually merge to fix it?

@bddckr
Copy link
Contributor

bddckr commented Jan 4, 2021

When I encountered this (to add Mono MSBuild support) I ultimately thought this shouldn't check the TargetFramework and instead should check for the available SDKs installed on the machine. That's a huge task in itself AFAIK, though.

Other tooling that integrates with MSBuild seems to ship with net46 and netstandard1.6 dlls and implements the whole logic inside that (i.e. the MSBuild tasks are inside those dlls and that is all the logic they run). So they neither invoke an .exe, nor do they invoke dotnet to point it to a dll. This is the best overview I could find.

Any thoughts on this? It feels a bit involved for this library to maintain a list of all possible TargetFrameworks to check.

@thoemmi
Copy link
Contributor Author

thoemmi commented Jan 4, 2021

I would provide you with a PR, but I don't know the proper way to fix the issue. Currently GitVersion.Msbuild.props sets GitVersionFileExe and GitVersionAssemblyFile for Mono, Full Framework, .NET Core 3.1 and .NET 5. All other frameworks are not supported ATM, and I would resist adding all of them. Having a decent fallback (like I did, using the netcoreapp3.1 version) would be helpful.

@thoemmi
Copy link
Contributor Author

thoemmi commented Jan 4, 2021

@bddckr sounds reasonable. However, I wouldn't go for netstandard1.6 anymore but netstandard2.0, which is supported by Full Framework since 4.7.2.

@bddckr
Copy link
Contributor

bddckr commented Jan 4, 2021

Yeah that makes sense. I was thinking of supporting older MSBuild usages and I don't seem to be able to find what versions it supports (or requires), but I guess assuming the build machine has at least a .NET Standard 2.0 compatible framework installation is OK.

@arturcic
Copy link
Member

arturcic commented Jan 4, 2021

Other tooling that integrates with MSBuild seems to ship with net46 and netstandard1.6 dlls and implements the whole logic inside that (i.e. the MSBuild tasks are inside those dlls and that is all the logic they run). So they neither invoke an .exe, nor do they invoke dotnet to point it to a dll. This is the best overview I could find.

That was the old way this package was working (when it was GitVersionTask). But we had quite a lot of issues because GitVersion relies on Libgit2Sharp with native libs embedded. There are some limitations on how the native libs are loaded by msbuild, you needed to provide a custom AssemblyLoader that needs to implement the resolving of the native dependencies depending on the RID. And in order to support all the platforms you have to update the RID manually and so on.

So plenty of issues we had in the past. Then we switched to this This way we let the executable resolve its dependencies the usual way and we just consume its ouptut

@bddckr
Copy link
Contributor

bddckr commented Jan 4, 2021

So plenty of issues we had in the past. Then we switched to this This way we let the executable resolve its dependencies the usual way and we just consume its ouptut

Ha, I should have found that post instead!

TL;DR Just don’t. Use a console tool instead. MSBuild tasks have limitations. It’s typically easier to write a console tool and start a new process from MSBuild using Exec.

I see. Definitely makes a lot of sense to me. I really like @thoemmi's suggestion on resolving this with a catch-all fallback.


So to summarize I wonder if this would work:

  1. For Full (or '' as noted in the linked posts) and Mono run the net48 exe.
  2. For Core run dotnet + dll.

Is there a need to ship a net5.0 dll and run that? Isn't the .NET 5 SDK/runtime backwards compatible with previous .NET Core assemblies? If that's the case the above simplification should work and there is no need to check for .NET 5 vs. .NET Core 3.1 etc. I.e. ship net48 and netcoreapp3.1 dlls only.

@arturcic
Copy link
Member

arturcic commented Jan 4, 2021

Is there a need to ship a net5.0 dll and run that? Isn't the .NET 5 SDK/runtime backwards compatible with previous .NET Core assemblies? If that's the case the above simplification should work and there is no need to check for .NET 5 vs. .NET Core 3.1 etc. I.e. ship net48 and netcoreapp3.1 dlls only.

Actually there are differences. I've tried embedding only 3.1 bits and use it on .net5.0 but the exe was asking for net50 runtime Then I tried the vice-versa, to embed 5.0 bits then it was asking for netcore 3.1 runtime. Also the dlls for the tasks on each runtime have different set of dependencies in the publish output so they cannot be used by both targets.

@SeppPenner
Copy link

I can see the same issue /root/.nuget/packages/gitversion.msbuild/5.6.1/tools/GitVersion.MsBuild.targets(3,38): error MSB4022: The result "" of evaluating the value "$(GitVersionAssemblyFile)" of the "AssemblyFile" attribute in element <UsingTask> is not valid. when building a net5.0 ASP.Net project in our Docker environment (Base image is dotnetsdk:5.0-buster-slim with the dependencies installed as described in #2466).

@SeppPenner
Copy link

I guess, I found the issue in my case. What about the TFMs introduced in Net5.0? If you use e.g. net5.0-windows instead of net5.0, you get the same issue as they're not included in the build props (As @thoemmi stated with netstandard already).

@ermshiperete
Copy link
Contributor

Similar error on Ubuntu 18.04 trying to build for netcoreapp3.1. Seems like dotnet can't load the project because of this error.

/home/user/.nuget/packages/gitversion.msbuild/5.6.1/tools/GitVersion.MsBuild.targets(3,38): error MSB4022: The result "" of evaluating the value "$(GitVersionAssemblyFile)" of the "AssemblyFile" attribute in element <UsingTask> is not valid.

Same problem trying to load the project in Rider.

@SeppPenner
Copy link

Same problem trying to load the project in Rider.

Interesting. It runs and builds in Visual Studio without a problem. Haven't tried VS code though.

@arturcic
Copy link
Member

arturcic commented Jan 4, 2021

In that case maybe it makes sense to have the fallback solution @thoemmi initially suggested, but instead of

<PropertyGroup Condition="'$(GitVersionFileExe)' == ''">
   <GitVersionFileExe>dotnet $(MSBuildThisFileDirectory)netcoreapp3.1/gitversion.dll</GitVersionFileExe>
   <GitVersionAssemblyFile>$(MSBuildThisFileDirectory)netcoreapp3.1/GitVersion.MsBuild.dll</GitVersionAssemblyFile>
</PropertyGroup>

we use

<PropertyGroup Condition="'$(GitVersionFileExe)' == ''">
     <GitVersionFileExe>dotnet $(MSBuildThisFileDirectory)net5.0/gitversion.dll</GitVersionFileExe> 
     <GitVersionAssemblyFile>$(MSBuildThisFileDirectory)net5.0/GitVersion.MsBuild.dll</GitVersionAssemblyFile> 
 </PropertyGroup> 

@SeppPenner
Copy link

In my case, I have changed all TargetFrameworks to net5.0 instead of net5.0-windows and just left the runtime identifier as win-x64, but the build still fails. (Just for reference)

@ermshiperete
Copy link
Contributor

The problem in my case is that TargetFramework isn't set when the .csproj file gets loaded.

@SeppPenner
Copy link

The problem in my case is that TargetFramework isn't set when the .csproj file gets loaded.

I guess, that's what the error is trying to tell us: MSB4022: The result "" of evaluating the value "$(GitVersionAssemblyFile)" of the "AssemblyFile" attribute in element is not valid. with the "" result.

@SeppPenner
Copy link

Sorry to disturb you again, but is there a quick fix workaround that might work on a build server (Gitlab CI) with the environment described already in issue #2465?

Right now, I'm building manually on my local computer which is ok, but sucks for a long term perspective.

@bddckr
Copy link
Contributor

bddckr commented Jan 7, 2021

I believe #2518 is forcing us to ensure we don't switch the used task dlls in a solution. I.e. switching by target framework of a specific project breaks builds for anyone who has projects with different target frameworks in the same solution, while all the affected projects use GitVersion.MsBuild.

@bddckr
Copy link
Contributor

bddckr commented Jan 7, 2021

My latest suggestion is to ask users to have (the runtime of) .NET 5.x installed as a requirement for using GitVersion.MsBuild. With that required we can now only ship the net5.0 dlls, both for the MSBuild tasks to load from them, but also for the dll to execute with dotnet.

That would reduce the maintenance burden to a single target framework for this library. Users only need the runtime for their dev environment, and since .NET is happy to be installed side-by-side with any other version that should be fine.

Alternatively we could only aim for .NET Core 3.1 for now of course, but I think it's in the interest of the maintainers of this library to stay with the latest and greatest if possible. There doesn't seem to be a downside for consumers besides having to install the .NET 5 SDK (or runtime only), which they probably have anyway (especially when they use the latest Visual Studio versions with the .NET component installed).

@SeppPenner
Copy link

My latest suggestion is to ask users to have (the runtime of) .NET 5.x installed as a requirement for using GitVersion.MsBuild. With that required we can now only ship the net5.0 dlls, both for the MSBuild tasks to load from them, but also for the dll to execute with dotnet.

This would make things a lot easier for the maintainers of the project, I guess.

@arturcic
Copy link
Member

arturcic commented Jan 8, 2021

@thoemmi, @bddckr, @SeppPenner, @ermshiperete do you mind to check the #2521 solution if it solves the issue? If you can confirm I will merge it

@SeppPenner
Copy link

It works for me on my dev machine :)

@arturcic
Copy link
Member

arturcic commented Jan 8, 2021

It works for me on my dev machine :)

Is it working for net5.0-windows as well?

@bddckr
Copy link
Contributor

bddckr commented Jan 8, 2021

That works for me on the following machines/projects:

  • Windows with MSBuild (Framework) on projects using net48 + net5.0
  • macOS with MSBuild (Mono) on projects using Xamarin.Mac + Xamarin.Android

I've confirmed it builds the listed projects on both machines from both inside Visual Studio, but also from the CLI. The only thing I'm unable to test with my solution is dotnet build as I'm forced to use msbuild still (old project system in use by Xamarin).

I've run each test at least 3 times on a cleared cache, but also as an incremental build. Each time I made sure I'm building a bunch of projects concurrently, too (as that triggered the issue for me most of the time). Previously this would have hit the bug in each run, but I'm unable to reproduce now 👍

@SeppPenner
Copy link

SeppPenner commented Jan 8, 2021

Is it working for net5.0-windows as well?

I have tested on Windows 10 with Visual Studio 2019 and one net5.0 and one net5.0-windows project. Seems fine so far.
dotnet build -c Release -r win10-x64 runs fine from the command line with both as well.

I sadly can't test for Linux or macOs...

I've run each test at least 3 times on a cleared cache, but also as an incremental build. Each time I made sure I'm building a bunch of projects concurrently, too (as that triggered the issue for me most of the time). Previously this would have hit the bug in each run, but I'm unable to reproduce now 👍

I did several rebuilds and cleans, too.

@SeppPenner
Copy link

I can confirm that this works with our build server, too :) (With the Debian Buster Docker base image). 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
5 participants