SebasH
SebasH

Reputation: 631

Gitlab CI ignores script exit code other than 1

I'm trying to set up a GitLab pipeline, so that certain exit_codes are okay for a script I'm executing. I have tried both shell and a ruby script, but both seem to have the same behaviour.

test_job:
  stage: build
  image: ruby:3.0
  script:
    - chmod +x ci/wrap.sh
    - ./ci/wrap.sh
  allow_failure:
    exit_codes:
      - 64

As you can see, I am just executing the script and nothing more, my expectation would be, that the last script executed is used a the exit status for the job.

In the script I'm only calling exit 64, which should be a "allowed failure" in that case, the pipeline log however says that the job failed because of exit code 1:

pipeline error

How do I get GitLab to accept the exit code of this (or a ruby) script as the job exit code?

Upvotes: 22

Views: 29819

Answers (2)

SebasH
SebasH

Reputation: 631

I found a way to fix this problem. Apparently Gitlab Runner uses the -e flag, which means that any non-zero exit code will cancel the job. This can be updated by using set +e, but then you still need to capture the actual exit code for the job.

Using $? in two different lines of the configuration does not work, because Gitlab does echo calls in-between them.

So the exit code needs to be captured directly, example:

script:
  - set +e
  - ruby "ci/example.rb" || EXIT_CODE=$?
  - exit $EXIT_CODE

Upvotes: 26

Jim Hunziker
Jim Hunziker

Reputation: 15390

Here's my trick for turning off early failure and checking the result code later:

  script:
    - set +e +o pipefail
    - python missing_module.py 2>&1 | grep found; result=$?
    - set -e -o pipefail
    - "[ $result == 0 ]"

This turns off early exit and runs a command that we consider to have an acceptable failure if "found" is in the error text. It then turns early exit back on and tests whether the exit code we saved was good or not.

Upvotes: 5

Related Questions