Msbuild ignoring build errors - msbuild

Context
I have a task integration testing and code coverage which I execute in my jenkins pipeline.
The tools used is dotcover and Nunit.
Nunit is executed throught dotcover during the integration test build when the configuration is Integration.
Problem
When I execute the configuration Integration in visual studio with some tests in error, then the build failed, everything are ok, but when the same configuration are executed with msbuild, it doesn't return any error code then jenkins pipelin doesn't fail.
The situation put us in delicate way because we can't trust our build pipeline anymore.
I looking for a solution on web for some days and I still on the same point, it's why I asking for your help here.
Thank you for helping.
Files
jenkinsfile
node('BUILD_PROJECT') {
stage ('Checkout')
{
checkout scm
}
stage ('Build')
{
bat '"C:/Program Files (x86)/NuGet/nuget.exe" restore -NonInteractive MySolution.sln'
bat "\"C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/MSBuild/15.0/Bin/MSBuild.exe\" /p:Configuration=Release;AssemblyVersion=0.1.0.${env.BUILD_NUMBER} /maxcpucount:8 MySolution.sln"
}
stage ('Integration')
{
bat "\"C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/MSBuild/15.0/Bin/MSBuild.exe\" /p:Configuration=Integration /maxcpucount:8 MySolution.sln"
}
stage ('Publish Coverage')
{
publishHTML target: [
allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: true,
reportDir: 'Solution/IntegrationProject/bin/Integration/TestResult',
reportFiles: 'ProjectCoverageReport.html',
reportName: 'Project Coverage Report'
]
}
stage ('Setup')
{
bat "\"C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/MSBuild/15.0/Bin/MSBuild.exe\" /p:Configuration=Setup;Platform=x86;AssemblyVersion=0.1.0.${env.BUILD_NUMBER} /maxcpucount:8 MySolution.sln"
}
stage ('Archive')
{
archiveArtifacts artifacts: 'Solution/SetupProject/bin/x86/Setup/MySetup.exe'
}
}
In IntegrationProject.csproj
<Target Name="CoverageReport" AfterTargets="CopySqlFiles" Condition="$(Configuration) == Integration">
<Exec Command="..\packages\JetBrains.dotCover.CommandLineTools.2018.1.3\tools\dotCover.exe analyse /TargetExecutable=..\packages\NUnit.ConsoleRunner.3.8.0\tools\nunit3-console.exe /ReturnTargetExitCode /TargetArguments="$(TargetPath)" /Filters=-:nunit.framework;-:IntegrationProjectTest;-:type=MyNamespace.View.*;-:type=*Test /TargetWorkingDir=$(TargetDir) /Output=$(TargetDir)\TestResult\MyCoverageReport.html /ReportType=HTML" />
</Target>

You should be able to make use of the dotcover parameter ReturnTargetExitCode to get the return code from nunit.
<Target Name="CoverageReport" AfterTargets="CopySqlFiles" Condition="$(Configuration) == Integration">
<Exec Command="..\packages\JetBrains.dotCover.CommandLineTools.2018.1.3\tools\dotCover.exe analyse ^
/TargetExecutable=..\packages\NUnit.ConsoleRunner.3.8.0\tools\nunit3-console.exe ^
/ReturnTargetExitCode ^
/TargetArguments="$(TargetPath)" ^
/Filters=-:nunit.framework;-:IntegrationProjectTest;-:type=MyNamespace.View.*;-:type=*Test ^
/TargetWorkingDir=$(TargetDir) ^
/Output=$(TargetDir)\TestResult\MyCoverageReport.html ^
/ReportType=HTML
/ReturnTargetExitCode">
<Output TaskParameter="ExitCode" PropertyName="DotCoverExitCode" />
</Exec>
<Message Text="Unit Tests Failed!" Condition="$(DotCoverExitCode) != '0'"/>
</Target>

Related

Jenkins pipeline executing msbuild.exe (2019) build.xml - The batch file cannot be found

pipeline {
agent { label 'Apps' }'''
environment {
MSBUILD_4_PATH = "c:\\WINDOWS\\Microsoft.NET\\Framework\\v4.0.30319\\msbuild"
MSBUILD_2019_PATH = "c:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Current\\Bin\\MSBuild.exe"
GLOBAL_SETTINGS = "\\PATH\\TO\\msbuild_settings"
BUILD_TYPE = "Dev"
// ------
}
stage('Build Infra - Release and Test') {
steps {
dir("${env.WORKSPACE}/${BRANCH_NAME}/Infra/Build"){
bat '''
set DevEnvDir="c:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\IDE\\"
"%MSBUILD_2019_PATH%" Build.xml /p:GlobalSettings=%GLOBAL_SETTINGS%;BUILD_TYPE=%BUILD_TYPE%;SC=GIT;MSBuildCommunityTasksPath="C:\\Program Files (x86)\\MSBuild\\MSBuildCommunityTasks";ExtensionTasksPath="C:\\\\Program Files (x86)\\\\MSBuild\\\\ExtensionPack\\\\4.0\\\\" /t:ReleaseAndTest
'''
}
}
}
Please help, cant find root cause of the problem
Log finished with:
375 Warning(s)
0 Error(s)
Time Elapsed 00:04:54.35
The batch file cannot be found.
Cant realize if the problem is with Jenkins pipeline or MsBuild itself
stage never finished... stack
Tried many different options and still stack

Nunit.framework dll from the package doesnt get copied to bin folder

I'm currently running .net framework 4.6 and added the NUnit, NUnit3TestAdapter nuget package to the test project that i am working on and I see that the test's are not being discovered.
Upon some investigtion, I see that nunit.framework.dll is not being copied to the bin folder. Did some more research and I see the following in the assets.json file, and Nunit's build/NUnit.props file which is supposed to have the MSBuild settings is empty and does not have any.
"NUnit/3.13.3": {
"type": "package",
"compile": {
"lib/net45/nunit.framework.dll": {}
},
"runtime": {
"lib/net45/nunit.framework.dll": {}
},
"build": {
"build/NUnit.props": {}
}
},
However Nbuild/Unit3TestAdapter.props file which is installed from the official Nunit has the MSBuild settings. Is there a reason why build/NUnit.props does not have the build setting where as build/Unit3TestAdapter.props has these?
Also, Is there a work-around to get these copied to local or should I add the reference's manually than getting these from the package?

AssemblyName property in Directory.Build.targets has no effect

I am trying to override the AssemblyName property defined in .NET projects in my Azure Pipeline. (The purpose is to standardize assembly names for NuGet packages.)
It works when I create a Directory.Build.props file right before building with MSBuild.
The problem is that this only works if the AssemblyName has not been defined in the .csproj file. Otherwise the .csproj property takes precedence.
According to the docs, I should be able to use Directory.Build.targets to override .csproj properties:
https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2022#choose-between-adding-properties-to-a-props-or-targets-file
If you need to override properties, do it in a .targets file, after
all user-project customizations have had a chance to take effect.
This is what the Directory.Build.targets file contains:
<Project>
<Target Name="IncludeProjectMatchMessage" Condition="$(MSBuildProjectName) == ''${{ parameters.projectName }}''" BeforeTargets="Build">
<Message Text="The custom Directory.Build.targets properties will be applied to this project $(MSBuildProjectName), AssemblyName = $(packageName)" Importance="high" />
</Target>
<PropertyGroup Condition="$(MSBuildProjectName) == ''${{ parameters.projectName }}''">
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Company>MyCompany</Company>
<AssemblyName>$(packageName)</AssemblyName>
</PropertyGroup>
</Project>
I have also tried this, with the same result:
<Project>
<Target Name="IncludeProjectMatchMessage" Condition="$(MSBuildProjectName) == ''${{ parameters.projectName }}''" BeforeTargets="Build">
<Message Text="The custom Directory.Build.targets properties will be applied to this project $(MSBuildProjectName), AssemblyName = $(packageName)" Importance="high" />
<PropertyGroup Condition="$(MSBuildProjectName) == ''${{ parameters.projectName }}''">
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Company>MyCompany</Company>
<AssemblyName>$(packageName)</AssemblyName>
</PropertyGroup>
</Target>
</Project>
The text message is displayed during the MSBuild, but the properties are not applied.
Why is that, and how do I fix it?
I could not get .targets to work, nor could I find any documentation on the properties that it is possible to override using this method.
Instead, I added a PS script that modifies the .csproj file directly:
- task: PowerShell#2
displayName: Modify .csproj file
inputs:
targetType: 'inline'
script: |
# This script will overwrite csproj properties that are already defined.
# If they are not defined, no changes are made - values are not added.
# The case of missing properties is handled by adding a .props file in the next step.
# Note that changing the assembly name may break the build when the library contains xaml files.
# Read more below.
$path = "$(projectFolder)\${{ parameters.projectName }}.csproj"
Write-Host "Reading project file: " $path
[xml]$xml =(gc $path)
$projectAssemblyName = $xml.Project.PropertyGroup.AssemblyName
Write-Host "AssemblyName: " $projectAssemblyName
if ($projectAssemblyName -like "$(packageName)")
{
Write-Host "AssemblyName corresponds to package name."
}
else
{
Write-Host $projectAssemblyName "is different from package name:" $(packageName)
Write-Host "Overwriting AssemblyName with " $(packageName)
$xml.Project.PropertyGroup |? AssemblyName |% {$_.AssemblyName="$(packageName)"}
}
$xml.Project.PropertyGroup |? Company |% {$_.Company="MyCompany"}
$xml.Project.PropertyGroup |? GenerateDocumentationFile |% {$_.GenerateDocumentationFile="True"}
$xml.Save($path)
$fileContent = Get-Content $path
Write-Host "Success. File contents: " $fileContent

Setting IntelliJ compiler args in Gradle

I need to add the -parameters java compiler parameter for my tests to succeed. I can do this in gradle already for ./gradlew build to work, or manually by adding -parameters under IntelliJ Settings > Build.. > Compiler > Java Compiler > Additional command line parameters: so they work in the IDE, but I don't want everyone who checks out this repo to have to do a manual step.
My .ipr file does show
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_STRING" value="-parameters" />
</component>
after setting it manually, but is it possible to configure the idea plugin in gradle so ./gradlew idea just does all the work?
It's possible to do that with the new "Proof-of-concept" plugin from JetBrains:
gradle-idea-ext-plugin with following configuration:
idea.project.settings {
compiler {
javac {
javacAdditionalOptions "-parameters"
}
}
}
You can modify the ipr file as XML and add the component node. The official documentation has an example how to do this:
idea.project.ipr {
withXml { provider ->
provider.node.component
.find { it.#name == 'VcsDirectoryMappings' }
.mapping.#vcs = 'Git'
}
}
But you will be limited to the IDEA file project structure (as opposed to the .idea directory structure).

Gulp task to web deploy from Visual Studio

I have not found a concrete example on how to do the publishing via a Gulp Task. Anyone has an idea?
This is how i'm trying at the moment.
gulp.task("Deploy-To-Azure", function() {
var targets = ["Build"];
console.log("Publishing to Azure");
return gulp.src(["./src/Feature/Accounts/code"])
.pipe(foreach(function (stream, file) {
return stream
.pipe(debug({ title: "Building project:" }))
.pipe(msbuild({
targets: targets,
configuration: "Azure",
logCommand: false,
verbosity: "verbose",
stdout: true,
errorOnFail: true,
maxcpucount: 0,
toolsVersion: 14.0,
properties: {
DeployOnBuild: "true",
DeployDefaultTarget: "Web Deploy",
WebPublishMethod: "FileSystem",
DeleteExistingFiles: "false",
_FindDependencies: "false",
Configuration: "Release"
}
}))
.pipe(debug({title: "Finished building project"}));
}));
});
But it looks like the project is built but not deployed. I think my properties are not complete. Any ideas are appreciated. Thank you
I attempted to use those same MSBuild properties from the commandline and received the following error:
>c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild /p:DeployOnBuild=true /p:WebPub
lishMethod=FileSystem /p:DeleteExistingFiles=false /p:DeployDefaultTarget="Web Deploy"
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.P
ublishing.targets(4449,11): error MSB4057: The target "Web Deploy" does not exi
st in the project. [c:\users\me\documents\visual studio 2015\projects\w
ebapplication12\WebApplication12.csproj]
Unless you've created a custom MSBuild Target named "Web Deploy". This won't work.
When I remove the /p:DeployDefaultTarget="Web Deploy" property a WebDeploy package is created in the /obj/[configuration]/Package folder.
Try DeployDefaultTarget: "WebPublish"