Workflow skips steps besides if condition

I am at my wits end. I am trying to run certain steps in a workflow even though I expect one step to fail.I have tried a few iterations of the workflow definition. You can find one example run here. As you can see the step with always() does run and shows that the outcome of my check step is 'failure'. However, for some reason the setup step gets skipped anyway and I don’t understand why. Can anyone enlighten me, please?

name: CI

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

env:
  POSTGRES_PASSWORD: secret

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest]

    steps:
    - uses: actions/checkout@v2
    - name: Print versions of important tools.
      run: |
        bash --version
        git --version
        make --version
        docker version
        docker-compose version
    - name: Check for the availability of all required command line tools.
      id: check
      run: make check
    - name: Print outcome
      run: echo "${{ steps.check.outcome }}"
      if: ${{ always() }}
    - name: Download all dependent repositories.
      id: setup
      run: make setup
      if: steps.check.outcome == 'failure' || steps.check.outcome == 'success'
    - name: Build all local Docker images.
      id: install
      run: make install -j -O
      if: steps.setup.outcome == 'success'
    - name: Initialize databases.
      id: initialize
      run: make initialize
      if: steps.install.outcome == 'success'

Hi @Midnighter,
According to the document: If your if expression does not contain any of the status functions it will automatically result with success() .
In your workflow, setup step didn’t add any of the status functions, so success() is added automatically.
if: success() && (steps.check.outcome == 'failure' || steps.check.outcome == 'success')
As check step is failed , then the result of success() is false . So the whole if conditional of setup step is false caused the step to be skipped.
You could enable step debug logging, the detail information of evaluating condition .

Ah, great! That makes it perfectly clear. I somehow misread the documentation on that part. Thank you for your clarification and also for the hint on debug logging.

That is horrible behavior :scream: It means that if: ${{ true }} does not always run. It means that if: ${{ false }} will run on success. In my case i had ${{ steps.build.outcome == 'success' && steps.test.outcome == 'failure' }} and was baffled when making my boolean expression stricter it would suddenly trigger: ${{ failure() && steps.build.outcome == 'success' && steps.test.outcome == 'failure' }}.