Ensure TOML feature flags are used and take precedence over job env

What does this MR do?

Previously setting the FF_USE_DIRECT_DOWNLOAD and FF_USE_FASTZIP feature flags in the runner TOML would have no effect because the runner did not properly export these flags to the artifact and cache helper environment. This was happening because:

  1. Build.Settings() initializes the settings by calling GetAllVariables().

  2. GetAllVariables() sets all the variables to the default values of the feature flags. This result is cached.

  3. populateFeatureFlags sets the internal state of the feature flags by considering the TOML values, but GetAllVariables() isn't updated to reflect that.

  4. The build helpers write out the environment based on the state of GetAllVariables(), which don't consider the TOML values.

To fix this, we need to update GetAllVariables() to add the state of the feature flags once the state has been resolved.

Note that checking the feature flag state with Build.IsFeatureFlagOn() worked fine because it used the data from populateFeatureFlags.

With this change, this exposes another inconsistency: GetAllVariables() simply appends the job variables to the end, which causes feature flags in the job environment to take precedence over the TOML values. However, Build.IsFeatureFlagOn() ensures that the TOML always takes precedence.

We fix this by adding two phases when resolving job variables:

  1. The first phase generates an array of job variables with the default feature flags set first with all other variables appearing after that.
  2. The second phase resolves the state of the feature flags, taking into account the TOML, and inserts the resolved values into a new set. Any subsequent job variable that matches a feature flag name is filtered.

Why was this MR needed?

Two reasons:

  1. Admins were unable to set FF_USE_DIRECT_DOWNLOAD and FF_USE_FASTZIP in the TOML, even though the runner output suggested the feature flags were set one way.
  2. Job variables could override the TOML values.

What's the best way to test this MR?

  1. In the TOML, add:
log_level = "debug"

  [runners.feature_flags]
  FF_USE_FASTZIP = true
  FF_USE_DIRECT_DOWNLOAD = false
  1. Run a CI job with this runner. In the debug logs you should be able to see these lines buried in the eval statements:
export FF_USE_FASTZIP=true
export FF_USE_DIRECT_DOWNLOAD=false
  1. Now in the CI Job try to override those values:
variables:
  FF_USE_FASTZIP: "false"
  FF_USE_DIRECT_DOWNLOAD: "true"
  1. Run a CI job again, and you should see the values have not changed:
  feature flags: FF_USE_DIRECT_DOWNLOAD:false, FF_USE_FASTZIP:true

You can confirm that in the debug logs too.

  1. Now drop the TOML settings and try to override the values:
  FF_USE_FASTZIP: "true"
  FF_USE_DIRECT_DOWNLOAD: "false"

You should see a job reflect that:

 feature flags: FF_USE_DIRECT_DOWNLOAD:false, FF_USE_FASTZIP:true,

What are the relevant issue numbers?

Relates to #28989 (closed)

Edited by Stan Hu

Merge request reports

Loading