30Jenkins
What you will master here
- Jenkins architecture: controller + agents
- Freestyle vs Pipeline (declarative + scripted)
- Jenkinsfile syntax, stages, agents, environment
- Credentials + secrets
- Parallel + matrix builds
- Shared libraries
- Plugins (Allure, JUnit, JaCoCo, etc.)
- Jenkins vs GitHub Actions vs GitLab CI
30.1 Architecture
- Controller — orchestrator; stores config, schedules jobs, serves UI
- Agent — worker (formerly "slave") that runs builds
- Executor — slot inside an agent (parallel job capacity)
- Job — a defined build (freestyle or pipeline)
- Build — one execution of a job
30.2 Declarative Pipeline (modern default)
// Jenkinsfile
pipeline {
agent any
options {
timeout(time: 30, unit: 'MINUTES')
timestamps()
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '20'))
}
environment {
NODE_ENV = 'test'
CI = 'true'
}
triggers {
pollSCM('H/5 * * * *') // poll git every 5 min
cron('H 2 * * *') // nightly
}
stages {
stage('Checkout') {
steps { checkout scm }
}
stage('Install') {
steps { sh 'npm ci' }
}
stage('Lint') {
steps { sh 'npm run lint' }
}
stage('Test') {
parallel {
stage('Unit') { steps { sh 'npm run test:unit' } }
stage('E2E') { steps { sh 'npx playwright test' } }
}
}
stage('Deploy') {
when { branch 'main' }
steps { sh './deploy.sh' }
}
}
post {
always {
junit 'test-results/junit.xml'
archiveArtifacts artifacts: 'playwright-report/**', allowEmptyArchive: true
}
failure {
mail to: 'team@acme.com', subject: "FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "See ${env.BUILD_URL}"
}
}
}
30.3 Scripted Pipeline (older Groovy DSL)
node('linux') {
stage('checkout') { checkout scm }
stage('install') { sh 'npm ci' }
stage('test') {
try {
sh 'npx playwright test'
} finally {
junit 'test-results/junit.xml'
}
}
}
30.4 Credentials & secrets
// Use a credential id stored in Jenkins
withCredentials([
string(credentialsId: 'JIRA_TOKEN', variable: 'JIRA_TOKEN'),
usernamePassword(credentialsId: 'docker-hub', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')
]) {
sh 'docker login -u $DOCKER_USER -p $DOCKER_PASS'
}
30.5 Parallel + matrix
// Static parallel
stage('Test') {
parallel {
stage('chromium') { agent { label 'linux' }; steps { sh 'npx playwright test --project=chromium' } }
stage('firefox') { agent { label 'linux' }; steps { sh 'npx playwright test --project=firefox' } }
stage('webkit') { agent { label 'mac' }; steps { sh 'npx playwright test --project=webkit' } }
}
}
// Matrix (axis cross-product)
matrix {
axes {
axis { name 'OS'; values 'linux','mac','windows' }
axis { name 'BROWSER'; values 'chromium','firefox' }
}
stages {
stage('test') {
agent { label "${OS}" }
steps { sh "npx playwright test --project=${BROWSER}" }
}
}
}
30.6 Shared libraries
// vars/runPlaywright.groovy
def call(Map config = [:]) {
sh "npx playwright test --shard=${config.shard ?: '1/1'}"
junit 'test-results/junit.xml'
}
// Jenkinsfile in any repo
@Library('test-pipeline-lib') _
pipeline {
agent any
stages {
stage('test') {
steps { runPlaywright(shard: '1/4') }
}
}
}
30.7 Common plugins for SDETs
| Plugin | Purpose |
|---|---|
| JUnit | Test result parsing + trend |
| Allure | Rich test reports |
| JaCoCo | Code coverage |
| HTML Publisher | Publish any HTML report (Playwright) |
| Slack Notification | Post build status |
| Pipeline Stage View | Visual stage graph |
| Blue Ocean | Modern pipeline UI |
| Configuration as Code (JCasC) | Jenkins config from YAML |
30.8 Jenkins vs GitHub Actions vs GitLab CI
| Aspect | Jenkins | GitHub Actions | GitLab CI |
|---|---|---|---|
| Hosting | Self-host (usually) | SaaS / self-hosted runners | SaaS / self-hosted runners |
| Config | Jenkinsfile (Groovy) | YAML (.github/workflows/) | YAML (.gitlab-ci.yml) |
| Plugin ecosystem | Huge (legacy) | Marketplace (growing) | Built-in (rich) |
| Best for | Enterprise on-prem, complex orchestration | GitHub-based teams, simple-medium | GitLab teams, full DevOps suite |
| Operational cost | You operate it | GitHub operates it | GitLab operates it |
Module 62 — Jenkins Q&A
What's a Jenkinsfile?
A Groovy DSL file describing the build pipeline as code. Lives in the repo (versioned with the code). Two flavours: declarative (recommended, more structured) and scripted (more powerful, less guarded).
How do you share pipeline code across repos?
Shared libraries — a Git repo with
vars/ (global steps) and src/ (Groovy classes). Reference via @Library('name') _ at top of Jenkinsfile. Centralises pipeline patterns across teams.How do you store secrets in Jenkins?
Credentials Manager — add secret text / username-password / SSH key. Reference in pipeline via
withCredentials wrapper; injects as masked env vars. Never echo them.How do you run a build on a specific agent?
agent { label 'linux-large' }. Labels group agents by capability/OS. agent any picks any available; agent { docker { image '...' } } spins up a container.How do you parallelise tests?
A
parallel block inside a stage runs nested stages concurrently. For shards, generate a map programmatically; for matrix runs, use the matrix directive.What's the post block?
Runs after the main stages. Conditions:
always, success, failure, unstable, changed. Use for publishing reports, sending notifications, cleanup.How do you publish a Playwright HTML report?
HTML Publisher plugin:
publishHTML([reportDir: 'playwright-report', reportFiles: 'index.html', reportName: 'Playwright Report']). Appears as a link on the build page.Jenkins vs GitHub Actions for an SDET team?
Jenkins if you need full on-prem control, deep enterprise plugin needs, or complex orchestration across heterogeneous platforms. GitHub Actions for simpler/medium teams already on GitHub — less ops, faster setup. Many orgs run both.
What is JCasC?
Jenkins Configuration as Code — declare the controller's full configuration (users, plugins, credentials, agents, jobs) in YAML. Reproducible installs, version-controlled, easier disaster recovery than clicking through the UI.