Jenkins

Upload test reports to Gaffer from Jenkins pipelines.

Jenkins is a widely-used open-source automation server. With Gaffer, you can automatically upload and share test reports from your Jenkins pipelines.

Prerequisites

Setup

1. Add your API key as a credential

  1. Go to Manage JenkinsCredentials
  2. Select the appropriate domain (or global)
  3. Click Add Credentials
  4. Kind: Secret text
  5. Secret: Your Gaffer project API key
  6. ID: gaffer-api-key
  7. Description: Gaffer API Key

2. Add the upload step to your Jenkinsfile

pipeline {
    agent any

    environment {
        GAFFER_API_KEY = credentials('gaffer-api-key')
    }

    stages {
        stage('Test') {
            steps {
                sh 'npm ci'
                sh 'npm test'
            }
            post {
                always {
                    sh '''
                        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":"'"$GIT_COMMIT"'","branch":"'"$GIT_BRANCH"'"}'
                    '''
                    junit 'test-results/junit.xml'
                }
            }
        }
    }
}

Environment Variables

Jenkins provides these variables for your pipeline:

VariableDescriptionExample
$GIT_COMMITFull commit SHAabc123def456...
$GIT_BRANCHBranch name (may include origin/)origin/main, origin/feature/login
$BRANCH_NAMEBranch name (multibranch pipelines)main, feature/login
$BUILD_NUMBERBuild number123
$JOB_NAMEJob namemy-app/main

Tip: In multibranch pipelines, use $BRANCH_NAME instead of $GIT_BRANCH for cleaner branch names without the origin/ prefix.

Examples

Playwright

pipeline {
    agent {
        docker {
            image 'mcr.microsoft.com/playwright:v1.40.0-jammy'
        }
    }

    environment {
        GAFFER_API_KEY = credentials('gaffer-api-key')
    }

    stages {
        stage('Install') {
            steps {
                sh 'npm ci'
            }
        }
        stage('Test') {
            steps {
                sh 'npx playwright test'
            }
            post {
                always {
                    sh '''
                        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":"'"$GIT_COMMIT"'","branch":"'"$BRANCH_NAME"'","test_framework":"playwright","test_suite":"e2e"}'
                    '''
                    archiveArtifacts artifacts: 'playwright-report/**'
                }
            }
        }
    }
}

Jest with JUnit Reporter

pipeline {
    agent any

    environment {
        GAFFER_API_KEY = credentials('gaffer-api-key')
    }

    stages {
        stage('Test') {
            steps {
                sh 'npm ci'
                sh 'npm test -- --reporters=default --reporters=jest-junit'
            }
            post {
                always {
                    sh '''
                        curl -X POST https://app.gaffer.sh/api/upload \
                            -H "X-API-Key: $GAFFER_API_KEY" \
                            -F "[email protected]" \
                            -F 'tags={"commitSha":"'"$GIT_COMMIT"'","branch":"'"$BRANCH_NAME"'","test_framework":"jest"}'
                    '''
                    junit 'junit.xml'
                }
            }
        }
    }
}

Declarative with Scripted Post

pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                sh 'npm ci && npm test'
            }
        }
    }

    post {
        always {
            withCredentials([string(credentialsId: 'gaffer-api-key', variable: 'GAFFER_API_KEY')]) {
                sh '''
                    # Clean branch name (remove origin/ prefix)
                    CLEAN_BRANCH="${GIT_BRANCH#origin/}"

                    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":"'"$GIT_COMMIT"'","branch":"'"$CLEAN_BRANCH"'"}'
                '''
            }
        }
    }
}

Using CTRF Format

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

stage('Test') {
    steps {
        // 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
        sh 'npm install --save-dev jest-ctrf-json-reporter'
        sh 'npm test -- --reporter=jest-ctrf-json-reporter'
    }
    post {
        always {
            sh '''
                curl -X POST https://app.gaffer.sh/api/upload \
                    -H "X-API-Key: $GAFFER_API_KEY" \
                    -F "[email protected]" \
                    -F 'tags={"commitSha":"'"$GIT_COMMIT"'","branch":"'"$BRANCH_NAME"'"}'
            '''
        }
    }
}

Troubleshooting

Report not uploading

  • Verify the credential ID matches (gaffer-api-key)
  • Ensure the upload is in a post { always { } } block
  • Check the file path is correct relative to the workspace

401 Unauthorized

  • Check your API key starts with gfr_
  • Verify the credential is accessible to the pipeline

Branch name includes “origin/”

Use ${GIT_BRANCH#origin/} to strip the prefix:

sh '''
    CLEAN_BRANCH="${GIT_BRANCH#origin/}"
    curl ... -F 'tags={"branch":"'"$CLEAN_BRANCH"'"}'
'''

curl not found

Ensure curl is installed on your Jenkins agent or use a Docker image that includes it.

Next Steps

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