CircleCI
CircleCI is a popular CI/CD platform with powerful caching and parallelism features. With Gaffer, you can automatically upload and share test reports from your CircleCI pipelines.
Prerequisites
Section titled “Prerequisites”- A Gaffer account with a project
- Your project’s upload token
- A CircleCI project with a
config.ymlfile
1. Add your upload token as an environment variable
Section titled “1. Add your upload token as an environment variable”- Go to your CircleCI project settings
- Navigate to Environment Variables
- Click Add Environment Variable
- Name:
GAFFER_UPLOAD_TOKEN - Value: Your Gaffer project upload token
2. Add the upload step to your config
Section titled “2. Add the upload step to your config”version: 2.1
jobs: test: docker: - image: cimg/node:20.0 steps: - checkout - run: name: Install dependencies command: npm ci - run: name: Run tests command: npm test - run: name: Upload to Gaffer when: always command: | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: $GAFFER_UPLOAD_TOKEN" \ -F "files=@test-results/junit.xml" \ -F 'tags={"commitSha":"'"$CIRCLE_SHA1"'","branch":"'"$CIRCLE_BRANCH"'"}' - store_test_results: path: test-results
workflows: test: jobs: - testEnvironment Variables
Section titled “Environment Variables”CircleCI provides these variables for your jobs:
| Variable | Description | Example |
|---|---|---|
$CIRCLE_SHA1 | Full commit SHA | abc123def456... |
$CIRCLE_BRANCH | Branch name | main, feature/login |
$CIRCLE_PR_NUMBER | Pull request number (if applicable) | 42 |
$CIRCLE_PROJECT_REPONAME | Repository name | my-app |
$CIRCLE_BUILD_NUM | Build number | 123 |
Examples
Section titled “Examples”Playwright
Section titled “Playwright”version: 2.1
jobs: playwright: docker: - image: mcr.microsoft.com/playwright:v1.40.0-jammy steps: - checkout - run: name: Install dependencies command: npm ci - run: name: Run Playwright tests command: npx playwright test - run: name: Upload to Gaffer when: always command: | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: $GAFFER_UPLOAD_TOKEN" \ -F "files=@playwright-report/index.html" \ -F 'tags={"commitSha":"'"$CIRCLE_SHA1"'","branch":"'"$CIRCLE_BRANCH"'","test_framework":"playwright","test_suite":"e2e"}' - store_artifacts: path: playwright-reportJest with JUnit Reporter
Section titled “Jest with JUnit Reporter”version: 2.1
jobs: test: docker: - image: cimg/node:20.0 steps: - checkout - run: name: Install dependencies command: npm ci - run: name: Run Jest tests command: npm test -- --reporters=default --reporters=jest-junit environment: JEST_JUNIT_OUTPUT_DIR: ./test-results - run: name: Upload to Gaffer when: always command: | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: $GAFFER_UPLOAD_TOKEN" \ -F "files=@test-results/junit.xml" \ -F 'tags={"commitSha":"'"$CIRCLE_SHA1"'","branch":"'"$CIRCLE_BRANCH"'","test_framework":"jest"}' - store_test_results: path: test-resultspytest
Section titled “pytest”version: 2.1
jobs: pytest: docker: - image: cimg/python:3.11 steps: - checkout - run: name: Install dependencies command: pip install pytest pytest-html - run: name: Run pytest command: pytest --html=report.html --self-contained-html - run: name: Upload to Gaffer when: always command: | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: $GAFFER_UPLOAD_TOKEN" \ -F "files=@report.html" \ -F 'tags={"commitSha":"'"$CIRCLE_SHA1"'","branch":"'"$CIRCLE_BRANCH"'","test_framework":"pytest"}' - store_artifacts: path: report.htmlUsing CTRF Format
Section titled “Using CTRF Format”For a standardized format across all your test frameworks, consider using CTRF:
- run: name: Install CTRF reporter # Choose the 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 command: npm install --save-dev jest-ctrf-json-reporter- run: name: Run tests with CTRF command: npm test -- --reporter=jest-ctrf-json-reporter- run: name: Upload CTRF to Gaffer when: always command: | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: $GAFFER_UPLOAD_TOKEN" \ -F "files=@ctrf-report.json" \ -F 'tags={"commitSha":"'"$CIRCLE_SHA1"'","branch":"'"$CIRCLE_BRANCH"'"}'Parallel Test Runs
Section titled “Parallel Test Runs”When using CircleCI’s parallelism feature, you can upload from each container:
jobs: test: parallelism: 4 steps: - run: name: Run tests command: | circleci tests glob "**/*.spec.js" | circleci tests split | xargs npm test -- - run: name: Upload to Gaffer when: always command: | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: $GAFFER_UPLOAD_TOKEN" \ -F "files=@test-results/junit.xml" \ -F 'tags={"commitSha":"'"$CIRCLE_SHA1"'","branch":"'"$CIRCLE_BRANCH"'","container":"'"$CIRCLE_NODE_INDEX"'"}'Troubleshooting
Section titled “Troubleshooting”Report not uploading
Section titled “Report not uploading”- Verify
GAFFER_UPLOAD_TOKENis set in project environment variables - Ensure
when: alwaysis set so the step runs even when tests fail - Check the file path is correct relative to the working directory
401 Unauthorized
Section titled “401 Unauthorized”- Check your upload token starts with
gfr_ - Verify the token is correctly copied (no extra spaces)
Missing branch name
Section titled “Missing branch name”- Make sure you’re using
$CIRCLE_BRANCH(not$CIRCLE_PR_BRANCH) - For forks, the branch may be available in different variables
Next Steps
Section titled “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 · GitLab CI · Jenkins · Bitbucket · Azure DevOps