GitHub Actions
Automatically upload Playwright, Jest, and Vitest test reports from GitHub Actions. Use the official Gaffer Uploader action with full YAML examples.
The official Gaffer Uploader GitHub Action makes it easy to automatically upload test reports from your CI workflows.
Prerequisites
- A Gaffer account with a project
- Your project’s upload token
- A GitHub repository with a test workflow
Setup
1. Add your upload token as a secret
- Go to your GitHub repository
- Navigate to Settings → Secrets and variables → Actions
- Click New repository secret
- Name:
GAFFER_UPLOAD_TOKEN - Value: Your Gaffer project upload token
2. Add the upload step to your workflow
Add the Gaffer uploader step after your test step. Use if: always() to ensure reports are uploaded even when tests fail.
Inputs
| Input | Required | Description |
|---|---|---|
gaffer_api_key | Yes | Your Gaffer project upload token |
report_path | Yes | Path to the report file or directory to upload |
api_endpoint | No | Custom API endpoint URL (for staging/preview environments) |
commit_sha | No | Git commit SHA to associate with the test run |
branch | No | Git branch name to associate with the test run |
test_framework | No | Test framework used (e.g., playwright, jest, pytest) |
test_suite | No | Name of the test suite (e.g., unit, e2e) |
Examples
Basic Usage
name: Tests
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Upload to Gaffer
uses: gaffer-sh/gaffer-uploader@v1
if: always()
with:
gaffer_api_key: ${{ secrets.GAFFER_UPLOAD_TOKEN }}
report_path: ./test-results
commit_sha: ${{ github.sha }}
branch: ${{ github.ref_name }}
Playwright Example
A complete example for Playwright tests:
name: Playwright Tests
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Install Playwright browsers
run: pnpm exec playwright install --with-deps
- name: Run Playwright tests
run: pnpm exec playwright test
- name: Upload Playwright Report to Gaffer
uses: gaffer-sh/gaffer-uploader@v1
if: always()
with:
gaffer_api_key: ${{ secrets.GAFFER_UPLOAD_TOKEN }}
report_path: ./playwright-report
commit_sha: ${{ github.sha }}
branch: ${{ github.ref_name }}
test_framework: playwright
test_suite: e2e
Pull Request Workflow
For pull request workflows, use github.head_ref to get the correct branch name:
name: PR Tests
on:
pull_request:
branches: [main]
env:
branch_name: ${{ github.head_ref || github.ref_name }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test
- name: Upload to Gaffer
uses: gaffer-sh/gaffer-uploader@v1
if: always()
with:
gaffer_api_key: ${{ secrets.GAFFER_UPLOAD_TOKEN }}
report_path: ./test-results
commit_sha: ${{ github.event.pull_request.head.sha }}
branch: ${{ env.branch_name }}
test_framework: jest
test_suite: unit
Tip: The if: always() condition is important! Without it, the upload step will be skipped when tests fail — which is usually when you need the report the most.
Using CTRF Format
For a standardized format across all your test frameworks, consider using CTRF:
- name: Install CTRF reporter
run: npm install --save-dev jest-ctrf-json-reporter # or playwright-ctrf-json-reporter, vitest-ctrf-json-reporter
- name: Run tests with CTRF reporter
run: npm test -- --reporter=jest-ctrf-json-reporter
- name: Upload CTRF report to Gaffer
uses: gaffer-sh/gaffer-uploader@v1
if: always()
with:
gaffer_api_key: ${{ secrets.GAFFER_UPLOAD_TOKEN }}
report_path: ./ctrf-report.json
commit_sha: ${{ github.sha }}
branch: ${{ github.ref_name }}
Environment Variables
GitHub Actions provides these variables for your workflow:
| Variable | Description | Example |
|---|---|---|
${{ github.sha }} | Full commit SHA | abc123def456... |
${{ github.ref_name }} | Branch or tag name | main, feature/login |
${{ github.head_ref }} | PR source branch (PR workflows only) | feature/login |
${{ github.event.pull_request.head.sha }} | PR head commit SHA | def456abc789... |
Troubleshooting
Report not uploading
- Verify the
report_pathpoints to the correct file or directory - Check that your upload token secret is named exactly
GAFFER_UPLOAD_TOKEN - Ensure
if: always()is set so the step runs even when tests fail
Wrong branch showing
For pull request workflows, use github.head_ref || github.ref_name pattern to get the correct source branch name.
401 Unauthorized
- Check your upload token starts with
gfr_ - Verify the token is correctly copied (no extra spaces)
- Make sure the secret is accessible to the workflow
Next Steps
- CTRF Guide - Use the universal test format
- Upload API Reference - Full API documentation
- cURL Guide - Manual uploads for debugging
- Slack Integration - Get test results in Slack
Other CI Providers: GitLab CI · CircleCI · Jenkins · Bitbucket · Azure DevOps