github-actions

Fail workflow based on previous conditional steps


For our GitHub Actions workflow, we want to analyze previous steps and give a final result based on those steps. We run a test, if the first tests fail, we run two reruns of the failed tests in parallel, we expect at least one of the rerun tests to pass. if there are no failed tests in the first run we also consider it a pass, and skip the reruns.

I came up with:

analyze-results:
  name: ${{inputs.test-description}} final verdict
  needs: [test-result, rerun-1-test-result, rerun-2-test-result]
  if: |
    always() && 
    (needs.test-result.result == 'success' ||
    needs.rerun-1-test-result.result == 'success' ||  
    needs.rerun-2-test-result.result == 'success' )
  runs-on: ${{inputs.runner-tag}}
  steps:
    - name: tests passed        
      run: echo "atleast one run passed"

However the rerun-1-test-result will not trigger if the first run test-result already passed. We also want to have the stage either fail or pass based on the if condition, so I'm not sure if the above idea is the correct way to go.


Solution

  • Having the always() in the if condition of the job, makes sure the job is triggered even when a stage is skipped. You can use an if conditions in the steps, this way we can trigger a fail, using exit 1, in case the if condition is met, an else statement is not available, we added a 2nd if statement in case all is as expected.

      final-verdict:
        name: ${{inputs.test-description}} Final verdict
        runs-on: scanner
        if: ${{ always()}}
        needs: [test-result, rerun-1-test-result, rerun-2-test-result]
        steps:    
        - run: echo "Atleast one test passed, results, first test run ${{needs.test-result.result}}, rerun-1 ${{needs.rerun-1-test-result.result}}, rerun-2 ${{needs.rerun-2-test-result.result}}"
          if: needs.test-result.result == 'success' || needs.rerun-1-test-result.result == 'success'  || needs.rerun-2-test-result.result == 'success'
        - run: |
            echo "None of the runs or reruns passed"
            exit 1
          if: needs.test-result.result != 'success' && needs.rerun-1-test-result.result != 'success' && needs.rerun-2-test-result.result != 'success'