Skip to content
CertiQA is in early access. Request access

5.2 GitHub Actions Quality Gate Workflow

How to add CertiQA test execution and pull request quality gates to GitHub Actions workflows.

GitHub Actions doesn’t have a separate concept of a “quality gate” – a workflow step’s own exit code is the check. The moment the “Run CertiQA Tests” step exits non-zero, GitHub marks the job (and, by extension, the PR check) failed, and every later step in the job without its own if: always() is skipped. That’s exactly why the exit-code contract from 6.1 matters here: a quarantined test’s failure does not fail the gate (exit 0), but a timeout (exit 2) or an infrastructure or auth error (exit 3) also turns the step red, and you will usually want to retry those rather than treat them as regressions.

CERTIQA_PROJECT_ID, CERTIQA_SUITE_ID, and CERTIQA_API_TOKEN are pulled from GitHub Actions secrets rather than typed into the workflow file – beyond the obvious reason (nothing sensitive lives in source control), GitHub also actively redacts any string it recognizes as a registered secret from the raw log output, so a token doesn’t leak into a public log even if a step accidentally echoes it.

name: CertiQA Quality Gate
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run CertiQA Tests
env:
CERTIQA_API_URL: https://api.certiqa.app
CERTIQA_PROJECT_ID: ${{ secrets.CERTIQA_PROJECT_ID }}
CERTIQA_SUITE_ID: ${{ secrets.CERTIQA_SUITE_ID }}
CERTIQA_TOKEN: ${{ secrets.CERTIQA_API_TOKEN }}
run: |
./certiqa-run.sh
- name: Publish Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: certiqa-junit
path: certiqa-junit.xml

On exit code 1, the “Run CertiQA Tests” step shows red in the Actions tab immediately, with the runner’s own console output preserved above the failure line – open it to see which case and step actually failed before reaching for a local re-run. On exit code 2 (timed out) or 3 (infrastructure or auth), the step also shows red under this bare setup: without branching on the exit code explicitly, a timeout looks identical to a real regression in the Actions UI.

  • 🦊 GitLab CI/CD Pipeline Template — The same runner wired into a GitLab .gitlab-ci.yml stage instead, with native JUnit reporting.