Execute GitHub Actions step after failure while maintaining job failure status

I need help with a GitHub Actions workflow issue. I’m running automated tests and want to upload the test results as artifacts, but I’m having problems when tests fail.

My current setup works perfectly when tests pass - everything runs and artifacts get uploaded. However, when tests fail, the workflow stops and never reaches the artifact upload step.

I tried using continue-on-error: true which does let the workflow continue and upload artifacts, but then the entire job shows as successful even though the tests actually failed.

Is there a way to force artifact upload even after a step fails, but still have the job marked as failed?

Here’s my current workflow:

name: Build Pipeline
on:
  pull_request:
    branches:
    - main
  push:
    branches:
      - main

jobs:
  test-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Run Unit Tests
      run: ./mvnw test

    - name: Upload Test Reports
      uses: actions/upload-artifact@v2
      with:
        name: test-reports
        path: target/surefire-reports

You should consider using if: failure() for the upload step. This configuration allows the artifact upload to occur only if previous steps have failed, while still ensuring the job is marked as failed. I have implemented this in various CI pipelines to ensure test results are available even when a failure occurs.

To adjust your workflow, modify the upload step as follows:

- name: Upload Test Reports
  if: failure()
  uses: actions/upload-artifact@v2
  with:
    name: test-reports
    path: target/surefire-reports

If you want artifacts uploaded regardless of outcome, switch to if: always() and include a final step to exit 1 when tests fail, enabling control over both artifact uploads and job status.

just use if: always() for the upload step. it runs no matter the outcome of previous steps and still marks the job as failed if tests fail. this worked great for me.