0

I created a task in our C# Projects to auto-version projects when they are built (changes are made) in release mode. The versioning part works perfectly. However, all the projects are being built regardless if the project actually changed when done from command line. This causes projects to be versioned unnecessarily. Building in Visual Studio works, unchanged projects are not built, however we made a tool to do automated build using msbuild.exe and are using this as a temporary fix while we work on Bamboo and that method always does a blind build, even if there are no changes to the project. I need to be able to identify if changes were made to the project.

Something like

'$(wasSourceUpdated)' == 'true' or some kind of target condition to use on my custom versioning target.

Here is a sample of my versioning task in our projects

<Import Project="..\..\DXT.BuildTasks\Targets\DXTAutoIncrementVersion.targets" Condition="Exists('..\..\DXT.BuildTasks\Targets\DXTAutoIncrementVersion.targets') And '$(Configuration)|$(Platform)' == 'Release|AnyCPU' And '$(DeployOnBuild)' != 'true'" />

I also checked this and this articles to no avail.

EDIT

I need the task to run before the build is actually executed in order to stamp the generated assemblies with the new versions

EDIT 2

What I'm really looking for is the condition to run CoreCompile or to run CoreCompile again when I detect that the assembly was updated

What I've tried so far:

<Project>
<PropertyGroup>
    <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup>
    <_AssemblyTimestampBeforeCompile>%(IntermediateAssembly.ModifiedTime)</_AssemblyTimestampBeforeCompile>
</PropertyGroup>
<PropertyGroup>
    <_AssemblyTimestampAfterCompile>%(IntermediateAssembly.ModifiedTime)</_AssemblyTimestampAfterCompile>
</PropertyGroup>
<PropertyGroup>
    <_ProjectVersioned Condition="'$(_ProjectVersioned)'==''">false</_ProjectVersioned>
</PropertyGroup>
<Target Name="IncrementVersionBeforeBuild" AfterTargets="CoreCompile" Condition="'$(_AssemblyTimestampBeforeCompile)'!='$(_AssemblyTimestampAfterCompile)' and '$(_ProjectVersioned)' == 'false'">
 <Message Text="Before $(_AssemblyTimestampBeforeCompile) After $(_AssemblyTimestampAfterCompile)" Importance="High"/>
    <IncrementVersion
  ProjectPath="$(MSBuildProjectFullPath)"
    VersionRule="3.3.0.+"
    FileName="Properties\AssemblyInfo.cs">
    </IncrementVersion>
</Target>
<PropertyGroup>
    <TaskPath>$(MSBuildThisFileDirectory)..\Tasks\AutoVersionTask\AutoVersionTask\bin\Debug</TaskPath>
</PropertyGroup>
<!-- Sample import for projects
<Import Project="..\..\DXT.BuildTasks\Targets\DXTAutoIncrementVersion.targets" Condition="Exists('..\..\DXT.BuildTasks\Targets\DXTAutoIncrementVersion.targets') And '$(Configuration)|$(Platform)' == 'Release|AnyCPU' And '$(DeployOnBuild)' != 'true'" />
-->
<UsingTask AssemblyFile="$(TaskPath)\AutoVersionTask.dll" TaskName="AutoVersionTask.IncrementVersion" />

<PropertyGroup>
    <_ProjectVersioned>true</_ProjectVersioned>
</PropertyGroup>

Thanks in advance

Community
  • 1
  • 1
Kaizer69
  • 373
  • 4
  • 18
  • Have you use post-build-event and when will execute the auto-version task? After build and before publish? – LoLance May 23 '19 at 02:05
  • The auto-version task runs just before the build. Publish is skipped since it can cause the auto version task to run twice on publish – Kaizer69 May 23 '19 at 14:51

2 Answers2

1

So Thanks to Lance for getting me to understand MSBuild to the point that I understand the issue way better.

After a long time researching the default task, I ran upon this question that had the perfect solution to my issue. After applying the fix the versioning task now only runs when changes are made to the msbuild code.

The inputs and outputs are the same as the CoreCompile target and ensures that the task is only run if there were changes to the source

Here is the target I ran that works:

<?xml version="1.0" encoding="utf-8"?>
<Project>
    <PropertyGroup>
        <CoreCompileDependsOn>
        $(CoreCompileDependsOn);
        IncrementVersionBeforeBuild
        </CoreCompileDependsOn>
    </PropertyGroup>
    <Target Name="IncrementVersionBeforeBuild"
            Inputs="$(MSBuildAllProjects);
            @(Compile);                               
            @(_CoreCompileResourceInputs);
            $(ApplicationIcon);
            $(AssemblyOriginatorKeyFile);
            @(ReferencePath);
            @(CompiledLicenseFile);
            @(EmbeddedDocumentation); 
            $(Win32Resource);
            $(Win32Manifest);
            @(CustomAdditionalCompileInputs)"
            Outputs="@(DocFileItem);
             @(IntermediateAssembly);
             @(_DebugSymbolsIntermediatePath);                 
             $(NonExistentFile);
             @(CustomAdditionalCompileOutputs)"
    >
        <Message Text="Version Task running" Importance="High"/>
        <IncrementVersion
      ProjectPath="$(MSBuildProjectFullPath)"
        VersionRule="3.3.0.+"
        FileName="Properties\AssemblyInfo.cs">
        </IncrementVersion>
    </Target>
    <PropertyGroup>
        <TaskPath>$(MSBuildThisFileDirectory)..\Tasks\AutoVersionTask\AutoVersionTask\bin\Debug</TaskPath>
    </PropertyGroup>
    <UsingTask AssemblyFile="$(TaskPath)\AutoVersionTask.dll" TaskName="AutoVersionTask.IncrementVersion" />

    <PropertyGroup>
        <_ProjectVersioned>true</_ProjectVersioned>
    </PropertyGroup>
</Project>
Kaizer69
  • 373
  • 4
  • 18
  • Hi friend, thanks for sharing your solution here. You can consider marking it as answer so that other members with similar issue could find the solution easily! – LoLance May 27 '19 at 07:08
  • It didn't let me do it last time and I forgot to mark it again earlier. Thanks for your help Lance – Kaizer69 May 28 '19 at 15:22
0

Normaly, we can add the script below into .csproj file:

  <PropertyGroup>
    <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
  </PropertyGroup>
  <Target Name="AutoVersionWhenBuild" AfterTargets="CoreBuild"
          Condition="'$(_AssemblyTimestampBeforeCompile)'!='$(_AssemblyTimestampAfterCompile)'">
    <Message Importance="high" Text="Auto-version begins when changes are made!"/>
    <!--<AutoVersionTask>Do your auto-version task here.</AutoVersionTask>-->
  </Target>

It will be called during the build when changes are really made to the project. See this similar issue.

As for your situation:

It seems your tasks and target comes from the targets file DXTAutoIncrementVersion.targets,you can open that file and change the target in it to the format above.

In addition: Please check the relationship between tasks, targets and .targets file.

1.MSBuild uses tasks to perform these actions.

2.Targets group tasks together.

3.MSBuild includes several .targets files that contain items, properties, targets, and tasks for common scenarios.

So you can either modify your auto-version target in the xx.targets file, or use the script above, and call the auto-version task in the AutoVersionWhenBuild target. Hope it helps:)

LoLance
  • 25,666
  • 1
  • 39
  • 73
  • Hi Lance, Thanks for the answer! I'll be trying it out and will update this question. I did make the custom target since we are using it in multiple project files. – Kaizer69 May 23 '19 at 13:40
  • Hi Lance, it seems there was a misunderstanding, the task needs to run before the build, not after. We need the version to be updated on the created binaries. – Kaizer69 May 23 '19 at 14:52
  • @Kaizer69 Sorry for the misunderstanding, I'm researching this. Maybe it takes some time :( – LoLance May 24 '19 at 05:38
  • Thanks Lance, no worries I'm researching it too but I'm just looking for help – Kaizer69 May 24 '19 at 13:44