Setting Cached Agent Environment Variable During Run

(luke) #1

We have conditional compilation that is determined by a system environment variable. The variable is set at the top of a local final builder project, that is also shared with Ci.

We have noticed the Ci caches the system environment variables are the start of the stage. We set the system environment variable through a script, and then do a ‘Continua Ci set variable’ and ‘set variable’ immediately after. They all share the same variable name. The local final builder variable has ‘Make environment variable’ enabled. However, the cached environment variable in the agent property (i.e. ContinuaCi.AgentProperty.Env.BuildVersion) is not updated to match the system.

Can you please advise us on how we can sync the Agent Properties with the System.

Thanks for your help in advance!

Ci Version:
Final Builder Version:

(Dave Sparks) #2

Hi Luke,

It’s not clear what you are trying to do here. When you set an environment variable in one Windows process it is not available to another, so setting an environment variable in a FinalBuilder action will not be picked up by Continua CI.

If you are trying to set a Continua CI variable from FinalBuilder you can use the Continua CI - Set Variable action available in FinalBuilder 8, or send a custom log message to stdout.

If you need to pass set a FinalBuilder variable from Continua CI, specify the variable name and value in the Variables tab of the FinalBuilder action.

The agent property ContinuaCi.AgentProperty.Env.BuildVersion is the value of user or machine environment variable on the agent, picked up by a property collector run on the agent every 30 seconds. It cannot pick up any changes to process environment variables set in a Finalbuilder action.

We recommend that you update your versions of Continua CI and FinalBuilder as we cannot provide proper support for such old versions.

(luke) #3

Thanks for the reply Dave, perhaps I need to explain our problem better, sometimes I struggle to explain my problem well…

We have a final builder project, foo.fbp7, that runs a batch script to set an environment variable on the system, whose value is dependent on some user flags. This variable is propagated to a C# constant through property sheets later on, and used conditional compilation.

Final builder is responsible for accepting user input, and executing the batch to setup the system environment variables. The same project is responsible for building .NET projects that uses this C# constant.

We have discovered this only works when ran locally on Final builder, but not when the Final Builder project is ran on the Ci through an agent. When ran through the Ci Agent, it seems the agent takes a snapshot of the systems environment variable list before our foo.fbp7 is executed, and caches them as ‘Agent Properties’. Consequently when foo.fbp7 is ran, and our batch script is executed, the systems environment variable list is updated, but the agent property is not, so when VC15 comes round to setting up our constant, the wrong value is used - The one in the agent properties, and not in the system…

We are looking for a way to sync the system environment variables and the agents .Env agent properties while a final builder project is running on a Ci agent.

Hope that makes more sense

(Dave Sparks) #4

What action in FinalBuilder (or Continua CI) is looking at the agent properties?

(luke) #5

The variables are in the log when the action ‘Log Variable Values’ is executed in Final Builder. It displays local variables and ContinuaCI.AgentProperty variables when ran through a Final Builder project on Ci.

The system environment variables look like they are cached in sub-properties of the ContinuaCI.AgentProperty.Env property group.

(Dave Sparks) #6

What do you need ContinuaCI.AgentProperty.Env for?

(luke) #7

We want the environment variable set through the batch script to be visible to the .NET solution built in Final Builder on the Ci agent.

Our testing suggests the Agent property.Env. is being used instead, which unfortunately reflects the snapshot before the project is ran. As a result, the first run uses an old value which is incorrect, when the Agent property is not updated after our batch script is ran. It uses the correct one on the second run, when the Agent property matches the parameter set by our batch script. The system environment variable list shows what we expect before, during and after the Final Builder project is ran.

(Dave Sparks) #8

The agent properties are updated every 30 seconds using a property collector which gets the values of user and machine variables on the agent. You cannot assume that they are up to date. I don’t understand why you are using the agent property to get the value of the environment variable?

So the FinalBuilder project is running a batch file, maybe running SETX to set a MACHINE environment variable? The value of this environment variable is needed by a VC15 action? Is this action in the same FinalBuilder project another FinalBuilder project, or run directly from Continua CI? Can you describe the actions you have in FinalBuilder and Continua CI?

(luke) #9

Thanks for the update. We are not - We resolve Environment Variables the standard way in our .NET property sheets… $(OurEnvironmentVariable). Locally this is evaluated correctly when working directly in Visual Studio, or running foo.fbp7. On the Ci, it is evaluated the same as the AgentProperty.Env…

Yes, batch script is simply running setx with two parameters. A project inside the x64 Visual Studio solution requires it to do some conditional compilation as part of our work flow. Yes, the only difference on Ci, is that it is running foo.fbp7 as a ‘Final Builder’ action. Ci does no more steps in this test.

We set the system variable before 30s at the start of the script, but we can gaurentee the first project requiring this macro is built 15-20mins later.

Edit: I noticed the AgentProperties are logged by our FinalBuilder actions at 19:02:52 and 19:17:47. The SETX is executed on 19:02:40.

Both 19:02 and 19:17 logs produce the same results (with different timestamps ofc)…

19:02:40 Run DOS Command / Batch File [ …\SetEnvironmentVariable.bat BuildVersion R5 ]
19:02:40 Executing external process: C:\Windows\system32\cmd.exe
19:02:40 Parameters: /c …\SetEnvironmentVariable.bat BuildVersion R5
19:02:40 Output from C:\Windows\system32\cmd.exe
19:02:40 …\DevelopmentSetup\FinalBuilder>setx BuildVersion R5
19:02:40 SUCCESS: Specified value was saved.

Log Variable Values [All Variables]
19:17:47 All variable values :
19:17:47 ATIDefines_Contents = // This file is dynamically generated by FinalBuilder.
19:17:47 // These Graphics settings are for: Non-ATI-only (Cruise control DLL not used, so other GPUs are supported)
19:17:47 #undef ENABLE_ATI_SETUP
19:17:47 BuildVersion = R5
19:17:47 ConfirmCleanBuild = True
19:17:47 ContinuaCI.AgentProperty.Env.BuildVersion = R6

(Dave Sparks) #10

Everything appears to be working fine in your log. BuildVersion is set to R5 at 19:02:40 and BuildVersion is logged as R5 at 19:17:47. ContinuaCI.AgentProperty.Env.BuildVersion - a environment variable which is set when the FinalBuilder action starts remains unchanged.

I still don’t get what you are trying to do.

Are you trying to change a Continua CI agent property from a FinalBuilder script? If so why?

Are you trying to persist environment variables after the FinalBuilder action has been run for use by another Continua action, or another Continua build?

Agent properties are mainly for use on the server for deciding which agent to run builds on. A copy of all agent properties is transferred from the server to the agent at the start of the stage. These are available for reference by stage actions but cannot be updated by them.

A copy of all current user and machine environment variables is taken at the start of each stage and these are added to each Continua action process via Process.StartInfo.EnvironmentVariables.

We do not pick up any changes to environment variables between Continua actions. We recommend using build variables to pass values between actions.

If you let us know how you want things to work, we’ll see whether that is possible.

(Dave Sparks) #11

Maybe the problem is that $(BuildVersion) in the property sheet somehow picks up the environment variable ContinuaCI.AgentProperty.Env.BuildVersion instead of BuildVersion because it ends with the same suffix?

If you clear the option Generate system environment variables on the FinalBuilder action in ContinuaCI, then the environment variable ContinuaCI.AgentProperty.Env.BuildVersion will not set.

(luke) #12

This is incorrect in our eyes. ContinuaCI.AgentProperty.Env.BuildVersion should always reflect the value of BuildVersion, and our testing suggests this is causing the value “R6” to be propagated to all our .NET projects built on the Ci final builder project.

We are not doing anything explicitly with ContinuaCI.AgentProperty, we have just noticed when there is a mismatch between ContinuaCI.AgentProperty.Env.BuildVersion and BuildVersion on the user environment varaibles, our build is failing because the wrong BuildVersion constant value is propagated.

Edit: Sorry replied to the message in my inbox. Yes, I believe the property sheet is somehow picking this up. I will try the Generate system environment variables and let you know how it goes, thanks.

(Dave Sparks) #13

ContinuaCI.AgentProperty.Env.BuildVersion does not mirror BuildVersion. It’s a different variable. What I don’t understand is how it is propagated to your other projects?

(luke) #14

Thanks, that’s interesting, perhaps we have set something up incorrectly - We assumed it was caching the system variables.

I will investigate this, thanks.

(luke) #15

Sorry Dave, I understand what you are saying now. Yes, BuildVersion is a Final Builder project variable, so it should not match ContinuaCI.AgentProperty.Env.BuildVersion at first glance. However we execute our environment variable batch script with this variable as a parameter, so our Final Builder node is…

…\SetEnvironmentVariable.bat BuildVersion %BuildVersion%

Which evaluates as…

…\SetEnvironmentVariable.bat BuildVersion R5

So yes, The ContinuaCI.AgentProperty.Env.BuildVersion shouldn’t reflect BuildVersion at first glance, but after the batch is executed it should do.

This is shown in the logs at 19:02:40, where %BuildVersion% is evaluated as R5.

I will try the ‘Generate system environment variables’ next…

(Dave Sparks) #16

I don’t know what is in your batch file but SETX BuildVersion R5 only updates the user-level environment variable BuildVersion, SETX BuildVersion R5 /m only updates the system-level environment variable BuildVersion and SET BuildVersion=R5 only updates the process-level environment variable BuildVersion.

Neither of these commands updates the process-level environment variable ContinuaCI.AgentProperty.Env.BuildVersion. If, for some reason, you want to update the process-level environment variable ContinuaCI.AgentProperty.Env.BuildVersion, put SET ContinuaCI.AgentProperty.Env.BuildVersion=R5 in your batch file.

Again, ContinuaCI.AgentProperty.Env.BuildVersion is a process-level environment variable set at the start of the FinalBuilder action process when Generate system environment variables is ticked. It contains a copy of the value of the agent property Env.BuildVersion at the start of the stage. The agent property in turn contains the value of the ‘BuildVersion’ environment variable the last time the agent properties were collected from the agent. Any change to this process-level variable will not be persisted at the end of the FinalBuilder process. It’s not really useful for your build process.

Maybe you can send a copy of your FinalBuilder project and related batch file so we can see what you are trying to do?

(luke) #17

Thanks Dave, it looks like disabling ‘Generate system environment variables’ solved the problem. It looks like the .NET constant was resolving ContinuaCI.AgentProperty.Env.BuildVersion instead of the User Environment Variable.

Thanks for the help, much appreciated.