10

Setting up a Pipeline build in Jenkins (Jenkins 2.6), copying the sample script for a git-based build gives: "no tool named MSBuild found". I have set MSBuild Tool in Manage Jenkins -> Global Tool Configuration. I am running pipeline on the slave node.

In Slave configuration, I have set MSBuild tool path in Node Properties -> Tool Locations.
While build process it is not able to get MSBuild tool path, if i run same source without pipeline (without using Jenkinsfile) it works fine.


Please see Jenkinsfile Syntax

pipeline {
    agent { label 'win-slave-node' }
    stages {
           stage('build') {
           steps {

           bat "\"${tool 'MSBuild'}\" SimpleWindowsProject.sln /t:Rebuild /p:Configuration=Release"
           }
    }
   }
}



I have also tried to change environment variable for windows slave it not refreshed.


NOTE: I have installed MS Build tool for on slave node

Atul N
  • 811
  • 1
  • 8
  • 20
  • Have you checked the console on which agent it was running while you are building. – Chandra Sekhar Y Jul 31 '17 at 14:44
  • Can you check this once "node('win-slave-node') { def MSBuild MSBuild= tool 'MSBuild' stage('Build') { bat(/"${MSBuild}" SimpleWindowsProject.sln /t:Rebuild /p:Configuration=Release/) } }" – Chandra Sekhar Y Jul 31 '17 at 14:59
  • Above is the same code with minor changes try once to check whether working/not – Chandra Sekhar Y Jul 31 '17 at 15:00
  • Can you check to make sure you called the tool `MSBuild`? You have it referenced one I'm above as "MBuild", without an S. – Kdawg Aug 01 '17 at 04:16
  • @Chandra Sekhar: Thanks for the code, but it is not working, the issue is not with code, it showing empty string on MSBuild variable. I have set vs2017 env variable by running vcvars64.bat in Jenkinsfile – Atul N Aug 03 '17 at 06:09
  • @Kdawg it was a typo in the question, I have updated question. still facing the same problem. – Atul N Aug 03 '17 at 06:18
  • Hmm... Have you checked the console output like the first commenter recommended to make sure it is actually building on the node that you think it's building on? Maybe provide some screenshots of your global and node tool config? – Kdawg Aug 03 '17 at 14:14

5 Answers5

15

In Declarative Pipeline syntax, the tooling for MSBuild is a little clunkier. Here's how I've had to handle it, using a script block:

pipeline {
  agent { 
    label 'win-slave-node'
  }
  stages {
    stage('Build') {
      steps {
        script {
          def msbuild = tool name: 'MSBuild', type: 'hudson.plugins.msbuild.MsBuildInstallation'
          bat "${msbuild} SimpleWindowsProject.sln"
        } 
      } 
    } 
  } 
} 

In the older Scripted Pipeline syntax, it could be like this:

node('win-slave-node') {
  def msbuild = tool name: 'MSBuild', type: 'hudson.plugins.msbuild.MsBuildInstallation'

  stage('Checkout') {
    checkout scm
  }

  stage('Build') {
    bat "${msbuild} SimpleWindowsProject.sln"
  }
}
Nick Jones
  • 4,395
  • 6
  • 33
  • 44
  • 4
    Thanks @nick for above solution, finally it is working with msbuild tool, with small modification in command `bat "\"${msbuild}\" SimpleWindowsProject.sln"` As i was getting **error** `C:\Program' is not recognized as an internal or external command` due to space in MSBuild path – Atul N Aug 10 '17 at 09:27
  • 1
    Yes, we avoided that particular space problem by using the old-style folder name, e.g., the 32-bit MSBuild from Visual Studio 2013 is here: C:\PROGRA~2\MSBuild\12.0\Bin\MSBuild.exe. – Nick Jones Aug 11 '17 at 13:09
  • Can't you just use the msbuild definition from Global Tools? – Caltor Dec 12 '19 at 13:36
  • @Caltor the msbuild definition from Global Tools is exactly what `def msbuild = tool name: 'MSBuild', type: 'hudson.plugins.msbuild.MsBuildInstallation'` is using. – Nick Jones Dec 12 '19 at 15:37
  • @NickJones How is that different to ‘${tool 'MSBuild'}’ which seems a lot easier? Genuine question – Caltor Dec 13 '19 at 23:57
  • @Caltor there's not a major difference; your example syntax is not explicitly specifying the _type_ of tool so would pick up whatever tool has the _name_ 'MSBuild' (regardless of type), and you're using a ${} expression to evaluate it to a string immediately. Your example could specify the type too: `${tool name: 'MSBuild', type: 'msbuild'}`. (My syntax uses a fully-qualified tool type, which is just a product of the age of my original answer.) – Nick Jones Dec 16 '19 at 17:31
8

For anyone having this problem and just trying to figure out what 'Tool' represents in Jenkins and where it is configured, see following screenshots:

Go to Manage Jenkins -> Global Tool Configuration:
Global Tool Configuration


Scroll down to MSBuild and click the button to expand the section:
MSBuild tool installations


Here you can see what tool name to use to reference MSBuild (or add one):
MSBuild tool name


Then you can reference it for example like this: bat "\"${tool '15.0'}\" solution.sln /p:Configuration=Release /p:Platform=\"x86\" (example is not declarative syntax, but should show the idea)

jumbo
  • 4,670
  • 5
  • 39
  • 44
  • 1
    please rather use a more descriptive name (not only a version number!): ${tool 'MSBuild 15.0 [32bit]'} – Alexander Stohr Jun 28 '19 at 08:59
  • Jenkins complains when you put the full path to the exe into the tool configuration. If you put just the path to the folder instead it won't complain but you then have to append \\msbuild.exe in the JenkinsFile as per some of the other answers and comments on this page. – Caltor Dec 12 '19 at 13:39
5

You have to define MSBuild in Jenkins => Manage Jenkins => Global Tool Configuration or use a different toolname which is already defined.

${tool 'toolname'}  returns the path defined for a tool in Global Tool Configuration.

Warning: Pay attention to the path defined. Does it point to a folder or to msbuild.exe? You might have to append msbuild.exe:

 ${tool 'VS2017'}\msbuild.exe

A simple snapshot for explaining the concept: How to use Jenkins tool paths in scripts

addmoss
  • 622
  • 10
  • 14
3

While the provided answer certainly works, you just have to provide the correct complete tool name.

In our Installation, we had three different MSBuild versions available and I could just use the following

${tool 'MSBuild 15.0 [32bit]'}

pfeigl
  • 457
  • 5
  • 12
  • 4
    in our case, it was `${tool '14.0'}`, and returned path to msbuild, so we used it like this `\"${tool '14.0'}\\msbuild.exe\"` – d.Candela Jun 19 '18 at 13:12
0

We have to define msbuild which is installed in Global Tool Configuration in script block

stage('App_Build'){ steps{ tool name: 'MsBuild', type: 'msbuild' bat ""${tool 'MsBuild'}"My.Service.sln /t:Rebuild /p:Configuration=Release" } }

This will work