How to override environment variables through the Build Trigger API

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}"

5 Likes

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

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

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?

Is it possible to override a env var like $BITRISE_BUILD_NUMBER
We build our app for several customers and would like it to contain the same build number.

I tried this curl, but it still seems to set whatever Bitrise has as the next build number and ignore the one in the curl.

$ curl https://app.bitrise.io/app/REDACTED/build/start.json --data ‘{“hook_info”:{“type”:“bitrise”,“build_trigger_token”:“REDACTED”},“build_params”:{“branch”:“develop”,“environments”:[{“mapped_to”:“BITRISE_BUILD_NUMBER”,“value”:“114”,“is_expand”:true}]},“triggered_by”:“curl”}’

1 Like

Hey there @mleatherbmm!

It is, please check out this thread: How can I overwrite the BITRISE_BUILD_NUMBER env var for a single build? :wink:

I m trying to override a variable from ENV VARS using script action / step

#!/bin/bash
set -ex
if [ ! -z “$API_BUILD_NO” ] ; then
echo “Env Vars”
envman add --key BUILD_NO --value “$API_BUILD_NO”
fi

BUILD_NO is defined in ENV VARS and I m trying to use BUILD_NO in next step after this , here is the request to API

{“hook_info”: {“type”: “bitrise”},“build_params”: {“branch”: “master”},“environments”:[
{“mapped_to”:“API_BUILD_NO”,“value”:“10”,“is_expand”:false}]}

But in the response I see following in the script step

  • ‘[’ ‘!’ -z ‘’ ‘]’

I am not a script expert can you please suggest whats wrong with this ?

You are exporting BUID_NO via envman, not BUILD_NO. Missing L infix.

Yep sorry about the typo but output is still same , it doesnt receive the API_BUILD_NO variable in API. Getting same output in script execution.

I think main issue is the variable isn’t reaching the workflow hence script show empty values ?

Hey there @destinysoftware,

Can you please send us the log file or the URL of the related build and also enable Support Access on the Settings tab of the app ( Enabling the Bitrise Support user for your app | Bitrise DevCenter ) so that we can take a more in-depth look of what exactly is going on? :slight_smile: