CloudOpsGuide
jenkins

Jenkins GitHub Integration: Webhooks and Triggers

Intermediate
11 minutes
October 2026
CloudOpsGuide Team

Jenkins GitHub Integration: Webhooks and Triggers

Configure Jenkins to automatically build on every GitHub push using webhooks, with proper authentication and branch filtering.

Table of Contents

Two Ways to Trigger Builds

MethodHowProsCons
PollingJenkins asks GitHub every N minutesWorks behind firewallsDelayed, wasteful
WebhooksGitHub pushes an event to JenkinsInstant buildsJenkins must be reachable

Webhooks are the standard for production. Polling is only for when Jenkins isn't publicly reachable.

Setup: GitHub Webhook

Step 1: Add the Webhook in GitHub

Repository → Settings → Webhooks → Add webhook:

  • Payload URL: https://jenkins.example.com/github-webhook/ (trailing slash matters)
  • Content type: application/json
  • Events: "Just the push event" (or add pull_request for PR builds)
  • Active: ✓

GitHub sends a test ping — a green checkmark means Jenkins received it.

Step 2: Securing the Webhook

Set a secret so only GitHub can trigger builds:

  1. Generate a secret: openssl rand -hex 20
  2. Add it in the GitHub webhook Secret field
  3. Jenkins validates the X-Hub-Signature-256 header automatically when the GitHub plugin's shared secret matches.

Jenkins Configuration

Install Required Plugins

  • GitHub Integration Plugin
  • GitHub Branch Source Plugin (for multibranch)
  • Pipeline plugin

Multibranch Pipeline (Recommended)

Multibranch pipelines auto-discover branches and PRs:

  1. New Item → Multibranch Pipeline
  2. Branch Sources → GitHub
  3. Add credentials + repository URL
  4. Behaviours: Discover branches + PRs
  5. Scan triggers: "Periodically if not otherwise run" as fallback

Jenkins will find Jenkinsfile in every branch and create jobs automatically.

Jenkinsfile with Branch Filtering

pipeline {
    agent any

    triggers {
        // Backup polling — webhooks are primary
        pollSCM('H/5 * * * *')
    }

    stages {
        stage('Build') {
            steps {
                sh 'npm ci && npm run build'
            }
        }

        stage('Test') {
            steps {
                sh 'npm test'
            }
            post {
                always {
                    junit 'test-results/**/*.xml'
                }
            }
        }

        stage('Deploy to Staging') {
            when { branch 'develop' }
            steps {
                sh './deploy.sh staging'
            }
        }

        stage('Deploy to Production') {
            when { branch 'main' }
            input { message 'Deploy to production?' }
            steps {
                sh './deploy.sh production'
            }
        }
    }

    post {
        success {
            // Report build status back to GitHub
            githubNotify status: 'SUCCESS',
                         context: 'ci/jenkins',
                         description: 'Build passed'
        }
        failure {
            githubNotify status: 'FAILURE',
                         context: 'ci/jenkins',
                         description: 'Build failed'
        }
    }
}

Private Repositories

SSH Key Authentication

# Generate a deploy key
ssh-keygen -t ed25519 -C "jenkins@mycompany" -f jenkins_key
  1. Add the public key to GitHub repo → Settings → Deploy keys
  2. Add the private key to Jenkins credentials (SSH Username with private key)
  3. Use SSH URL: git@github.com:org/repo.git

GitHub App Authentication (Best for Orgs)

  1. Create a GitHub App in your org settings
  2. Grant Contents: Read, Metadata: Read, Commit Statuses: Write
  3. Install the app on your repositories
  4. Add App ID + private key to Jenkins → GitHub App credentials

Apps give finer permissions and better rate limits than PATs.

Troubleshooting

Webhook shows ✓ but builds don't trigger

# Check Jenkins webhook logs
# Manage Jenkins → System Log → Add recorder for:
#   com.cloudbees.jenkins.GitHubWebHook

Common causes:

  • Job isn't multibranch or lacks GitHub trigger config
  • Branch filter excludes the pushed branch
  • Jenkins URL mismatch (GitHub delivers, Jenkins ignores)

"Invalid hook signature" errors

The secret in GitHub doesn't match Jenkins' GitHub plugin secret. Re-generate and update both sides.

Builds trigger on every push to every branch

// Restrict with when conditions
when {
    anyOf {
        branch 'main'
        branch 'develop'
        changeRequest()   // PRs
    }
}

Or filter in the multibranch job config: Behaviours → "Filter by name (regex)": main|develop|PR-.*

GitHub rate limiting

Symptoms: 403 rate limit exceeded in Jenkins logs.

Fix: authenticate all GitHub API calls — add credentials to the multibranch source, or use a GitHub App (higher limits).

Security Checklist

  • Webhook secret configured
  • Jenkins behind HTTPS (webhooks should never go over plain HTTP)
  • Deploy keys scoped to single repos (not org-wide keys)
  • scriptApproval — review any pending script signatures
  • Don't log secrets: use withCredentials, never echo $SECRET

Related Articles


Last Updated: October 2026
Author: CloudOpsGuide Team
Difficulty: Intermediate
Estimated Reading Time: 11 minutes