How do I assign exe output to a variable in gitlab ci scripts?

Viewed 7419

When running my gitlab ci I need to check whether a specified svn directory exists.

I was using the script:

variables:
  DIR_CHECK: "default"

stages:
  - setup
  - test
  - otherDebugJob
  
.csharp:
  only:
    changes:
      - "**/*.cs"
      - "**/*.js"

setup:
  script:
    - $DIR_CHECK = $(svn ls https://server.fsl.local:port/svn/myco/personal/TestNotReal --depth empty)
    - echo $DIR_CHECK
test:
  script:
    - echo "DIR_CHECK is blank"
    - echo $DIR_CHECK
  rules:
    - if: $DIR_CHECK == ''

otherDebugJob:
  script:
    - echo "DIR_CHECK is not blank"
    - echo $DIR_CHECK
  rules:
    - if: $DIR_CHECK != ''
    

the svn command works and echos back the correct reply but $DIR_CHECK does not get set to anything but the original default. It does not store the returned string from the svn command.

How do I store the returned string from an exe in a variable in gitlab ci?

Test run:

Executing "step_script" stage of the job script 00:00 $ $DIR_CHECK = $(svn ls https://server.fsl.local:port/svn/myco/personal/TestNotReal --depth empty) svn: E170000: Illegal repository URL https://server.fsl.local:port/svn/myco/personal/TestNotReal' $ echo $DIR_CHECK Cleaning up file based variables 00:01 Job succeeded

1 Answers

Passing variables between jobs

Unfortunately, you cannot use DIR_CHECK variable the way you described. List of steps to be executed generates before steps actually runs, that means for all of the steps DIR_CHECK will be equal to default. First of all there are few tips how you can pass variables between jobs:

First way

You can add desired command to the before_script section in your .csharp template:

.csharp:
  before_script:
    - export DIR_CHECK=$(svn ls https://server.fsl.local:port/svn/myco/personal/TestNotReal --depth empty)

and extend other steps with this .csharp.

Second way

You can pass variables between jobs with job artifacts:

setup:
  stage: setup
  script:
    - DIR_CHECK=$(svn ls https://server.fsl.local:port/svn/myco/personal/TestNotReal --depth empty)
    - echo "DIR_CHECK=$DIR_CHECK" > dotenv_file
  artifacts:
    reports:
      dotenv: 
        - dotenv_file

Thirds way You can trigger or use parent/child pipelines to pass variables into pipelines.

staging:
  variables:
    DIR_CHECK: "you are awesome, guys!"
  stage: deploy
  trigger: my/deployment

In the triggered pipeline your variable will exists at the very start moment, and all the rules will be applied correctly.

Solution

In your case, if you really don't want to include otherDebugJob step in your pipeline you can do the following:

First approach

This is quite easy way and this will work, but looks like not a best practice. So, we are already know how to pass our DIR_CHECK variable from setup step , just add some check in the test step script block:

script:
- |
  if [ -z "$DIR_CHECK" ]; then
    exit 0
  fi
- echo "DIR_CHECK is blank"
- echo $DIR_CHECK

Do the almost same thing for the otherDebugJob but check if DIR_CHECK is not empty with if [ -n "$DIR_CHECK" ].

This approach is helpful when your pipeline not contains a lot of steps, but after the test and otherDebugJob follows another few steps.

Second approach

You can fail your setup step and then handle this fail in otherDebugJob step:

setup:
  script:
    - DIR_CHECK=$(svn ls https://server.fsl.local:port/svn/myco/personal/TestNotReal --depth empty)
    - |
      if [ -z "$DIR_CHECK" ]; then
        exit 1
      fi

otherDebugJob:
  script:
    - echo "DIR_CHECK is not blank"
  when: on_failure

This approach is useful if you only want to make some debug stuff after this setup step. After all on_failure jobs, pipeline will be marked as Failed and stopped.

Related