GitLab CI

Upload test reports to Gaffer from GitLab CI/CD pipelines.

GitLab CI/CD makes it easy to run tests on every push. With Gaffer, you can automatically upload and share test reports from your pipelines.

Prerequisites

  • A Gaffer account with a project
  • Your project’s API key
  • A GitLab repository with a .gitlab-ci.yml file

Setup

1. Add your API key as a CI/CD variable

  1. Go to your GitLab project
  2. Navigate to SettingsCI/CDVariables
  3. Click Add variable
  4. Key: GAFFER_API_KEY
  5. Value: Your Gaffer project API key
  6. Check Mask variable to hide it in logs

2. Add the upload step to your pipeline

test:
  stage: test
  script:
    - npm ci
    - npm test
  after_script:
    - |
      curl -X POST https://app.gaffer.sh/api/upload \
        -H "X-API-Key: $GAFFER_API_KEY" \
        -F "files=@test-results/junit.xml" \
        -F 'tags={"commitSha":"'"$CI_COMMIT_SHA"'","branch":"'"$CI_COMMIT_REF_NAME"'"}'
  artifacts:
    when: always
    reports:
      junit: test-results/junit.xml

Environment Variables

GitLab CI provides these variables for your pipeline:

VariableDescriptionExample
$CI_COMMIT_SHAFull commit SHAabc123def456...
$CI_COMMIT_REF_NAMEBranch or tag namemain, feature/login
$CI_MERGE_REQUEST_SOURCE_BRANCH_NAMESource branch in MR pipelinesfeature/login
$CI_PROJECT_NAMEProject namemy-app

Examples

Playwright

playwright:
  stage: test
  image: mcr.microsoft.com/playwright:v1.40.0-jammy
  script:
    - npm ci
    - npx playwright install --with-deps
    - npx playwright test
  after_script:
    - |
      curl -X POST https://app.gaffer.sh/api/upload \
        -H "X-API-Key: $GAFFER_API_KEY" \
        -F "files=@playwright-report/index.html" \
        -F 'tags={"commitSha":"'"$CI_COMMIT_SHA"'","branch":"'"$CI_COMMIT_REF_NAME"'","test_framework":"playwright","test_suite":"e2e"}'
  artifacts:
    when: always
    paths:
      - playwright-report/

Jest with JUnit Reporter

jest:
  stage: test
  script:
    - npm ci
    - npm test -- --reporters=default --reporters=jest-junit
  after_script:
    - |
      curl -X POST https://app.gaffer.sh/api/upload \
        -H "X-API-Key: $GAFFER_API_KEY" \
        -F "[email protected]" \
        -F 'tags={"commitSha":"'"$CI_COMMIT_SHA"'","branch":"'"$CI_COMMIT_REF_NAME"'","test_framework":"jest"}'
  artifacts:
    when: always
    reports:
      junit: junit.xml

pytest

pytest:
  stage: test
  image: python:3.11
  script:
    - pip install pytest pytest-html
    - pytest --html=report.html --self-contained-html
  after_script:
    - |
      curl -X POST https://app.gaffer.sh/api/upload \
        -H "X-API-Key: $GAFFER_API_KEY" \
        -F "[email protected]" \
        -F 'tags={"commitSha":"'"$CI_COMMIT_SHA"'","branch":"'"$CI_COMMIT_REF_NAME"'","test_framework":"pytest"}'
  artifacts:
    when: always
    paths:
      - report.html

Using CTRF Format

For a standardized format across all your test frameworks, consider using CTRF:

test:
  script:
    - npm ci
    # Install the CTRF reporter for your framework:
    # npm install --save-dev jest-ctrf-json-reporter
    # npm install --save-dev playwright-ctrf-json-reporter
    # npm install --save-dev vitest-ctrf-json-reporter
    - npm test -- --reporter=jest-ctrf-json-reporter
  after_script:
    - |
      curl -X POST https://app.gaffer.sh/api/upload \
        -H "X-API-Key: $GAFFER_API_KEY" \
        -F "[email protected]" \
        -F 'tags={"commitSha":"'"$CI_COMMIT_SHA"'","branch":"'"$CI_COMMIT_REF_NAME"'"}'

Tip: Using after_script ensures the upload runs even when tests fail, since that’s usually when you need the report the most.

Merge Request Pipelines

For merge request pipelines, use the source branch name:

test:
  rules:
    - if: $CI_MERGE_REQUEST_IID
  script:
    - npm test
  after_script:
    - |
      BRANCH="${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-$CI_COMMIT_REF_NAME}"
      curl -X POST https://app.gaffer.sh/api/upload \
        -H "X-API-Key: $GAFFER_API_KEY" \
        -F "files=@test-results/junit.xml" \
        -F 'tags={"commitSha":"'"$CI_COMMIT_SHA"'","branch":"'"$BRANCH"'"}'

Troubleshooting

Report not uploading

  • Verify GAFFER_API_KEY is set in CI/CD variables
  • Check the variable is not marked “Protected” if running on unprotected branches
  • Ensure after_script is used (runs even when tests fail)

401 Unauthorized

  • Check your API key starts with gfr_
  • Verify the key is correctly copied (no extra spaces)

Wrong branch showing

For merge request pipelines, use CI_MERGE_REQUEST_SOURCE_BRANCH_NAME instead of CI_COMMIT_REF_NAME.

Next Steps

Other CI Providers: GitHub Actions · CircleCI · Jenkins · Bitbucket · Azure DevOps