Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make variable visible across steps in Bitbucket pipelines?

I would like to share a variable across two steps.

I define it like:

- export MY_VAR="FOO-$BITBUCKET_BUILD_NUMBER" 

but then when I try to print it in other step:

- echo $MY_VAR 

it's empty.

How I can share such variable?

like image 395
pixel Avatar asked Sep 24 '18 14:09

pixel


People also ask

How do you use variables in Bitbucket pipelines?

To access and configure the repository variables, the user must be an admin of that repository. From the repository, you can manage repository variables in Repository settings > Pipelines > Repository variables.

What is parallel in Bitbucket pipeline?

Parallel steps enable you to build and test faster, by running a set of self-contained steps at the same time.

Where are repository variables in Bitbucket?

In your Bitbucket project go to Settings > Pipelines > Respository Variables.


2 Answers

For some reason, exported environment variables are not retained between the child items of a "step:" or between the top-level "step:" items (more info about these definitions here). But you can copy all the environment variables to a file, then read them back again, because files are preserved between steps:

1. Share variables between the child items of a "step:"

How to share variables between "script:" and "after-script:"

pipelines:   default:     - step:         script:           # Export some variables           - export MY_VAR1="FOO1-$BITBUCKET_BUILD_NUMBER"           - export MY_VAR2="FOO2-$BITBUCKET_BUILD_NUMBER"           - echo $MY_VAR1           - echo $MY_VAR2            # Copy all the environment variables to a file, as KEY=VALUE, to share to other steps           - printenv > ENVIRONMENT_VARIABLES.txt          after-script:           # If the file exists, read all the previous environment variables           # from the file, and export them again           - |             if [ -f ENVIRONMENT_VARIABLES.txt ]; then                 export $(cat ENVIRONMENT_VARIABLES.txt | xargs)             fi           - echo $MY_VAR1           - echo $MY_VAR2 

Note: Try to avoid using strings that have spaces or new line characters in them (for the keys and values). The export command will have trouble reading them, and can throw errors. One possible workaround is to use sed to automatically delete any line that has a space character in it:

# Copy all the environment variables to a file, as KEY=VALUE, to share to other steps - printenv > ENVIRONMENT_VARIABLES.txt # Remove lines that contain spaces, to avoid errors on re-import (then delete the temporary file) - sed -i -e '/ /d' ENVIRONMENT_VARIABLES.txt ; find . -name "ENVIRONMENT_VARIABLES.txt-e" -type f -print0 | xargs -0 rm -f 

More info:

  • https://www.cyberciti.biz/faq/linux-list-all-environment-variables-env-command/ -- for printenv command
  • Set environment variables from file of key/value pairs

2. Share variables between the top-level "step:" items

pipelines:   default:     - step:         script:           - export MY_VAR1="FOO1-$BITBUCKET_BUILD_NUMBER"     - step:         script:           - echo $MY_VAR1 # This will not work 

In this scenario, Bitbucket Pipelines will treat the 2 "step:" items as completely independent builds, so the second "step:" will start from scratch with a blank folder and a new git clone.

So you should share files between steps by using declared artifacts, as shown in the answer by belgacea (19 Dec 2019).

like image 108
Mr-IDE Avatar answered Sep 22 '22 14:09

Mr-IDE


As Mr-IDE and Rik Tytgat explained, you can export your environment variables by writing them to a file and then share this file with a following step as an artifact. One way to do so is to write your variables to a shell script in a step, define it as an artifact and then source it in the next step.

definitions:   steps:     - step: &build         name: Build         script:           - MY_VAR="FOO-$BITBUCKET_BUILD_NUMBER"           - echo $MY_VAR           - echo "export MY_VAR=$MY_VAR" >> set_env.sh         artifacts: # define the artifacts to be passed to each future step           - set_env.sh     - step: &deploy         name: Deploy         script:             # use the artifact from the previous step           - cat set_env.sh            - source set_env.sh           - echo $MY_VAR  pipelines:   branches:     master:       - step: *build       - step:           <<: *deploy           deployment: test 

NB: In my case, the step which publish set_env.sh as an artifact is not always part of my pipelines. In this case, be sure to check if the file exists in the next step before using it.

- step: &deploy   name: Deploy   image: alpine   script:     # check if env file exists     - if [ -e set_env.sh ]; then     -   cat set_env.sh     -   source set_env.sh     - fi 
like image 23
belgacea Avatar answered Sep 21 '22 14:09

belgacea