A Declarative Jenkinsfile That Doesn't Fight You
Scripted Jenkinsfiles turn into unreadable Groovy fast. Declarative syntax with a few escape hatches covers almost everything.
The pipeline
pipeline {
agent { label 'docker' }
environment {
IMAGE = "registry.internal/checkout"
}
stages {
stage('Test') {
parallel {
stage('Unit') {
steps { sh 'make test-unit' }
}
stage('Lint') {
steps { sh 'make lint' }
}
}
}
stage('Build') {
steps {
sh "docker build -t ${IMAGE}:${GIT_COMMIT} ."
}
}
stage('Push') {
steps {
withCredentials([usernamePassword(
credentialsId: 'registry-creds',
usernameVariable: 'REG_USER',
passwordVariable: 'REG_PASS'
)]) {
sh "echo $REG_PASS | docker login registry.internal -u $REG_USER --password-stdin"
sh "docker push ${IMAGE}:${GIT_COMMIT}"
}
}
}
stage('Deploy') {
when { branch 'main' }
steps {
sh "kubectl set image deployment/checkout checkout=${IMAGE}:${GIT_COMMIT}"
}
}
}
post {
failure {
slackSend(channel: '#deploys', message: "Build failed: ${env.BUILD_URL}")
}
}
}
Useful CLI checks against Jenkins itself
Trigger a build from the CLI:
curl -X POST -u user:token "https://jenkins.internal/job/checkout/build"
Tail the console log of the last build:
curl -s -u user:token "https://jenkins.internal/job/checkout/lastBuild/consoleText"
when { branch 'main' } on the deploy stage is what keeps every feature branch from also deploying to prod.