In Bitbucket Pipelines, why doesn't '$?' get the expected exit code from the previously run command?

paulwatson
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
July 21, 2017

In a script I have:

script:

  - set +e  # turn off error-trapping

  - failing-tests

  - echo $?

I expect an exit code of 1, but get 0. What's going on?

3 answers

2 accepted

3 votes
Answer accepted
ZenobiusJ
Contributor
July 18, 2018

Do it like this instead: 


- step:
  name: notify
  image: cfcommunity/slack-notification-resource
  script:
- |
set +e
faiing-tests
echo $?
- some other stuff
- yet more stuff

    

Leo Sanchez
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
April 3, 2019

Thanks!

3 votes
Answer accepted
paulwatson
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
July 25, 2017

Pipelines executes the printf command before every command in a script section of the bitbucket-pipelines.yml file in order to print those commands to the logs. This means, for example, that:

script:

  - mvn clean build

 

actually behave like this:

script:

  - printf "+ mvn clean build\n"

  - mvn clean build

 

One consequence of this is that an attempt to use '$?' to pass the exit code of a failing command to the next command (when error-trapping is turned off) will fail because the next command actually receives the exit code of the printf command.

For example:

script:

  - set +e  # turn off error-trapping

  - failing-tests

  - echo $?

 

will behave like this:

script:

  - printf "set +e\n"

  - set +e  # turn off error-trapping

  - printf "failing-tests\n"

  - failing-tests

  - printf "echo $?\n"

  - echo $?  # with exit code of 0, because the preceding printf command succeeded

 

If you want to catch the exit code of a failing command, a workaround is to combine commands on the same line (to prevent the printf command from intercepting the exit code), like this:

script:

  - set +e

  - failing-tests; echo $? # with exit code of 1 in this case 
Mina Luke May 18, 2019

You may also use `BITBUCKET_EXIT_CODE`

0 votes
Tomasz Raganowicz April 10, 2019

I am using: `set +e` to prevent `failing tests` from stopping Pipelines, so I can add some debugging commands, printout logs after the failing tests command.


However I would still like Pipeline to fail in case of failing test. With: `set +e` Pipeline passes and last command in my Pipeline

How can I make Bitbucket Pipeline fail or not, given the result of my tests?

Mina Luke May 22, 2019

I have the same issue.

Mina Luke June 2, 2019

I figured it out finally as follows:

set +e # turn off error-trapping

# do something here that might throw
git merge-base --is-ancestor $(git rev-parse master) HEAD
RETURN_CODE=$?  ## capture the exit code

if [ $RETURN_CODE -eq 1 ]; then
  echo "The current branch is not sibling of master"
  exit 1
else
  echo "The current branch is sibling of master"
fi

set -e # turn on error-trapping

Like # people like this
Tomasz Raganowicz June 2, 2019

Thanks @Mina Luke for sharing, I am using exactly the same approach (Forgot to share it here though) for  and it works flawlessly.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events