14

I've recently started using GitVersion to version my assemblies, and I love it!

I like to generate a .msi file that reflects the version of the product being built. Hitherto, I was using this in my .wixproj file:

  <!-- [TPL] name the output file to include the version from theLocalServer assembly -->
  <Target Name="BeforeBuild">
    <GetAssemblyIdentity AssemblyFiles="$(SolutionDir)BuildOutput\$(Configuration)\TA.DigitalDomeworks.Server.exe">
      <Output TaskParameter="Assemblies" ItemName="AssemblyVersions" />
    </GetAssemblyIdentity>
    <CreateProperty Value="$(OutputName).%(AssemblyVersions.Version)">
      <Output TaskParameter="Value" PropertyName="TargetName" />
    </CreateProperty>
    <CreateProperty Value="$(TargetName)$(TargetExt)">
      <Output TaskParameter="Value" PropertyName="TargetFileName" />
    </CreateProperty>
    <CreateProperty Value="$(TargetDir)$(TargetFileName)">
      <Output TaskParameter="Value" PropertyName="TargetPath" />
    </CreateProperty>
  </Target>

This produces an output file with a name like:

TA.DigitalDomeworks.Installer.7.1.0.3.msi

I found this solution from this answer, which references this blog post. The 7.1.0.3 comes from the assembly version of the main assembly in the build, which in turn is being versioned by GitVersion during its own build.

However, what I'd really like is to use the FullSemVer property, which can be seen here:

C:\Users\Tim\source\repos\TA.DigitalDomeworks [release/7.1 ↑1 +0 ~1 -0 !]> gitversion
{
  "Major":7,
  "Minor":1,
  "Patch":0,
  "PreReleaseTag":"beta.3",
  "PreReleaseTagWithDash":"-beta.3",
  "PreReleaseLabel":"beta",
  "PreReleaseNumber":3,
  "BuildMetaData":"",
  "BuildMetaDataPadded":"",
  "FullBuildMetaData":"Branch.release/7.1.Sha.77fa2c96ed9b0f5ab162d07052ef094e8ccfc8c5",
  "MajorMinorPatch":"7.1.0",
  "SemVer":"7.1.0-beta.3",
  "LegacySemVer":"7.1.0-beta3",
  "LegacySemVerPadded":"7.1.0-beta0003",
  "AssemblySemVer":"7.1.0.3",
  "FullSemVer":"7.1.0-beta.3",
  "InformationalVersion":"7.1.0-beta.3+Branch.release/7.1.Sha.77fa2c96ed9b0f5ab162d07052ef094e8ccfc8c5",
  "BranchName":"release/7.1",
  "Sha":"77fa2c96ed9b0f5ab162d07052ef094e8ccfc8c5",
  "NuGetVersionV2":"7.1.0-beta0003",
  "NuGetVersion":"7.1.0-beta0003",
  "CommitsSinceVersionSource":3,
  "CommitsSinceVersionSourcePadded":"0003",
  "CommitDate":"2018-09-10"
}

So the final filename I'd like to see is:

TA.DigitalDomeworks.Installer-7.1.0-Beta.3.msi

In the GitVersion documentation, it say that I need to make sure the GitVersion.GetVersion build task has executed, after which I should be able to obtain the full SemVer from a build property called $(GitVersion_FullSemVer).

However, I'm not sure how to achieve that in a WiX project, since installing the GitVersionTask NuGet package doesn't seem to do anything (in C# projects, everything just magically works). If I could get to the point where I can execute the GitVersion.GetVersion task, then I think I can see my way clear to getting the output name I want.

Has anyone got this working? Or can anyone offer any advice on how to approach this?

Tim Long
  • 13,508
  • 19
  • 79
  • 147
  • Note: it is apparently a bad idea to vary the output name of an installer if it is planned to use minor upgrades. However, I only ever use major upgrades in my installers so I can live with that limitation. – Tim Long Dec 30 '18 at 02:00

2 Answers2

6

I figured it out. I was on the right lines to start with. There's no need to manually execute GitVersion.GetVersion, this is handled correctly by MSBuild once the GitVersionTask NuGet package is installed in the WiX project. The reason it wasn't working is because I was trying to use GitVersion's properties before they had been set.

So, first thing is to create a couple of properties that disable some unwanted GitVersion actions:

  <PropertyGroup>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <WriteVersionInfoToBuildLog>false</WriteVersionInfoToBuildLog>
    <GenerateGitVersionInformation>false</GenerateGitVersionInformation>
  </PropertyGroup>

We can't simply change the OutputName property because that is set before any tasks (including GitVersion tasks) execute, so if we try to use the GitVersion properties in there, they will be empty/unset because the GitVersion targets haven't executed yet. Instead, we have to put some logic into a build target, the obvious candidate being the BeforeBuild target that is usually found at the end of the project file:

  <Target Name="BeforeBuild" AfterTargets="GetVersion">
    <CreateProperty Value="$(OutputName).$(GitVersion_SemVer)">
      <Output TaskParameter="Value" PropertyName="TargetName" />
    </CreateProperty>
    <CreateProperty Value="$(TargetName)$(TargetExt)">
      <Output TaskParameter="Value" PropertyName="TargetFileName" />
    </CreateProperty>
    <CreateProperty Value="$(TargetDir)$(TargetFileName)">
      <Output TaskParameter="Value" PropertyName="TargetPath" />
    </CreateProperty>
  </Target>

Here we use the OutputName property as a base name and augmented it with the desired GitVersion properties, to create the TargetName, TargetFileName and TargetPath properties that will be used in the rest of the build process. This works because the BeforeBuild task is guaranteed to execute before any output file is generated, so all the Target* properties will be set before then.

Tim Long
  • 13,508
  • 19
  • 79
  • 147
1

Let's see if this solves your problem

My approach goes thus:

Add the following to your main assembly project, not the wix project

<Target Name="WriteVersionToFile" AfterTargets="GetVersion">
        <WriteLinesToFile File="$(OutputPath)version.txt" Lines="$(GitVersion_FullSemVer)" Overwrite="true" Encoding="Unicode" /> 
</Target>

Then replace your BeforeBuild target with this sample in your wix project

<Target Name="BeforeBuild">
    <ReadLinesFromFile File="$(SolutionDir)BuildOutput\$(Configuration)\version.txt">  
        <Output TaskParameter="Lines" ItemName="Version" />  
    </ReadLinesFromFile>
    <CreateProperty Value="$(OutputName).$(Version)">
      <Output TaskParameter="Value" PropertyName="TargetName" />
    </CreateProperty>
    <CreateProperty Value="$(TargetName)$(TargetExt)">
      <Output TaskParameter="Value" PropertyName="TargetFileName" />
    </CreateProperty>
    <CreateProperty Value="$(TargetDir)$(TargetFileName)">
      <Output TaskParameter="Value" PropertyName="TargetPath" />
    </CreateProperty>
  </Target>

The solution adds the GitVersion_FullSemVer property to a text file after the GetVersionTask is run. This data is then used in the wix project for versioning the msi file.

koolkoda
  • 365
  • 3
  • 6
  • Thanks for the suggestion. This might have worked, but I didn't want to write out a text file if I could avoid it. I hate using the file system as a temporary variable! Luckily, I figured out what I think is a more elegant solution and I have posted it as a separate answer. – Tim Long Dec 30 '18 at 02:05