how to pass variables between gitlab-ci jobs?

Viewed 1352

I have a gitlab-ci like this:

stages:
- calculation
- execution

calculation-job:
  stage: calculation
  script: ./calculate_something_and_output_results.sh
  tags:
  - my-runner

execution-job:
  stage: execution
  script: ./execute_something_with_calculation_results.sh foo
  tags:
  - my-runner

The foo argument in execution-job is base on the results of calculation-job. I want to pass the results from one job to another job via variables. How can I do that?

3 Answers

AFAIK it is not possible to pass a variable directly from one job to another job. Instead you have to write them into a file and pass that as artifact to the receiving job. To make parsing of the file easy, I recommend to create it with bash export statements and source it in the receiving job's script:

calculation-job:
  stage: calculation
  script:
  - ./calculate_something_and_output_results.sh
  - echo "export RESULT1=$calculation_result1" > results
  - echo "export RESULT2=$calculation_result2" >> results
  tags:
  - my-runner
  artifacts:
    name: "Calculation results"
    path: results

execution-job:
  stage: execution
  script:
  - source ./results
  # You can access $RESULT1 and $RESULT2 now
  - ./execute_something_with_calculation_results.sh $RESULT1 $RESULT2 foo
  tags:
  - my-runner
  needs: calculation-job

Note the ./ when sourcing results might be necessary in case of a POSIX compliant shell that does not source files in the current directory directly like, for example, a bash started as sh.

If you're looking to get the results without storing a file anywhere you can use artifacts: reports: dotenv. This is taken entirely from DarwinJS shared-variables-across-jobs repo.

stages:
  - calculation
  - execution

calculation-job:
  stage: calculation
  script: - |
      # stores new or updates existing env variables, ex. $OUTPUT_VAR1
      ./calculate_something_and_output_results.sh >> deploy.env
  tags:
    - my-runner
  artifacts:
    reports:
      #propagates variables into the pipeline level, but never stores the actual file
      dotenv: deploy.env

execution-job:
  stage: execution
  script: - |
      echo "OUTPUT_VAR1: $OUTPUT_VAR1"
      ./execute_something_with_calculation_results.sh foo
  tags:
    - my-runner

As a simpler version of what @bjhend answered (no need for export or source statements), since GitLab 13.1 the docs. recommend using a dotenv artifact.

stages:
- calculation
- execution

calculation-job:
  stage: calculation
  script:
  # Output format must feature one "VARIABLE=value" statement per line (see docs.)
  - ./calculate_something_and_output_results.sh >> calculation.env
  tags:
  - my-runner
  artifacts:
    reports:
      dotenv: calculation.env

execution-job:
  stage: execution
  script:
  # Any variables created by above are now in the environment
  - ./execute_something_with_calculation_results.sh
  tags:
  - my-runner
  # The following is technically not needed, but serves as good documentation
  needs: 
    job: calculation-job
    artifacts: true

If you have a job after the calculation stage that you don't want to use the variables, you can add the following to it:

  needs: 
    job: calculation-job
    artifacts: false
Related