Teamcity build loops on successful build - msbuild

I have set up a build with Teamcity. See my build file below.
When the build is succesful and the tests pass, the build process just runs again and again indefinitely in a loop.
When the build fails, this does not happen.
I have tried to first set 60 second pause on buildtriggering, and finally disabled build triggering altogether. No difference.
What else could be the cause of this?
My MSBuild file looks like this:
<Project DefaultTargets="Build;Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<DeployDirectory>$(MSBuildProjectDirectory)\..\bin</DeployDirectory>
<DependencyDirectory>$(MSBuildProjectDirectory)\Dependencies</DependencyDirectory>
<LinqToSqlMapFolder>$(DeployDirectory)\LinqToSql</LinqToSqlMapFolder>
<NCoverVersionForMSI>$(BUILD_NUMBER)</NCoverVersionForMSI>
<NCoverVersionPeriod>$(BUILD_NUMBER)</NCoverVersionPeriod>
</PropertyGroup>
<ItemGroup>
<ProjectFiles Include="**\*.vbproj"/>
<ConfigFiles Include="**\*.config"/>
<MapFiles Include="**\*.linqtosql.config"/>
<TestAssemblies Include="$(DeployDirectory)\*.Test.dll"/>
<Dependencies Include="$(DependencyDirectory)\**\*" />
</ItemGroup>
<Target Name="Clean">
<MSBuild Projects="#(ProjectFiles)" Targets="Clean"/>
</Target>
<Target Name="Build">
<MSBuild Projects="#(ProjectFiles)" Targets="Rebuild">
<Output TaskParameter="TargetOutputs" ItemName="BuildOutput"/>
</MSBuild>
<Copy SourceFiles="#(BuildOutput)" DestinationFolder="$(DeployDirectory)" />
<Copy SourceFiles="#(Dependencies)" DestinationFolder="$(DeployDirectory)" SkipUnchangedFiles="true" />
<Copy SourceFiles="#(ConfigFiles)" DestinationFolder="$(DeployDirectory)" SkipUnchangedFiles="true" />
<Copy SourceFiles="#(MapFiles)" DestinationFolder="$(LinqToSqlMapFolder)" SkipUnchangedFiles="true" />
</Target>
<UsingTask AssemblyFile="$(DependencyDirectory)\Gallio\Gallio.MsBuildTasks.dll" TaskName="Gallio" />
<Target Name="Test">
<Gallio IgnoreFailures="true" Files="#(TestAssemblies)">
<Output TaskParameter="ExitCode" PropertyName="ExitCode"/>
</Gallio>
</Target>
</Project>

While it appears that this wasn't your issue, I ran into a similar looping problem of my own. I had enabled labeling in the project configuration. I was also using a check for modifications every 60 seconds rule to trigger the build. As a result, upon successful build, TeamCity would tag the build in the VCS and then 60 seconds later, it would see (it's own) modification and trigger another build.
To fix our problem, we just disabled labeling because we didn't want it anyways, but you can also configure a rule to ignore particular authors such that it won't trigger on modifications it made.

It appears there were some problems with the install of teamcity, and a backup of configuration following a reinstall solved the problem with exactly same configuration and buildscript.

Related

Target with AfterTargets="Publish" executes in unpublishable project

I have a project in my solution that I wanna publish separately from the rest of the solution. So the way to skip it is by setting the IsPublishable property to false, which works like a charm. It seems though that no matter the publishable status of the project, targets set to run after the publish target (AfterTargets="Publish") are still executed when I try to publish the entire solution.
Is this intended? Is there any way to prevent this? I am using VS 2022 preview.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<LangVersion>9.0</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<BaseOutputPath>..\Build</BaseOutputPath>
<IsPublishable>false</IsPublishable>
</PropertyGroup>
<ItemGroup>
<SomeFiles Include="$(SolutionDir)SomeFiles\**\*.txt" />
</ItemGroup>
<Target Name="CopyCustomContentBuild" AfterTargets="AfterBuild">
<Copy SourceFiles="#(SomeFiles)" DestinationFolder="$(TargetDir)SomeFiles" />
<Message Text="Files copied successfully." Importance="high" />
</Target>
<Target Name="CopyCustomContentPublish" AfterTargets="Publish">
<Copy SourceFiles="#(SomeFiles)" DestinationFolder="$(PublishDir)SomeFiles" />
<Message Text="Files copied successfully to publish dir." Importance="high" />
</Target>
</Project>
That is the intended behaviour. When you set IsPublishable to false MsBuild still logs when a Publish target is supposed to run and continues onto your AfterTargets="Publish" target.
You'll have to set a condition on your actions inside the target to make sure they do not get executed when IsPublishable is false.
<Target Name="CopyCustomContentPublish" AfterTargets="Publish">
<Copy SourceFiles="#(SomeFiles)" DestinationFolder="$(PublishDir)SomeFiles" Condition=" '$(IsPublishable)' == 'true' " />
<Message Text="Files copied successfully to publish dir." Importance="high" Condition=" '$(IsPublishable)' == 'true' " />
</Target>

wixproj/msbuild program creating automatically unwanted folder in the solution tree

I want to remove folder from my deployment folder.
I'm using removedir task.
<ItemGroup>
<FolderToExcludefromDeploymentFolder Include="$(SourceDir)\Support" />
</ItemGroup>
<Target Name="BeforeBuild" BeforeTargets="Build">
<RemoveDir Condition="Exists('$(sourceDir)\Support')" Directories="#(FolderToExcludefromDeploymentFolder)" />
</Target>
In that case i get a folder in the solution tree.
In case of trying to delete the folder i get this error and the itemgroup element will automatically will be removed.
How can i fix this?
The only way I could fix this issue is to move all problematic properties to BeforeBuild target and set them as DefineConstants.
<Target Name="BeforeBuild">
<PropertyGroup>
<SourceDir>$(MSBuildProjectDirectory)..\..\..\Example</SourceDi>
<FolderToExclude>$(MSBuildProjectDirectory)..\..\..\Example\Support</FolderToExclude>
<DefineConstants>$(DefineConstants);SourceDir=$(SourceDir);FolderToExclude=$(FolderToExclude)</DefineConstants>
</PropertyGroup>
<RemoveDir Condition="Exists('$(sourceDir)\Support')" Directories="#(FolderToExclude)" />
</Target>
This solution worked for me but didn't find the reason behind this.

Calling MSbuild Publish

Is it possible to call MSbuild publish during build or in pre-buildevent or in post-buildevent? I'm trying to publish two of the web projects from a solution. I'm using file system publishing.Requirement here is , building solution should take care of publish those two web projects. Can any one please suggest ?
I wouldn't put too much deploy logic in a post-build event. It becomes "fragile".
Create a separate .msbuild file, and do the "extra" logic in it, instead of messing too much with the .csproj file.
Below is a basic example.
Place the xml below in an file call "MyBuildAndDeploy.msbuild", put it in the same folder as your .sln (or .csproj) file, and then use
msbuild.exe "MyBuildAndDeploy.msbuild" from the command line.
So below is a basic example of building the primary solution and then copying the files somewhere.
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapper">
<PropertyGroup>
<!-- Always declare some kind of "base directory" and then work off of that in the majority of cases -->
<WorkingCheckout>.</WorkingCheckout>
<BuildResultsRootFolder>$(WorkingCheckout)\..\BuildResults</BuildResultsRootFolder>
</PropertyGroup>
<Target Name="AllTargetsWrapper">
<CallTarget Targets="BuildSolution" />
<CallTarget Targets="CopyBuildOutputFiles" />
</Target>
<Target Name="BuildSolution">
<MSBuild Projects="$(WorkingCheckout)\MySuperCoolSolution.sln" Targets="Build" Properties="Configuration=$(Configuration)">
<Output TaskParameter="TargetOutputs" ItemName="TargetOutputsItemName"/>
</MSBuild>
<Message Text="BuildSolution completed" />
</Target>
<Target Name="CopyBuildOutputFiles">
<MakeDir Directories="$(BuildResultsRootFolder)\$(Configuration)" Condition="!Exists('$(BuildResultsRootFolder)\$(Configuration)\')"/>
<ItemGroup>
<BuildOutputFilesExcludeFiles Include="$(WorkingCheckout)\**\*.doesnotexist" />
<BuildOutputFilesIncludeFiles Include="$(WorkingCheckout)\**\*.dll" Exclude="#(BuildOutputFilesExcludeFiles)" />
<BuildOutputFilesIncludeFiles Include="$(WorkingCheckout)\**\*.exe" Exclude="#(BuildOutputFilesExcludeFiles)" />
<BuildOutputFilesIncludeFiles Include="$(WorkingCheckout)\**\*.config" Exclude="#(BuildOutputFilesExcludeFiles)" />
<BuildOutputFilesIncludeFiles Include="$(WorkingCheckout)\**\*.pdb" Exclude="#(BuildOutputFilesExcludeFiles)" />
</ItemGroup>
<Copy SourceFiles="#(BuildOutputFilesIncludeFiles)"
DestinationFolder="$(BuildResultsRootFolder)\$(Configuration)\"/>
</Target>
</Project>

I want to run a task for al files and exclude those who did not change

I have two buildtargets to check my code quality.
I run the following buildtargets every time i compile. This takes up too much time and i would like them to only check the files that did change.
In other words i want to filter files that did not change from the ItemGroup CppCheckFiles / LinterFiles.
<Target Name="CppCheck">
<ItemGroup>
<CppCheckFiles Include="*main.c" />
<CppCheckFiles Include="Source/*/*.c" />
</ItemGroup>
<Message Text="$(Configuration) starting." Importance="High" />
<Exec Command="C:\Cppcheck\cppcheck.exe %(CppCheckFiles.FullPath) --enable=style --template="{file}({line}): error:{severity}-{id}: {message}"" />
</Target>
<Target Name="SPLint">
<ItemGroup>
<LinterFiles Include="*main.c" />
<LinterFiles Include="Source/*/*.c" />
<LinterFiles Include="Source/*/*.h" />
</ItemGroup>
<Message Text="$(Configuration) starting." Importance="High" />
<Exec Command="splintCaller %(LinterFiles.FullPath)" />
</Target>
I know that the regular build process does this and i wonder if i have to go so fas as to write my own task.
hmm.. this sounds interesting. I can't help you. But it would be nice if the cppcheck wiki or manual had some small example project that did this.
Some people use cppcheck in commit hooks. I've tried it with GIT myself (I added a linux shell script). And there is a TortoiseSVN plugin you can try (http://sourceforge.net/apps/phpbb/cppcheck/viewtopic.php?f=3&t=443).
The solution is incremental Build. Where MSBuild compares Timestamps to exclude complete Buildtargets if nothing changed.
The following target creates a timesstamp for each file and skippes those files that did not change.
cppcheck.exe returns -1 if an error was detected and the timestamp is not written.
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="CppCheck" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<CppCheckFiles Include="*main.c" />
<CppCheckFiles Include="Source/*/*.c" />
</ItemGroup>
<Target Name="CppCheck"
Inputs="#(CppCheckFiles)"
Outputs="CCPCheck\%(CppCheckFiles.Filename)%(CppCheckFiles.Extension).stamp">
<Exec Command="C:\Cppcheck\cppcheck.exe %(CppCheckFiles.FullPath) --enable=style --template="{file}({line}): error:{severity}-{id}: {message}"" />
<MakeDir Directories="CCPCheck"/>
<Touch Files="CCPCheck\%(CppCheckFiles.Filename)%(CppCheckFiles.Extension).stamp" AlwaysCreate = "true" />
</Target>
</Project>

Msbuild compile website without placing the site in IIS

I am trying to create a msbuild script that will compile and place a test app into a folder on my desktop. I do not want this app published to IIS. I have followed several blgos and looked through hashimi's book but I still cannot figure this out. Below is my script. Thank you very much!
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Clean">
<ItemGroup>
<BinFiles Include="bin\*.*" />
</ItemGroup>
<Delete Files="#(BinFiles)" />
</Target>
<Target Name="Compile" DependsOnTargets="Clean">
<MSBuild Projects="test.vbproj"/>
</Target>
<Target Name="Publish" DependsOnTargets="Compile">
<RemoveDir Directories="$(OutputFolder)"
ContinueOnError="true"/>
<MSBuild Projects="test.vbproj"
targets="ResolveReferences;_CopyWebApplication"
Properties="WebProjectOutputdir=$(OutputFolder; OutDir=$WebProjectOutputDir)\"/>
</Target>
</Target>
</Project>
Your script is a bit awkward (you redefined the clean target to do the same as the the basic clean target).
I'm pretty sure your problem comes from the CopyWebApplication which does lots of stuff according to the properties set in your project file and pass by command line.
Can you try the following script :
<Project DefaultTargets="Compile" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Compile">
<MSBuild
Projects="test.vbproj"
Targets="Clean;Build"
Properties="OutputPath=C:\tmp"/>
</Target>
</Project>
if your test project is a website then the build target should create it on the folder specified in the OutputPath/OutDir property