Handle the k6 exit code

k6 uses exit codes to communicate test results to the pipeline. Exit code 0 means all thresholds passed. A non-zero exit code means the test failed. For threshold breaches, k6 commonly returns 99. Most CI/CD platforms treat any non-zero exit code as a job failure by default, but you still need to confirm that nothing in your job swallows that signal.

To ensure your pipeline correctly handles the k6 exit code, complete the following steps:

  1. Verify that your CI platform fails the job on a non-zero exit code. In GitHub Actions, each step fails the job by default when the command returns a non-zero exit code. grafana/run-k6-action preserves this behavior, so no additional configuration is needed if you used the setup from the previous milestone.

  2. If you run k6 using a shell script or Docker command in your pipeline, ensure the exit code propagates. A common mistake is wrapping k6 in a script that doesn’t forward the exit code:

    Bash
    # Wrong: the echo succeeds and masks a k6 failure
    docker run --rm grafana/k6:latest run /tests/test.js
    echo "Test complete"

    The echo command returns exit code 0 regardless of the k6 result. Instead, ensure k6 is the last command, or capture the exit code explicitly:

    Bash
    docker run --rm grafana/k6:latest run /tests/test.js
    K6_EXIT=$?
    echo "Test complete with exit code $K6_EXIT"
    exit $K6_EXIT
  3. Test the gate by temporarily setting a threshold that will fail, as you did in the verify-thresholds milestone. Push the change and confirm the pipeline marks the job as failed.

    In GitHub Actions, a failed job shows a red X next to the step. In GitLab CI, the job status changes to failed. The pipeline log shows which k6 thresholds were breached.

  4. Revert the threshold to its passing value and push again. Confirm the pipeline passes.

Tip: For pull request workflows, configure your repository to require the k6 job to pass before merging. In GitHub, go to Settings > Branches > Branch protection rules and add your performance test job to the required status checks. In GitLab, keep the job in a stage that blocks the pipeline by default.

  1. Confirm the full cycle: a passing test allows the pipeline to continue, and a failing test blocks the merge or deploy. This is your performance gate.

In the next milestone, you trigger a full pipeline run and verify the automated results end to end.


page 6 of 9