msbuild-plugin should implement SimpleBuildStep to allow tighter workflow integration.

          [JENKINS-26948] Workflow compatibility for MsBuildBuilder

          Jesse Glick added a comment -

          Plan of record is to use JENKINS-37011 for such things.

          Jesse Glick added a comment - Plan of record is to use JENKINS-37011 for such things.

          I was hoping to use msbuild-plugin in a declarative pipeline so that it would automatically check the output for warnings and mark the build as unstable if there are any. As that did not work, I had to use a bat step instead and lost the support for warnings. Now though, I have added the /fileloggerparameters option to the MSBuild command line and parse the log file afterwards with warnings-plugin. I find that the ability of warnings-plugin to compare the warnings of consecutive builds is more useful than just flagging whether there were any warnings at all, particularly when legacy source code is being built. As such, I now consider the bat step the right way to run MSBuild, rather than just a workaround.

          Kalle Niemitalo added a comment - I was hoping to use msbuild-plugin in a declarative pipeline so that it would automatically check the output for warnings and mark the build as unstable if there are any. As that did not work, I had to use a bat step instead and lost the support for warnings. Now though, I have added the /fileloggerparameters option to the MSBuild command line and parse the log file afterwards with warnings-plugin. I find that the ability of warnings-plugin to compare the warnings of consecutive builds is more useful than just flagging whether there were any warnings at all, particularly when legacy source code is being built. As such, I now consider the bat step the right way to run MSBuild, rather than just a workaround.

          kon I use the exact same setup right now.
          It's probably the best solution while msbuild plugin is not pipeline compatible.
          However you lose some advantages like the capacity to define a different path for the msbuild tool on the slaves you use. The plug-in could also be easier to use. I started working on making it pipeline ready and you could use it by simply writing "msbuild" in its simplest form (assuming msbuild.exe is in the path and you're running it from the directory containing your solution file).
          If you would like to keep the warnings plug-in behavior, you will still have to use /fileloggerparameters option so using the msbuild plug-in doesn't make a clear cut difference against a bat step in my opinion. But I guess it's true for any tool when you start using command line parameter extensively.

          Lionel Cabasson added a comment - kon I use the exact same setup right now. It's probably the best solution while msbuild plugin is not pipeline compatible. However you lose some advantages like the capacity to define a different path for the msbuild tool on the slaves you use. The plug-in could also be easier to use. I started working on making it pipeline ready and you could use it by simply writing "msbuild" in its simplest form (assuming msbuild.exe is in the path and you're running it from the directory containing your solution file). If you would like to keep the warnings plug-in behavior, you will still have to use /fileloggerparameters option so using the msbuild plug-in doesn't make a clear cut difference against a bat step in my opinion. But I guess it's true for any tool when you start using command line parameter extensively.

          marshall777, I actually used to configure MSBuild versions in msbuild-plugin but then make Jenkinsfile look up one of them with the tool step and use the result in a bat step. However, because there is no standard on how the MSBuild versions should be named in the Jenkins configuration, and because MSBuild 4.0 comes with .NET Framework, I decided it's less error-prone to hardcode the path in Jenkinsfile, so that it doesn't have to be configured in each Jenkins master instance.

          For later versions of MSBuild that come with Visual Studio, I think the best way is to run vswhere (which could be a custom tool) and derive the path of MSBuild.exe from its output. This too can be done with bat steps but I don't think msbuild-plugin presently supports this kind of lookup.

          Kalle Niemitalo added a comment - marshall777 , I actually used to configure MSBuild versions in msbuild-plugin but then make Jenkinsfile look up one of them with the tool step and use the result in a bat step. However, because there is no standard on how the MSBuild versions should be named in the Jenkins configuration, and because MSBuild 4.0 comes with .NET Framework, I decided it's less error-prone to hardcode the path in Jenkinsfile, so that it doesn't have to be configured in each Jenkins master instance. For later versions of MSBuild that come with Visual Studio, I think the best way is to run vswhere (which could be a custom tool ) and derive the path of MSBuild.exe from its output. This too can be done with bat steps but I don't think msbuild-plugin presently supports this kind of lookup.

          Kalle Niemitalo added a comment - - edited

          For later versions of MSBuild that come with Visual Studio, I think the best way is to run vswhere (which could be a custom tool) and derive the path of MSBuild.exe from its output.

          I put this in one stage:

                      environment {
                          VSWHERE_DIR = tool(type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool', name: 'vswhere')
                      }
          

          Then this as the first step:

                          script {
                              // The @ sign prevents CMD.EXE from echoing the command and
                              // thus messing up the JSON output.
                              def VisualStudioInstances = readJSON(
                                  text: bat(
                                      script: '@"%VSWHERE_DIR%\\vswhere.exe" -products Microsoft.VisualStudio.Product.BuildTools Microsoft.VisualStudio.Product.Professional -requires Microsoft.Component.MSBuild -format json',
                                      returnStdout: true))
          
                              def VisualStudioInstallationPath = VisualStudioInstances[0].installationPath
                              echo "Using Visual Studio from ${VisualStudioInstallationPath}"
                              env.VSDEVCMD_BAT = VisualStudioInstallationPath + '\\Common7\\Tools\\vsdevcmd.bat'
                          }
          

          And the step to run MSBuild:

                          bat 'CALL "%VSDEVCMD_BAT%" && MSBuild.exe /property:Platform="Any CPU",Configuration="Release" /target:Restore;Build "SOLUTION.sln"'
          

          The projects in this solution use PackageReference rather than packages.config, so Jenkinsfile can use /target:Restore instead of locating and running nuget.exe.

          This seems to work but a few things could be improved:

          • Error handling, if no matching version of Visual Studio has been installed.
          • Also recognize Enterprise, Express, and Community editions. Perhaps it's best to say -products *.
          • Perhaps move to a sharable pipeline library.

          Kalle Niemitalo added a comment - - edited For later versions of MSBuild that come with Visual Studio, I think the best way is to run vswhere (which could be a custom tool) and derive the path of MSBuild.exe from its output. I put this in one stage: environment { VSWHERE_DIR = tool(type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool' , name: 'vswhere' ) } Then this as the first step: script { // The @ sign prevents CMD.EXE from echoing the command and // thus messing up the JSON output. def VisualStudioInstances = readJSON( text: bat( script: '@ "%VSWHERE_DIR%\\vswhere.exe" -products Microsoft.VisualStudio.Product.BuildTools Microsoft.VisualStudio.Product.Professional -requires Microsoft.Component.MSBuild -format json' , returnStdout: true )) def VisualStudioInstallationPath = VisualStudioInstances[0].installationPath echo "Using Visual Studio from ${VisualStudioInstallationPath}" env.VSDEVCMD_BAT = VisualStudioInstallationPath + '\\Common7\\Tools\\vsdevcmd.bat' } And the step to run MSBuild: bat 'CALL "%VSDEVCMD_BAT%" && MSBuild.exe /property:Platform= "Any CPU" ,Configuration= "Release" /target:Restore;Build "SOLUTION.sln" ' The projects in this solution use PackageReference rather than packages.config , so Jenkinsfile can use /target:Restore instead of locating and running nuget.exe . This seems to work but a few things could be improved: Error handling, if no matching version of Visual Studio has been installed. Also recognize Enterprise, Express, and Community editions. Perhaps it's best to say -products * . Perhaps move to a sharable pipeline library.

          Michael Fowler added a comment - - edited

          I have a PR open here: https://github.com/jenkinsci/msbuild-plugin/pull/36 to add pipeline support.

          Michael Fowler added a comment - - edited I have a PR open here: https://github.com/jenkinsci/msbuild-plugin/pull/36  to add pipeline support.

          Wrong link?

          Antony Gelberg added a comment - Wrong link?

          Amit Dar added a comment -

          I see the last entry in this log is from last year.

          Is someone still working on this issue? this is a major feature we are looking in our company...

          Amit Dar added a comment - I see the last entry in this log is from last year. Is someone still working on this issue? this is a major feature we are looking in our company...

          Jesse Glick added a comment -

          this is a major feature we are looking [for]

          For what it is worth, see my discussion.

          Jesse Glick added a comment - this is a major feature we are looking [for] For what it is worth, see my discussion .

          Tilo added a comment - - edited

          I've implemented this feature in the latest release. Your feedback would be greatly appreciated.

          pipeline {
              agent any
              tools {
                  msbuild 'MSBuild 2022'
              }
              stages {
                  stage('Build') {
                      steps {
                          script {
                              bat 'msbuild right-first-time.sln /p:Configuration=Release %MSBUILD_ARGS%'
                          }
                      }
                  }
              }
          } 

          Tilo added a comment - - edited I've implemented this feature in the latest release. Your feedback would be greatly appreciated. pipeline { agent any tools { msbuild 'MSBuild 2022' } stages { stage( 'Build' ) { steps { script { bat 'msbuild right-first-time.sln /p:Configuration=Release %MSBUILD_ARGS%' } } } } }

            mdkf Michael Fowler
            nharniman Nigel Harniman
            Votes:
            39 Vote for this issue
            Watchers:
            45 Start watching this issue

              Created:
              Updated:
              Resolved: