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.ymlfile
Setup
1. Add your API key as a CI/CD variable
- Go to your GitLab project
- Navigate to Settings → CI/CD → Variables
- Click Add variable
- Key:
GAFFER_API_KEY - Value: Your Gaffer project API key
- 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:
| Variable | Description | Example |
|---|---|---|
$CI_COMMIT_SHA | Full commit SHA | abc123def456... |
$CI_COMMIT_REF_NAME | Branch or tag name | main, feature/login |
$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME | Source branch in MR pipelines | feature/login |
$CI_PROJECT_NAME | Project name | my-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_KEYis set in CI/CD variables - Check the variable is not marked “Protected” if running on unprotected branches
- Ensure
after_scriptis 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
- CTRF Guide - Use the universal test format
- Upload API Reference - Full API documentation
- Slack Integration - Get test results in Slack
Other CI Providers: GitHub Actions · CircleCI · Jenkins · Bitbucket · Azure DevOps