Jenkins GitHub Integration: Webhooks and Triggers
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
- Setup: GitHub Webhook
- Jenkins Configuration
- Jenkinsfile with Branch Filtering
- Private Repositories
- Troubleshooting
Two Ways to Trigger Builds
| Method | How | Pros | Cons |
|---|---|---|---|
| Polling | Jenkins asks GitHub every N minutes | Works behind firewalls | Delayed, wasteful |
| Webhooks | GitHub pushes an event to Jenkins | Instant builds | Jenkins 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:
- Generate a secret:
openssl rand -hex 20 - Add it in the GitHub webhook Secret field
- Jenkins validates the
X-Hub-Signature-256header 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:
- New Item → Multibranch Pipeline
- Branch Sources → GitHub
- Add credentials + repository URL
- Behaviours: Discover branches + PRs
- 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
- Add the public key to GitHub repo → Settings → Deploy keys
- Add the private key to Jenkins credentials (SSH Username with private key)
- Use SSH URL:
git@github.com:org/repo.git
GitHub App Authentication (Best for Orgs)
- Create a GitHub App in your org settings
- Grant Contents: Read, Metadata: Read, Commit Statuses: Write
- Install the app on your repositories
- 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, neverecho $SECRET
Related Articles
Last Updated: October 2026
Author: CloudOpsGuide Team
Difficulty: Intermediate
Estimated Reading Time: 11 minutes