Amadou cisse
Amadou cisse

Reputation: 21

How can I get the error codes in github-actions shell when a docker run command fails while piping the output to file and CLI

I'm trying to capture both the output and the error status of a Docker command in GitHub Actions. Even when the command inside Docker fails, I'm getting a successful exit code. Here's my current workflow:

name: Test Docker Command

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Run test
        run: |
          docker run tensorpod/pymimic3:latest \
            bash -ic "pytest tests/test_metrics" 2>&1 | tee output.txt
          
          echo "Pipe status: ${PIPESTATUS[0]}"
          echo "Exit status: $?"
          
          if [ $? -ne 0 ]; then
            echo "The command failed."
            exit 1
          fi

Both ${PIPESTATUS[0]} and $? are returning 0 (success) even when the pytest command inside Docker fails. I know GitHub Actions uses bash with set -eo pipefail by default, but it's still not capturing the failure. Question: How can I correctly capture and handle the exit status of the Docker command while still piping its output to both a file and the console? Additional Info:

I need to capture both stdout and stderr (2>&1) I need to see the output in real-time in the GitHub Actions log I need to save the output to a file I need the step to fail if the command inside Docker fails

Can you help me understand what I'm doing wrong and how to fix it?

Upvotes: 1

Views: 133

Answers (1)

Shelton Liu
Shelton Liu

Reputation: 601

How can I correctly capture and handle the exit status of the Docker command while still piping its output to both a file and the console?

The potential issue probably is that, when using a pipe (|) to send the output of one command to another, only the exit code of the last command in the pipeline is captured by $?, not the exit code of the original Docker command.

docker run tensorpod/pymimic3:latest \
        bash -ic "pytest tests/test_metrics" 2>&1 | tee output.txt

What you can try to capture the correct exit code of the Docker command while still piping its output to both a file and the console

name: Test Docker Command

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Run test
        run: |
          docker_output=$(docker run tensorpod/pymimic3:latest \
              bash -ic "pytest tests/test_metrics" 2>&1)

          docker_exit_code=$?
          echo "$docker_output" | tee output.txt
      
          echo "Pipe status: ${PIPESTATUS[0]}"
          echo "Exit status: $docker_exit_code"

          if [ $docker_exit_code -ne 0 ]; then
            echo "The command inside Docker failed."
            exit 1
          fi

Upvotes: 1

Related Questions