Manage Environment Variables during a TFS / VSTS Build

To avoid creating unnecessary build definition, it is a best practice to allow for parameter overriding in every task that can be executed from a build. I’ve dealt on how to parametrize tests to use a different connection string when tests are executed during the build and I’ve used Environment variables for a lot of reasons.

Environment variables are not source controlled, this allows every developer to override settings in own machine without disturbing other developers. If I do not have a MongoDb in my machine I can simply choose to use some other instance in my network.

image

Figure 1: Overriding settings with environment variables.

Noone in the team is affected by this settings, and everyone has the freedom of changing this value to whatever he/she like. This is important because you can have different version of MongoDb installed in your network, with various different configuration (MMapV1 or Wired Tiger) and you want the freedom to choose the instance you want to use.

Another interesting aspect of Environment variables, is that they can be set during a VSTS/TFS build directly from build definition. This is possible because Variables defined for a build were set as environment variables when the build runs.

image

Figure 2: Specifing environment variables directly from Variables tab of a bulid

If you allow this value to be allowed at Queue Time, you can set the value when you manually queue a build.

image

Figure 3: Specifying variables value at Queue Time

If you look at Figure 3, you can verify that I’m able to change the value at queue time, but also, I can simply press “Add variable” to add any variable, even if it is not included in build definition. In this specific situation I can trigger a build and have my tests run against a specific MongoDb instance.

Remember that the value specified in the build definition overrides any value that is set on environment variables on build machine. This imply that, once you set a value in the Build definition, you are not able to change the value for a specific build agent.

It you want to be able to choose a different value for each build agent machine you can simply avoid setting the value on the Variables tab and instead define the variable on each build machine to have a different value for each agent. Another alternate approach is using two Environment variables, Es: TEST_MONGODB and TEST_MONGODB_OVERRIDE, and configure your tests to use TEST_MONGODB_OVERRIDE if present, if not present use TEST_MONGODB. This allows you to use TEST_MONGODB on build definition, but if you set TEST_MONGODB_OVERRIDE for a specific test agent, that agent will use that value.

Another interesting aspect of Environment Variable is that they are included in agent capabilities, as you can see from Figure 4.

SNAGHTMLd39383

Figure 4: All environment variables are part of agent Capabilities

This is an important aspect because if you want that variable to be set in the agent, you can avoid to include in Variables tab, and you can require this build to be run on an agent that has TEST_MONGODB environment variable specified.

image

Figure 5: Add a demand for a specific Environment Variable to be defined in Agent Machine

Setting the demands is not always necessary, in my example if the TEST_MONGODB variable is not definied, tests are executed against local MongDb instance. It is always a good strategy to use a reasonable default if some setting is not present in Environment Variables.

Gian Maria.

Published by

Ricci Gian Maria

.Net programmer, User group and community enthusiast, programmer - aspiring architect - and guitar player :). Visual Studio ALM MVP

4 thoughts on “Manage Environment Variables during a TFS / VSTS Build”

  1. Hi Gian,

    Have you ever experienced values in the agents list of capabilities taht do NOT appear when you loop through all environment variables? I have a capability that I think comes from SSDT, called SqlPackage and it contains a complete path to an executable. It shows in the Capabilities page for each of my agents, but when I add a task that displays all environment variables, it is not shown and I can not call it from my custom tasks.

    Do you know of any “hidden capabilities”? Or an option to get those exposed in some way? I could illustrate with some screenshots if you like. How can I get this SqlPackage variable to be used in my tasks?

    Thanks in advance!

  2. Actually the capability of Agents are not stored as Environment Variables in the build. The only solution you have is manually add that variable in the machine with the agent.

    In future update of the agent, capabilities should be visibile as variables inside script of the build agent, but in actual version they are not.

  3. Hi Ricci
    Just wondering if we can set a machine level environment variable using a build task ( powershell ) while executing build using the hosted agent.
    My scripts are throwing permission errors on the following code:

    [Environment]::SetEnvironmentVariable(“JUSTMOCK_INSTANCE”, 1, “Machine”)
    [Environment]::SetEnvironmentVariable(“COR_ENABLE_PROFILING”, 1, “Machine”)
    [Environment]::SetEnvironmentVariable(“COR_PROFILER”, “{B7ABE522-A68F-44F2-925B-81E7488E9EC0}”, “Machine”)
    [Environment]::SetEnvironmentVariable(“COMPLUS_ProfAPI_ProfilerCompatibilitySetting”, “EnableV2Profiler”, “Machine”)
    [Environment]::SetEnvironmentVariable(“COR_PROFILER_PATH”, $FilePath32, “Machine”)

    While the same script run very well for Process or User level environment variables.

  4. I think that in hosted build machines you have no rights to change machine environment variables. You should be able to change only user level variables. After all, hosted build machines are shared between accounts

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.