Skip to content

Commit

Permalink
Set Version and PackageVersion to a default value
Browse files Browse the repository at this point in the history
It's not entirely intuitive that you install GitInfo and by default
"nothing happens", as in, you get new code from ThisAssembly,
but otherwise, no versioning changes happen. This might be
counterintuitive to newcomers, who might just care to get
something (a sensible default) going, before investing more
in customizing GitInfo.

This is how MinVer does it (provided there's a version tag
in the repository) and it's quite intuitive.

The way we do it here should be mostly backwards compat
because:
1. Users leveraging assembly-version attributes will already
    have disabled .NET SDK assembly attribute generation
2. Users leveraging MSBuild targets to do this would be
    following the recommended guidance of creating a target
    that runs before specific targets, not as InitialTargets

We make our version-setting target run as an inital target,
which may have a minor impact on initial build perf, but
but shouldn't be a problem since the same targets are
run for DTB anyway (if you make them run before
GetAssemblyVersion, which also runs before
BeforeCompile and CoreCompile in the SDK).

By being an initial target, we allow for existing customization
in pretty much any target, prevail our own one, which becomes
just a default.

Even so, we check for GitVersion=false as an escape hatch for
users who may encounter unforseen broken scenarios.
  • Loading branch information
kzu committed Feb 9, 2023
1 parent d485b19 commit ca66be5
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 57 deletions.
104 changes: 51 additions & 53 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,34 @@ After installing via [NuGet](https://www.nuget.org/packages/GitInfo):

PM> Install-Package GitInfo

By default, if the containing project is a C#, F# or VB project, a compile-time generated source file will contain
all the git information and can be accessed from anywhere within the assembly, as constants in a
`ThisAssembly` (partial) class and its nested `Git` static class:
By default, if the containing project is a C#, F# or VB project, a compile-time generated
source file will contain all the git information and can be accessed from anywhere within
the assembly, as constants in a `ThisAssembly` (partial) class and its nested `Git` static class:

Console.WriteLine(ThisAssembly.Git.Commit);

All generated constants also have a Summary documentation tag that shows the current
value in the intellisense tooltip, making it easier to see what the different values contain:

![](https://raw.githubusercontent.com/devlooped/GitInfo/main/assets/images/tooltip.png)

> NOTE: you may need to close and reopen the solution in order
> for Visual Studio to refresh intellisense and show the
> ThisAssembly type the first time after installing the package.
With this information at your fingertips, you can build any versioning attributes you want,
By default, GitInfo will also set `$(Version)` and `$(PackageVersion)` which the .NET
SDK uses for deriving the AssemblyInfo, FileVersion and InformationalVersion values,
as well as for packing. This default version is formatted from the following populated
MSBuild properties: `$(GitSemVerMajor).$(GitSemVerMinor).$(GitSemVerPatch)$(GitSemVerDashLabel)+$(GitBranch).$(GitCommit)`.

So, straight after install and build/pack, you will get some versioning in place :).

Alternatively, you can opt-out of this default versioning by setting `GitVersion=false`
in your project file, if you want to just leverage the Git information and/or version
properties/constants yourself:

```xml
<PropertyGroup>
<GitVersion>false</GitVersion>
</PropertyGroup>
```

This allows you to use the provided constants to build any versioning attributes you want,
with whatever information you want, without resorting to settings, format strings or anything,
just plain code:

Expand Down Expand Up @@ -82,23 +94,42 @@ VB:
ThisAssembly.Git.Commit)>
```

> NOTE: when generating your own assembly version attributes, you will need to turn off
> the corresponding assembly version attribute generation from the .NET SDK, by setting
> the relevant properties to false: `GenerateAssemblyVersionAttribute`,
> `GenerateAssemblyFileVersionAttribute` and `GenerateAssemblyInformationalVersionAttribute`.

MSBuild:

```
<!-- Just edit .csproj file -->
<PropertyGroup>
<!-- We'll do our own versioning -->
<GitVersion>false</GitVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GitInfo" PrivateAssets="all" />
</ItemGroup>
<Target Name="PopulateInfo" DependsOnTargets="GitInfo" BeforeTargets="PrepareForBuild">
<Target Name="PopulateInfo" DependsOnTargets="GitVersion" BeforeTargets="GetAssemblyVersion;GenerateNuspec;GetPackageContents">
<PropertyGroup>
<Version>$(GitSemVerMajor).$(GitSemVerMinor).$(GitSemVerPatch)$(GitSemVerDashLabel)+$(GitBranch).$(GitCommit)</Version>
<PackageVersion>$(Version)</PackageVersion>
<RepositoryBranch>$(GitBranch)</RepositoryBranch>
<RepositoryCommit>$(GitCommit)</RepositoryCommit>
<SourceRevisionId>$(GitBranch) $(GitCommit)</SourceRevisionId>
</PropertyGroup>
</Target>
```

> NOTE: because the provided properties are populated via targets that need to run
> before they are available, you cannot use the GitInfo-provided properties in a
> PropertyGroup at the project level. You can only use them from within a target that
> in turn depends on the relevant target from GitInfo (typically, `GitVersion` as
> shown above, if you consume the SemVer properties).
Because this information is readily available whenever you build the project, you
never depend on CI build scripts that generate versions for you, and you can
always compile locally exactly the same version of an assembly that was built by
Expand All @@ -107,22 +138,6 @@ a CI server.
You can read more about this project at the
[GitInfo announcement blog post](http://www.cazzulino.com/git-info-from-msbuild-and-code.html).

### MSBuild

If you want to set other properties in your project, such as `$(Version)` or `$(PackageVersion)`
based on the populated values from GitInfo, you must do so from a target, such as:

```xml
<Target Name="_SetVersion" BeforeTargets="GetAssemblyVersion;GenerateNuspec;GetPackageContents">
<PropertyGroup>
<Version>$(GitSemVerMajor).$(GitSemVerMinor).$(GitSemVerPatch)$(GitSemVerDashLabel)+$(GitBranch).$(GitCommit)</Version>
<PackageVersion>$(Version)</PackageVersion>
</PropertyGroup>
</Target>
```

In this case, we're setting the version and package version.

## Details

Exposes the following information for use directly from any MSBuild
Expand All @@ -148,31 +163,8 @@ target that depends on the GitInfo target:
$(GitIsDirty)
```

From C#, F# and VB, by default code is generated too so that the same
information can be accessed from code, to construct your own
assembly/file version attributes with whatever format you want:

```csharp
[assembly: AssemblyVersion (ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor + "." + ThisAssembly.Git.SemVer.Patch)]
[assembly: AssemblyInformationalVersion (
ThisAssembly.Git.SemVer.Major + "." +
ThisAssembly.Git.SemVer.Minor + "." +
ThisAssembly.Git.SemVer.Patch + "-" +
ThisAssembly.Git.Branch + "+" +
ThisAssembly.Git.Commit)]
// i..e ^: 1.0.2-main+c218617
```

> NOTE: you may need to close and reopen the solution in order
> for Visual Studio to refresh intellisense and show the
> ThisAssembly type right after package installation for
> the first time.
All generated constants also have a Summary documentation tag
that shows the current value in the intellisense tooltip, making
it very easy to see what the different values contain.

The available constants from code are:
For C#, F# and VB, constants are generated too so that the same information can be
accessed from code:

```
ThisAssembly.Git.RepositoryUrl
Expand All @@ -193,15 +185,21 @@ The available constants from code are:
ThisAssembly.Git.IsDirty
```

Available [MSBuild properties](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-properties):
Available [MSBuild properties](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-properties)
to customize the behavior:

```
$(GitVersion): set to 'false' to prevent setting Version
and PackageVersion.
$(GitThisAssembly): set to 'false' to prevent assembly
metadata and constants generation.
$(GitThisAssemblyMetadata): set to 'false' to prevent assembly
metadata generation only. Defaults
to 'false'.
to 'false'. If 'true', it will also
provide assembly metadata attributes
for each of the populated values.
$(ThisAssemblyNamespace): allows overriding the namespace
for the ThisAssembly class.
Expand Down
21 changes: 17 additions & 4 deletions src/GitInfo/build/GitInfo.targets
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" InitialTargets="SetGitExe" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="4.0" InitialTargets="SetGitExe;GitSetVersion" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
==============================================================
Retrieves and exposes Git information
Expand All @@ -12,12 +12,18 @@
Customization:
$(GitVersion): set to 'false' to avoid setting Version and PackageVersion
to a default version with format:
$(GitSemVerMajor).$(GitSemVerMinor).$(GitSemVerPatch)$(GitSemVerDashLabel)+$(GitBranch).$(GitCommit)
$(GitThisAssembly): set to 'false' to prevent assembly
metadata and constants generation.
$(GitThisAssemblyMetadata): set to 'false' to prevent assembly
metadata generation only. Defaults
to 'false'.
$(GitThisAssemblyMetadata): set to 'false' to prevent assembly
metadata generation only. Defaults
to 'false'. If 'true', it will also
provide assembly metadata attributes
for each of the populated values.
$(ThisAssemblyNamespace): allows overriding the namespace
for the ThisAssembly class.
Expand Down Expand Up @@ -563,6 +569,13 @@

<Target Name="GitVersion" DependsOnTargets="$(GitVersionDependsOn)" Returns="@(GitInfo)" />

<Target Name="GitSetVersion" DependsOnTargets="GitVersion" Condition="'$(GitVersion)' != 'false'">
<PropertyGroup>
<Version>$(GitSemVerMajor).$(GitSemVerMinor).$(GitSemVerPatch)$(GitSemVerDashLabel)+$(GitBranch).$(GitCommit)</Version>
<PackageVersion>$(Version)</PackageVersion>
</PropertyGroup>
</Target>

<Target Name="_GitBaseVersionFile" Returns="$(GitBaseVersion)"
Inputs="@(_GitInput)"
Outputs="$(_GitInfoFile)"
Expand Down

0 comments on commit ca66be5

Please sign in to comment.