How can I reference an environment variable in TFS build configuration? - tfs

I have set an environment variable on my system named MSBUILD_HOME that points to the directory that contains the msbuild.exe.
I want to reference this environment variable in the TFS build configuration. Specifically, I want to reference it in the Build->Advanced->Path to MSBUILD field of an MSBuild configuration step.
I have tried: MSBUILD_HOME, $(MSBUILD_HOME), %MSBUILD_HOME% but nothing works and I've Googled this to death. What am I missing?

Doh! I just needed to restart the build agent to pick up the changes to the environment. Using $(MSBUILD_HOME) was the right way to reference it.

Related

Referencing BuildNumber in 2015 Xaml Builds

We are moving from tfs 2012 to tfs 2018 and converting our XAML build templates to 2015.
For the most part, using the default build template TfvcTemplate12 work well. However when a project references the build number, it fails.
One example is when we use the windows service publish task.
<WindowsServicePublishTask Publish="$(DeployFileService)" ServiceDisplayName="$(ServiceDisplayName)" Destinations="$(ServiceDestinations)" SourcePath="$(OutDir)" BuildNumber="$(BuildNumber)" CreateDropFolder="$(CreateDropFolder)" />
I get the following error
The "WindowsServicePublishTask" task was not given a value for the required parameter "BuildNumber".
How can I reference the build number using TfvcTemplate12?
You are using the wrong environment variables. For XAML build:
TF_BUILD_BUILDNUMBER The build number of the build. For example: CIBuild_20130613.6.
More details please refer TF_BUILD environment variables
You can use the TF_BUILD environment variables to get key bits of data that you need for your build process logic. For example, you can get the path to the source folder or the path to the folder that contains the outputs you want to drop.
TF_BUILD environment variables
Use environment variables in MSBuild
Use environment variables in programs or scripts
Use environment variables in a custom build process
A sample of adding something like the following options to the MSBuild arguments:
/p:DeployOnBuild=true;DeployMethod=Package /p:DefaultPackageOutputDir=”$(TF_BUILD_BINARIESDIRECTORY)”\WebPackage

How does TFS determine what directory to use for the output from a build?

I'm setting up some TFS build definitions. I see that once I run a build, the work is done within a subfolder of a subdirectory of /Agent/_work. It appears that the subfolder is the same between different executions of the same build definition, but I see no way to know in advance where I should expect TFS to set its working directory, nor do I see any way of specifying the name of the directory manually.
How does TFS determine what directory to use for the output from a build?
Refer to the documentation on build variables. The base folder can be accessed via the $(Agent.BuildDirectory) variable. The source folder is $(Build.SourcesDirectory).
You can't set this. It's determined by the agent's configuration.

Jenkins drops a letter from file paths

We have a Code Composer Studio (Eclipse) project that uses CMAKE to generate makefiles and build. The project compiles as expected when the project is manually imported onto the Jenkins slave (Win10 x64) and executed from the command line but fails when the build is handled by Jenkins. The failure always follows the same pattern: a singular letter is dropped from the path of an object file. For example, [Repo directory]/Cockpit_Scaling_and_Exceedance_data.dir becomes [Repo direcory]/Cockpit_Scaling_and_Exceedance_ata.dir and linking fails because it cannot find the referenced object file.
I made sure that there are no differences between the account environment variables and the system environment variables and have also configured the Jenkins Service to use the admin account on the slave instead of SYSTEM in order to get rid of as many differences between Jenkins and the command line as possible.
The project will build successfully using one of our other Jenkins slaves (also Win10 x64), so we know that it's not a Windows 10 issue or a problem with our Jenkins configuration. Since I can't find any differences between the configuration of the two slave machines, I was hoping that someone might be able to suggest somewhere to look for this path issue.
I never found out why the paths to object files were being mangled, but I did get the project to build successfully on the slave via Jenkins. All I did was change all of my system environment variables into user environment variables. I copy-pasted, so I know that the variables themselves did not change.
I have no idea why this corrected this issue as I had inserted a whoami call at the beginning of the build to confirm that Jenkins is indeed running as a user and not System. I guess from this point on all of my environment variables will be specific to a user and not SYSTEM...
EDIT: The problem has returned. I have made no further progress in tracking down the cause behind this issue, but I have found that I do not see this symptom when running the scripts in a bash environment instead of a Windows command prompt. Fortunately for me the scripts have all been written in such a way that they can be run in both environments, so I have had my coworkers use bash instead for them.

TFS Build GetBuildDirectory and Store it

I'm trying to get a TFS current build directory path but it's not working. I've tried this:
Microsoft.TeamFoundation.Build.Activities.Extensions.WellKnownEnvironmentVariables.BuildDirectory
I see it printing right path with "GetBuildDirectory" Step (in the diagnostics log), but How would I store this information into a variable?
ANSWER:
There have been TF_BUILD environment variables.You can use the TF_BUILD environment variables to get key bits of data that you need for your build process logic. More from MSDN: Team Foundation Build environment variables
You could just reference the TF_BUILD_BUILDDIRECTORY to get The build agent working directory. For example: C:\Build\BuildBot3\CoolApp\CIBuild.

How to declare a global variable in Jenkins and use it in an MSBuild task within each individual project

I am converting our CI platform from CruiseControl to Jenkins, and can't seem to figure something out that seems like it should be relatively simple to do (Disclaimer - I'm no CI or build automation expert, but this was dumped into my lap and I find it interesting)
In CruiseControl, I am able to declare variables like this:
<cb:define rootdir="J:\SOURCES\" />
<cb:define logdir="J:\SOURCES\buildlogs" />
<cb:define iisdir="J:\IIS\" />
<cb:define artifacts="artifacts\" />
Then use them as part of an MSBuild task
<msbuild>
<executable>C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
<workingDirectory>$(rootdir)$(ProjectName)</workingDirectory>
<projectFile>$(ProjectName).sln</projectFile>
<buildArgs>/p:BuildDate="1";OutDir="$(iisdir)$(ProjectName)\bin\\";WebProjectOutputDir="$(iisdir)$(ProjectName)\\"</buildArgs>
<targets>Rebuild;$(ProjectName)</targets>
<timeout>180</timeout>
<logger>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
If the root or IIS directories change, it can easily be applied to all projects at once. We have ~60 projects setup, so doing this project by project would be very time consuming. Migrating this to Jenkins, the MSBuild command line arguments now look like this (partial sample but includes what is relevant):
OutDir="J:\IIS\ProjectName\bin\\";WebProjectOutputDir="J:\IIS\ProjectName\\"
The IIS directory is hard coded. I need that to be something more like this:
OutDir="${IIS_DIR}\ProjectName\bin\\";WebProjectOutputDir="${ITEM_ROOTDIR}\ProjectName\\"
Is there a way to do that? I tried the configuration slicing plugin, which is useful, but doesn't fit this need from what I see
You can do this with built-in Jenkins' functionality:
Then you need to expand your variable. This, actually, depends on where you would use it.
For example: %MSBuild% and %IIS_DIR% for "Execute windows batch command" build step. Other build steps (and plugins) may use it differently.
For global variables, you need EnvInject plugin. This allows you (among other things) to setup variables at the Global (node) level, at job level or as a step. You can set variables directly, or from properties file, or from scripts.
Once set, the variables are available as environment variables to the rest of Jenkins and its steps (within scope).
For passing arguments to MSBuild, when you configure an MSBuild step, there is an option to pass "Command line arguments" in the format /p:Param=Value.
The "value" could be an environment variable. On Windows environment you would reference it as %myvar%
So, if you configure a global GLOBAL_IIS_DIR=C:\path\to\IIS using EnvInject, you can then reference it on command line with /p:IIS_DIR=%GLOBAL_IIS_DIR%

Resources