GitTools / GitVersion

From git log to SemVer in no time
https://gitversion.net/docs/
MIT License
2.85k stars 650 forks source link

Support for dotnet (prev. DNX) / .NET Core projects #647

Closed sunsided closed 5 years ago

sunsided commented 9 years ago

In DNX / .NET Core projects the version is set via the project.json file described here in the Metadata section. AssemblyInfo.cs on the other hand is gone. I'd like to use GitVersion with such projects.

gep13 commented 9 years ago

Out of the box support for the project.json file seems like a natural extension for GitVersion.

There is nothing to stop you using GitVersion today though, you could execute the GitVersion.exe on your repository, establish what the asserted Semantic Version is, and then manually update the project.json file using perhaps a regular expression.

pascalberger commented 9 years ago

Should it really be the task of GitVersion to update versions in all possible project types? If this is in the scope of GitVersion I would suggest to introduce some kind of interface like it is already done for the build server which easily can be extended to other project types (we use GitVersion for example for SharePoint Add-ins which also have their own XML file which contains the version number)

dazinator commented 9 years ago

You would potentially need a composite of these updaters to run. For example if you had a solution containing a library (assembly info), a vsix package (xml), and an asp.net 5 website (project.json) you would want possibly all 3 to be updated.. or maybe just one. This would complicate things a bit for gitversion.

There must be existing tools out there for updating xml / json files..

sunsided commented 9 years ago

On a side note, project.json is really not just ASP.NET, but rather sort of the upcoming standard project type for .NET. With the framework multi-targeting it's a safe bet that sooner or later all NuGet projects will adapt to that one.

gep13 commented 9 years ago

On a side note, project.json is really not just ASP.NET, but rather sort of the upcoming standard project type for .NET.

This was really my reasoning for including it within GitVersion. We have already included Assemblnfo.cs/.vb, which is the default .Net way of versioning a project. If project.json is becoming the new defacto, then IMO, this should also be included OOTB.

If we can setup something in the YAML file to make it more scalable, i.e. look for files matching this pattern, and replace entries with this pattern, with this GitVersion variable, then I would be all for that approach as well.

sunsided commented 9 years ago

You might want to know that DNX uses a versioning feature where a 1.0.0-* project version in project.json is rendered as 1.0.0 normally, but as 1.0.0-whatever when DNX_BUILD_VERSION=whatever is set in the environment. There also seems to exist DNX_ASSEMBLY_FILE_VERSION.

Also, commands defined in the project.json are directly executed by the DNX and this is generally done with the test command at the moment (see here):

"dependencies": {
        "xunit": "2.1.0-*",
        "xunit.runner.dnx": "2.1.0-*"
    },
"commands": {
        "test": "xunit.runner.dnx"
    }

Here xunit.runner.dnx (→ GitHub) is installed via NuGet. The canonical behavior seems to be to look for project.json files that contain this command and then execute dnx test in that directory as part of the build process (see below).

I could imagine hooking GitVersion in there with a version command.

"Default" build system

It's not necessarily directly related and I understand that not every scenario in the world has to be addressed by GitVersion, but this might be something you want to have an eye on.

The ASP.NET 5 team apparently uses KoreBuild and Sake as their self-contained cross-platform build system (which interestingly also has TeamCity integration) and it's getting some love in the community, e.g. here and here. There's a minimal example here, however there seems to be nada documentation available, like everywhere in the ASP.NET 5 world right now.

A very simple makefile.shade would look like this:

var VERSION='0.1'
var FULL_VERSION='0.1'
var AUTHORS='Contributors'

use-standard-lifecycle
k-standard-goals

From _use-standard-goals.shade it would seem that VERSION and FULL_VERSION are used to update AssemblyInfo.cs files if found, FULL_VERSION is in addition passed to nuget pack as the package version. The _k-standard-goals.shade in the Universe repo linked above skips that part and does not seem to patch project.json, however. There are git commands in the standard shadefiles, so this might be an interesting approach to integrate GitVersion in the build process as a use-gitversion step.

clairernovotny commented 9 years ago

There are now support for pre/post build script commands in beta 8 of the DNX tooling. This may be possible now....

olivier-spinelli commented 8 years ago

Unfortunately not. I tried to use prebuild to alter the project.json file with the semver version computed from the repository. The issue is that project.json is NOT read again after prebuild commands have been executed (same for prepack). (Note: the generation of the AssemblyInfo.cs is okay: the Version, FileVersion and InformationalVersion are correctly compiled).

sunsided commented 8 years ago

Crap, sorry, accidentally hit the close button.

RichiCoder1 commented 8 years ago

Any update? I might be interested in taking this up.

clairernovotny commented 8 years ago

@RichiCoder1 I think the biggest challenge is figuring out how to integrate calling GitVersion in the dotnet build pipeline. @olivier-spinelli's experiments weren't positive but a lot has changed since then and maybe the behavior is difference with the dotnet CLI over dnx?

RichiCoder1 commented 8 years ago

You mean ssomething like https://github.com/dotnet/cli/blob/a709f772f10e4c1caeab4199ba24ebc08590f036/TestAssets/TestProjects/TestAppWithScripts/project.json#L21? There's no other way "plug in" and there's straight up no way to set the version (currently) without explicitly modifying project.json.

clairernovotny commented 8 years ago

I'd say that if you can find a way to get GitVersion working, then that'd be awesome!

olivier-spinelli commented 8 years ago

@onovotny actually SimpleGitVersion (see here) did the job well ... for dnx.

What it does is:

It worked like a charm (just like the SimpleGitVersionTask does the job for msbuild).... but now I have to find time to see how I could adapt it to work on dotnet... :(

clairernovotny commented 8 years ago

Oh...this may be easier than we all thought. CLI works differently than DNX. It does not produce a nupkg file directly on build. There are two commands for that --

If you never call pack, you won't get a nupkg out of it. Point is, that if you have a pre/post-build script in the project.json that calls gitversion, and that script updates the version in the project.json itself, then there's a good chance that dotnet pack will do the right thing. The trick will be in multi-project solutions if it reads the dependencies correctly...

sunsided commented 8 years ago

@onovotny If I'm not totally mistaken then changing the project.json after a build would produce an error in pack telling you to restore (and build) again.

clairernovotny commented 8 years ago

@sunsided that's entirely possible, I was just guessing since build/pack were split into two steps.

dazinator commented 8 years ago

I might have a crack at this. I am currently thinking to expose GitVersion as a Dnx command in project.json

"commands": {    
    "gitversion": "GitVersion.Commandline /updateprojectjson"
  },

Then in any project.json within your solution that you want gitversion to replace the version number, add a dummy command:

"commands": {    
    "replace-version": "GitVersion.Commandline"
  },

The idea is that at the start of your build, you would only need to execute a dnx gitversion against the one project in the solution that has the gitversion dnx command. That command would then calculate the gitversion version number as normal, and (assuming you have added the additional /updateprojectjson arg to the command args) then look for all project.json files in the solution dir that contain this "dummy" command. For each one of those it will replace the version with the calculated version.

I thought about this for a little bit and I though this was better than having to execute dnx gitversion individually for each project.json file in the solution for which you want to update the version number in.

Feedback welcome before I start any action this. Perhaps there is a simpler way that I am not seeing.

So the build process would become:

  1. dnx gitversion / calls gitversion exe with args specified in the command in the project json - can replace versions in all relevant project.json files.
  2. dnx build
  3. dnx publish etc
dazinator commented 8 years ago

Ooo I have thought of a way to make that a bit better. The "dummy" command could be used to carry format params for how you'd like GitVersion to replace the version in the project.json. i.e:

"commands": {    
    "replace-version": "[MajorMinorPatch]"
  },
asbjornu commented 8 years ago

@dazinator It's awesome that you want to tackle this. But will the end solution only work with GitVersion.exe and not GitVersionTask?

RichiCoder1 commented 8 years ago

Meant to post this earlier, but I would not invest any time or effort into a DNX based solution. It will almost immediately be rendered obselete once Dotnet CLI RCs.

sunsided commented 8 years ago

Was just about to say this - dnx is dead (literally, i.e. not working anymore), dotnet is the new hype. I'm not too sure, but it doesn't seem to support commands.

RichiCoder1 commented 8 years ago

It doesn't, or at least not in the same way that Dnx does.

dazinator commented 8 years ago

Cheers guys! A lot of this isn't actually that tied to dnx. I'm seeing 2 parts:

  1. Extending gitversion command line so you can call it and have it find and version stamp project.json files (similar to how it does assembly infos)

Project.json files arent going anywhere right? So this still seems needed regardless of whether you plan to use dnx or dotnet cli.

  1. In dnx land, support adding a gitversion 'command' to the project.json file so that you can later invoke gitversion via dnx gitversion

Think it sounds like i can drop that bit.

Your build process would just end up calling the new gitversion command directly rather than via dnx. So rather than:

dnx gitversion
dnx build
dnx publish

You'd now do:

"somepath/gitversion.exe" /buildserver /update-project-json
dotnet build / dnx build

Does that sound ok? If so can continue down this path.

@asbjornu i'm not looking at gitversiontask right now, but perhaps it could be extended to check for a project.json file and also stamp that if it exists?

asbjornu commented 8 years ago

@dazinator I don't know how relevant GitVersionTask is going to be if the only way to version assemblies is to inject a version number into project.json. What GitVersionTask does, is generate temporary .g.cs files containing [Assembly*Version] attributes for each project it's added to. If that way of versioning assemblies is going away, then I guess GitVersionTask will be going away too?

clairernovotny commented 8 years ago

There's absolutely no reason for GitVersionTask to go away. All we're talking about are xproj; csproj still works just fine with GitVersionTask and csproj/msbuild isn't going anywhere.

asbjornu commented 8 years ago

@onovotny Ok, I thought perhaps .csproj was going to become an arcane relic with the introduction of project.json, but it's good to hear that GitVersionTask has a place, still. :smile:

clairernovotny commented 8 years ago

There's quite a lot of things that xproj does not support. WPF needs targets to compile BAML; UWP needs targets for x:Bind and a whole lot of other things; Xamarin projects need targets for their builds. Pretty much any non-trivial build phase needs targets, and MSBuild is how you get there.

xproj/project.json so far is really only good for "basic"/simple projects. Not that it's a bad thing, and it covers a lot. But build is far more than calling the resx compiler and csc.

olivier-spinelli commented 8 years ago

A small announcement that may interest some of you. We tried to use SimpleGitVersion (DNX) from a dotnet project ans it works fine.

Some details here: https://github.com/SimpleGitVersion/SGV-Net/wiki/Installing-SimpleGitVersion#new-dotnet-support

HTH...

olivier-spinelli commented 8 years ago

@sunsided, you are right to worry about:

then changing the project.json after a build would produce an error in pack telling you to restore (and build) again.

Fortunately this is only a warning, not an error and everything works fine.

@onovotny, its true that:

The trick will be in multi-project solutions if it reads the dependencies correctly.

This is what we do in SGV: all the cross references between local project.json files are updated: dotnet build (that takes into account these "local dependencies") works fine. The whole code for all this stuff can be found here: https://github.com/SimpleGitVersion/SGV-Net/tree/master/SimpleGitVersion.Core/DNXSupport There are 8 files and no dependency on any external JSON reader but a quite small JSONVisitor that forwards a "reading head" (the StringMatcher).

sunsided commented 8 years ago

With the advent of the preview1 dotnet CLI, there actually is an extensibility model that could allow for GitVersion to be directly integrated into the command-line tooling, e.g.

dotnet gitversion

by e.g. specifying something like

"tools": {
    "dotnet-gitversion": {
        "version": "1.0.0"
    }
},

per project, where dotnet-gitversion would (most likely) be a NuGet package itself.

That said, in the recent community standups it was made clear that project.json is going to fade away over time and be reintegrated in the .csproj project model. There is no documentation about that process though for the time being, so work on project.json is basically risky atm.

droyad commented 8 years ago

I'm happy to take on the creation of a dotnet-gitversion as we need something to tide us over until neoMSBuild.

droyad commented 8 years ago

So, I've found that changing the project.json within the build pipeline has no effect, it continues to use the original version (ie it reads it at start up). Therefor to get it to work, a command (eg GitVersion.exe) would need to be run before dotnet build. (or GitVersion.exe could run dotnet build)

ah- commented 8 years ago

@droyad i built a simple proof of concept a bit ago: https://github.com/ah-/dotnet-gitversion

JakeGinnivan commented 8 years ago

@ah- where is the source for https://www.nuget.org/packages/GitTools.Core-dotnet/ and https://www.nuget.org/packages/GitVersionCore-dotnet/

https://www.nuget.org/packages/LibGit2Sharp.NativeBinaries-dotnet

Would you be able to submit pull requests to each of these projects to add netstandard support if you got it working. It would be better to not fork the community if possible.

JakeGinnivan commented 8 years ago

Ah, I just found https://github.com/libgit2/libgit2sharp.nativebinaries/issues/39

JakeGinnivan commented 8 years ago

@ah- I think you can unlist https://www.nuget.org/packages/LibGit2Sharp.NativeBinaries-dotnet now as that has the change you suggested and the native dlls in the runtimes folder?

I guess the next thing to watch is https://github.com/libgit2/libgit2sharp/pull/1318, once that is merged and drops we can update GitTools.Core and GitVersion.Core to support netstandard. Then we can release a gitversion for dotnet cli

JakeGinnivan commented 8 years ago

Is there anyway we could just wrap the already compiled exe, because it is cross platform via mono.

ah- commented 8 years ago

@JakeGinnivan agree, unlisted LibGit2Sharp.NativeBinaries-dotnet as that's now fixed upstream. I opened pull requests with all projects, and only forked because https://github.com/libgit2/libgit2sharp/pull/1318 is moving at a glacial pace. The changes are all there, but nobody seems to be able to merge it.

Thought about using the existing mono build, but that doesn't work as a dotnet cli tool, which is running not as an native executable but a .net assembly that's executed by coreclr. Also it's quite a bit cleaner and slicker to use coreclr directly.

JakeGinnivan commented 8 years ago

Thought about using the existing mono build, but that doesn't work as a dotnet cli tool, which is running not as an native executable but a .net assembly that's executed by coreclr. Also it's quite a bit cleaner and slicker to use coreclr directly.

I was thinking wrapping, so create a native .net cli app which simply shells out to gitversion?

dazinator commented 8 years ago

Anyone made any headway with asp net core support (proejct.json) or are we going to wait it out until project.json ihas gone away?

sunsided commented 8 years ago

@dazinator Well @ah- made https://github.com/ah-/dotnet-gitversion which is awesome. With msbuild tooling around the corner I wouldn't rely too much on it now though. They have a history of breaking stuff that used to work fine in beta ...

bravecobra commented 7 years ago

The version of @ah- does not update the "local dependencies" in a multiproject. It seems, we need a combination of what SimpleGitVersion does and the dotnet-gitversion poc.

droyad commented 7 years ago

@bravecobra How do you mean? I've been using the following syntax to reference other projects:

"dependencies": {
    "MyOtherProject": {
      "target": "project"
    }
  },
bravecobra commented 7 years ago

@droyad I didn't know you could to that. Tnx!

asbjornu commented 5 years ago

.NET Core support (.NET Standard 1.3) was added in #1269, .NET Core 2.1 (.NET Standard 2.0) support in #1422.