Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gitlab ci scripts during which $? is allowed to be non-zero

Tags:

bash

gitlab-ci

In our project we have a shell script which is to be sourced to set up environment variables for the subsequent build process or to run the built applications.

It contains a block which checks the already set variables and does some adjustment.

# part of setup.sh
for LIBRARY in "${LIBRARIES_WE_NEED[@]}"
do
  echo $LD_LIBRARY_PATH | \grep $LIBRARY > /dev/null
  if [ $? -ne 0 ]
  then
   echo Adding $LIBRARY
   LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIBRARY
  else
   echo Not adding $LIBRARY
  fi
done

i.e. it checks if a path to a library is already in $LD_LIBRARY_PATH and if not, adds it. (To be fair, this could be written differently (like here), but assume the script is supposed to achieve something which is very hard to do without calling a program, checking $? and then either doing one thing or doing another thing).

The .gitlab-ci.yml then contains

before_script:
  - yum install -y <various packages>
  - source setup.sh

but the runner decides to stop the before script the very moment $? is non-zero, i.e. when the if-statement decides to add a path to $LD_LIBRARY_PATH. Now it is nice that the gitlab runner checks $? after each line of my script, but here it'd be great if the lines in .gitlab-ci.yml were considered atomic.

Is there a way to avoid the intermediate checks of $? in a script that's sourced in .gitlab-ci.yml?

like image 809
pseyfert Avatar asked Sep 13 '16 09:09

pseyfert


People also ask

Is it possible to override GitLab CI default variables?

gitlab-ci. yml file. The variables are used by the runner any time the pipeline runs. You can also override variable values manually for a specific pipeline.

What is script in GitLab CI?

You can use special syntax in script sections to: Split long commands into multiline commands. Use color codes to make job logs easier to review. Create custom collapsible sections to simplify job log output.

What is Before_script in GitLab CI?

These are scripts that you choose to be run before the job is executed or after the job is executed. These can also be defined at the top level of the YAML file (where jobs are defined) and they'll apply to all jobs in the . gitlab-ci. yml file.


2 Answers

Use command_that_might_fail || true to mask the exit status of said command.

Also note that you can use grep -q to prevent output:

echo "$LD_LIBRARY_PATH" | grep -q "$LIBRARY" || true

This will however also mask $? which you might not want. If you want to check if the command exits correct you might use:

if echo "$LD_LIBRARY_PATH" | grep -q "$LIBRARY"; then
  echo "Adding $LIBRARY"
else
  ...
fi

I suspect that gitlab-ci sets -e which you can disabled with set +e:

set +e # Disable exit on error
for library in "${LIBRARIES_WE_NEED[@]}"; do
  ...
done
set -e # Enable exit on error

Future reading: Why double quotes matter and Pitfalls with set -e

like image 81
Andreas Louv Avatar answered Oct 09 '22 10:10

Andreas Louv


Another trick that I am using is a special kind of "|| true", combined with having access to previous exit code.

- exit_code=0
- ./myScript.sh || exit_code=$?
- if [ ${exit_code} -ne 0 ]; then echo "It failed!" ; else echo "It worked!"; fi

The $exit_code=$? always evaluates to "true" so you get a non failing command but you also receive exit_code and you can do whatever you want with it.

Note please, that you shouldn't skip the first line or exit_code will be uninitialized (since on successful run of script, the or'ed part is never executed and the if ends up being)

if [ -ne 0 ];

instead of

if [ 0 -ne 0 ];

Which causes syntax error.

like image 42
Marcin K. Avatar answered Oct 09 '22 10:10

Marcin K.