CircleCI workflow migration to Jenkins on Kubernetes and using the Multibranch pipeline
As a DevOps engineer I am partially involved in migration of CicrleCI workflows to Jenkins on Kubernetes. In this article, I will try to share my knowledge on this topic and I hope it will be useful to you.
Let’s start.
What is CircleCi?
CI/CD platform lets teams build and deliver great software, quickly and at scale, either in the cloud or on a self-hosted server.
What is Jenkins?
Jenkins is a self-contained, open source automation server which can be used to automate all sorts of tasks related to building, testing, and delivering or deploying software.
What is the Kubernetes plugin for Jenkins?
Jenkins plugin to run dynamic agents in a Kubernetes cluster. The plugin creates a Kubernetes Pod for each agent started, defined by the Docker image to run, and stops it after each build.
CircleCI Workflow
Used images: circleci/node:12.16
version: 2.1
defaults: &defaults
docker:
- image: circleci/node:12.16
working_directory: ~/repo
Defined Stages:
- Build: Install dependencies and run ‘npm build’
- Deploy: Publish created package to npmjs.org with ‘npm publish’
- Audit: Run security audit with ‘npm run audit’
jobs:
build:
<<: *defaults
steps:
- checkout
- run:
name: Install dependencies
command: npm ci --prefer-offline
- run:
name: Build library
command: npm run build
- persist_to_workspace:
root: ~/
paths:
- repo
deploy:
<<: *defaults
steps:
- attach_workspace:
at: ~/
- run:
name: Publish package
command: npm publish
audit:
<<: *defaults
steps:
- attach_workspace:
at: ~/
- run:
name: Run npm production dependencies security audit
command: npm run audit
Defined Workflows
- Build’ stage always runs first.
- ‘Deploy’ stage depends on ‘build’ stage, meaning it will run after ‘build’ stage completed. Also, deploy branch runs only for branch starting with ‘publish-v’.
- ‘Audit’ stage depends on ‘build’ stage, it will run after ‘build’ and only for the ‘master’ branch.
- 2nd and 3rd may run in parallel after the 1st stage is finished.
workflows:
version: 2
build-deploy:
jobs:
- build
- deploy:
requires:
- build
filters:
branches:
only: /^publish-v.*/
- audit:
requires:
- build
filters:
branches:
only: master
Let’s create this flow on Jenkins with multibranch pipeline
Definition of pod template: build-pod.yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: node
image: node:12.16
command:
- cat
tty: true
Jenkinsfile
pipeline {
agent {
kubernetes {
label 'ci'
defaultContainer 'jnlp'
yamlFile 'jenkins/build-pod.yaml'
}
}
environment {
branch = "${env.BRANCH_NAME}"
workspace = "${env.WORKSPACE}"
project = "jenkins-example"
}
options {
checkoutToSubdirectory('jenkins-example')
}
stages {
stage('Build') {
steps {
container('node'){
dir("${workspace}/${project}") {
echo "Install dependencies"
sh 'npm ci --prefer-offline'
echo "Build library"
sh 'npm run build'
}
}
}
}
stage('Deploy') {
when {
expression { return branch =~ /^publish-v.*/ }
}
steps {
container('node'){
dir("${workspace}/${project}") {
echo "Publish package"
sh 'npm publish'
}
}
}
}
stage('Audit'){
when {
branch 'master'
}
steps {
container('node'){
dir("${workspace}/${project}") {
echo 'Run security audit'
sh 'npm run audit'
}
}
}
}
}
}
To simplify things, I am not running ‘Deploy’ and ‘Audit’ stages in parallel, which is not correct, so let’s fix that
stage('Run in parallel') {
parallel {
stage('Deploy') {
when {
expression { return branch =~ /^publish-v.*/ }
}
steps {
container('node'){
dir("${workspace}/${project}") {
echo "Publish package"
sh 'npm publish'
}
}
}
}
stage('Audit'){
when {
branch 'master'
}
steps {
container('node'){
dir("${workspace}/${project}") {
echo 'Run security audit'
sh 'npm run audit'
}
}
}
}
}
}
Thank you for reading.
Please subscribe to my YT channel
Please follow me on Twitter (@warolv)