How to override environment variables through the Build Trigger API

#1

Environment Variables are set (processed) in a specific order. An environment variable processed before another one can’t override the second one, but the second one can use the first one.

If you use the Build Trigger API and you specify one-off environment variables as parameters of the build, those will be processed after the Secret Env Vars, but before App Env Vars.

This means that simply specifying the same environment variable this way which is also defined in the build configuration (bitrise.yml), e.g. as an App Env Var, you won’t be able to override it, the value of the App Env Var will be used as it will override the value you specify through the API.

For more technical information about the environment variable processing order see this DevCenter article.

The solution

So, what if you want to override a variable which is defined in the build configuration? The solution is simple: you have to override it at a later stage!

Probably the easiest solution is to do it with a build step (e.g. with a Script step). Steps and step outputs are processed after App Env Vars and Workflow Env Vars, so with this solution you can reliably override any other environment variable.

The key is to specify an environment variable through the API which is not defined in your build configuration, and then “copy” the value of this env var to the main one, overriding it. For example, if you want to override the environment variable BITRISE_SCHEME, you should specify e.g. an API_BITRISE_SCHEME env var, and then copy the value of API_BITRISE_SCHEME to BITRISE_SCHEME.

Using a Script step

Any step or script can expose environment variables for subsequent steps, using the Bitrise CLI built in envman utility.

If you want to override BITRISE_SCHEME with the value of API_BITRISE_SCHEME (which is not defined in your build configuration, but might be specified through the Bitrise Build Trigger API), the script can be as simple as:

#!/bin/bash
set -ex
if [ ! -z "$API_BITRISE_SCHEME" ] ; then
  envman add --key BITRISE_SCHEME --value "$API_BITRISE_SCHEME"
fi

This of course have to run before you’d use the value of BITRISE_SCHEME. Also please note that BITRISE_SCHEME environment variable’s new value would only be available in the next steps and not in the step that contains the envman command.

A very minimal bitrise.yml for demonstration:

format_version: 1.3.1
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
app:
  envs:
  - BITRISE_SCHEME: SchemeFromAppEnv
workflows:
  primary:
    steps:
    - script:
        title: Copy the value of API_BITRISE_SCHEME into BITRISE_SCHEME if defined
        inputs:
        - content: |
            #!/bin/bash
            set -ex
            if [ ! -z "$API_BITRISE_SCHEME" ] ; then
              envman add --key BITRISE_SCHEME --value "$API_BITRISE_SCHEME"
            fi
    - script:
        inputs:
        - content: |
            #!/bin/bash
            echo "BITRISE_SCHEME: ${BITRISE_SCHEME}"

3 Likes

Custom Env. Vars did not override App Env Vars or Workflow env vars
How to schedule builds in web panel with overriding BITRISE_SCHEME
Public install page URLs for multiple apps
ENV vars not showing up in workflow?
#2

I’m not a shell expert, but it looks to me like your test is missing a $:

if [ ! -z "API_BITRISE_SCHEME" ]

should be

if [ ! -z "$API_BITRISE_SCHEME" ]
1 Like

#3

Ouch, you’re right @paour, I guess the $ was accidentally removed when we shared the workflow here - it was based on an internal one where we used a different env, I guess we accidentally deleted the $ during the replace…

Fixed in the script, and thanks for reporting @paour!

1 Like

#4

I’ve tried to change the value of a “computed” environment variable, but it doesn’t seem to reflect the values that it is build from.

Example:
A build is triggered via the API
The environment variable API_SHIP_TO is set through the API to external

In the Workflow editor, the following environment variables is set
SHIP_TO is set to internal
FASTLANE_BUILD_PARAMS is set to ship_to:$SHIP_TO

Changing ship_to
Before all other steps in the workflow, a script step is added

if [ ! -z "$API_SHIP_TO" ] ; then
  envman add --key SHIP_TO --value "$API_SHIP_TO"
fi

The value of FASTLANE_BUILD_PARAMS will still be ship_to:internal instead of ship_to:external

Re-compute with the newly updated SHIP_TO
Adding the following to force FASTLANE_BUILD_PARAMS to be set with the updated SHIP_TO

if [ ! -z "$API_SHIP_TO" ] ; then
  envman add --key SHIP_TO --value "$API_SHIP_TO"
fi
envman add --key FASTLANE_BUILD_PARAMS --value "\"ship_to:$SHIP_TO\""

Value of FASTLANE_BUILD_PARAMS is still ship_to:internal

Using the value directly from API_SHIP_TO
Only by setting it explicitly as

if [ ! -z "$API_SHIP_TO" ] ; then
  envman add --key SHIP_TO --value "$API_SHIP_TO"
  envman add --key FASTLANE_BUILD_PARAMS --value "\"ship_to:$API_SHIP_TO\""
fi

Updates the value of FASTLANE_BUILD_PARAMS to ship_to:external

The reason I’d like to just update the SHIP_TO, is, that FASTLANE_BUILD_PARAMS will contain multiple environment variables.

@viktorbenei is this intended?

0 Likes