Jenkins Shared Library Nedir?

Caner Dikkollu
adessoTurkey
Published in
6 min readJun 10, 2022

Jenkins ile basit işler yapıp hızlanmaya başladınız ve yetkinliklerinizi arttırmak mı istiyorsunuz? Oluşturduğunuz pipelinelarda çok fazla tekrar eden ve bakımını zorlaştıran komutlar mı bulunuyor? Bu sorulara cevabınız evet ise ve daha önce jenkins shared library kullanmadıysanız birlikte ilk adımları atmaya hazırız demektir.

Akış

1. Jenkins Shared Library Nedir?
2. Jenkins Shared Library Dosya Yapısı Nasıldır?
3. Jenkins Shared Library Nasıl Kullanılır?

1. Jenkins Shared Library Nedir?

Genellikle modern uygulamaların küçük bileşenlere ayrılarak mikroservis mimarisinde çalıştığı bir dönemdeyiz. Monolitik bir uygulamaya kıyasla mikroservis mimarisine sahip bir uygulamada ekstra birçok pipeline bulunmaktadır. Bu nedenle oluşturulan pipelineların modülerliği ve tekrar kullanılabilirliğini sağlamak oldukça önemlidir. Jenkins Shared Library sayesinde pipeline içerisindeki kod kalabalığından kurtulabilir ve DRY(Don’t Repeat Yourself) prensibine uyum sağlayabiliriz.

Örnek: Birden fazla servis için ortak olarak yaptığınız docker build işlemini tüm servisler için tek bir fonksiyona dışardan sadece docker image bilgilerini göndererek sağlayabilirsiniz.

// var/dockerBuild.groovy
#!/usr/bin/env groovy
def call(String REPOSITORY) {
String REGISTRY = "canerdikkollu"
sh "docker build -t ${REGISTRY}/${REPOSITORY}:latest ."
}
// Jenkinsfile
@Library('mylibrary') _
pipeline {
stages {
stage('Docker Build') {
dockerBuild "nodejs-helloworld"
}
}
}

2. Jenkins Shared Library Dosya Yapısı Nasıldır?

Shared library, Jenkins’e kodlarınızı nasıl yükleyeceğinizi söyleyen bir dosyalama yapısına sahiptir. src, vars ve resources adlarında üç ana dizinden oluşur.

https://www.jenkins.io/doc/book/pipeline/shared-libraries/

src dizini; standart Java kaynak dizin yapısı gibi görünür. Bu dizin, pipeline yürütülürken sınıf yoluna eklenir.

// src/org/foo/Point.groovy
package org.foo
// point in 3D space
class Point {
float x,y,z
}

vars dizini; pipelineda bir değişken olarak gösterilen komut dosyalarını içerir. Dosyanın adı pipelineda değişken adı olarak kullanılabilir. Aşağıdaki örnekte oluşturulan sayHello.groovy dosyası için pipeline da sayHello komutu kullanılabilir olacaktır.

// vars/sayHello.groovy
def call(String name = 'human') {
// Scripted Pipeline
echo "Hello, ${name}."
}

Diğer bir kullanım şekli de call metodu yerine tek bir script içerisinde birden fazla fonksiyon oluşturmak.

// vars/log.groovydef info(message) {
echo "INFO: ${message}"
}

def warning(message) {
echo "WARNING: ${message}"
}

Pipeline içerisinde log.info veya log.warning şeklinde fonksiyonlara erişilebiliyor.

// Jenkinsfile@Library('utils') _log.info 'Starting'
log.warning 'Nothing to do!'

resources dizini; pipeline için gereken tüm groovy olmayan dosyalar bu klasörde saklanabilir. Derleme sırasında bir API çağrısı yapmak için json şablonuna ihtiyacınız olduğunu varsayalım. Bu şablonu resources klasöründe saklayabilir ve libraryResource işlevi kullanarak shared library içerisinde çağırabiliriz.

3. Jenkins Shared Library Nasıl Kullanılır?

  • Ön Hazırlık

İlk olarak Jenkins çalışma ortamına ihtiyacımız var. Bu kurulum işlemi için farklı alternatifler mevcut. (https://www.jenkins.io/doc/book/installing/) Eğer makinenizde docker kurulu ise oluşturduğum hazır docker image’i ile bir jenkins çalışma ortamı ayağa kaldırabilirsiniz. (https://github.com/canerdikkollu/jenkins-installation.git)

docker run -it \
-p 8080:8080 -p 50000:50000 \
-e JENKINS_OPTS="--prefix=/jenkins" \
-e JENKINS_ADMIN_ID=admin \
-e JENKINS_ADMIN_PASSWORD=secret \
canerdikkollu/jenkins:latest

Bu kullanım örneğinde aşağıda çizmeye çalıştığım yapıya uygun bir örnek yapmaya çalışacağız. Nodejs ile yazılmış basit bir uygulamayı jenkins shared library scriptlerini kullanarak docker build işleminin ardından dockerhub’a yükleyeceğiz.

— Github’a nodejs ile yazılmış bir “helloworld” reposu ekledim. (https://github.com/canerdikkollu/nodejs-helloworld.git)

— Jenkins shared library için oluşturduğum scriptlerde github’da ayrı bir repoda bulunuyor. (https://github.com/canerdikkollu/jenkins-shared-library.git)

Adım 1: Jenkins shared library oluşturma

Jenkins shared library’nin ilk olarak groovy scriptlerini oluşturup git’e push’layalım. Bu örnek için iki adet basit scriptimiz bulunuyor. Docker build işlemini ve docker push işlemlerini bu scriptleri kullanarak gerçekleştireceğiz.

// vars/dockerBuild.groovy
#!/usr/bin/env groovy
def call(String APP_IMAGE_REGISTRY, String APP_IMAGE_REPOSITORY) {
dir("${WORKSPACE}") {
sh "docker build -t ${APP_IMAGE_REGISTRY}/${APP_IMAGE_REPOSITORY}:\$(git rev-parse HEAD) ."
}
}
// vars/dockerPush.groovy
#!/usr/bin/env groovy
def call(String APP_IMAGE_REGISTRY, String APP_IMAGE_REPOSITORY) {
dir("${WORKSPACE}") {
sh "echo $DOCKERHUB_CRED_PSW | docker login -u $DOCKERHUB_CRED_USR --password-stdin"
sh "docker push ${APP_IMAGE_REGISTRY}/${APP_IMAGE_REPOSITORY}:\$(git rev-parse HEAD)"
}
}

Şimdi sırada Jenkins’e Global Pipeline Library ekleme işlemi var. Jenkins dashboarda erişim sağladıktan sonra, Manage Jenkins > Configure System yolu takip edilerek Global Pipeline Libraries bölümü bulunur ve yeni bir library eklemek için add butonuna tıklanır. İlgili alanlar görseldekilere benzer bir şekilde doldurulabilir. Default version kısmında branch adına göre versiyonlama yapabilirsiniz.

Adım 2: Jenkinsfile oluşturma

Oluşturacağımız Jenkinsfile’a bir önceki adımda oluşturduğumuz library’i

@Library(‘[library name]’) _

şeklinde ekleyebiliyoruz. Eğer library’nin belirli bir versiyonunu kullanmak istersek adı belirttikten sonra @ parametresinin ardından versiyon tagini belirtebiliriz.

@Library(‘[library name]@[library version]’) _

Bu demo’da kullanacağımız Jenkinsfile şu şekilde olacak:

@Library('my-shared-library') _pipeline {
agent any

environment {
DOCKERHUB_CRED=credentials('docker-hub-credential')
}
stages {
stage('Set Environment') {
steps {
script {
REGISTRY = "canerdikkollu"
REPOSITORY = "nodejs-helloworld"
}
}
}
stage('Hello') {
steps {
sayHello "caner"
}
}
stage('Build') {
steps {
dockerBuild "${REGISTRY}", "${REPOSITORY}"
}
}
stage('Push') {
steps {
dockerPush "${REGISTRY}", "${REPOSITORY}"
}
}
}
}

Adım3: Jenkins multibranch pipeline oluşturma

Oluşturduğumuz nodejs-helloworld reposu için Jenkins’de bir pipeline oluşturalım. Bu işlem gerçekleştirilirken dikkat edilmesi gereken nokta repo içerisinde bulunan Jenkinsfile’ın path’inden emin olmaktır.

OK diyerek devam ettikten sonra dosyalarım GitHub’da bulunduğu için kaynak olarak GitHub seçip ardından repo url’ini ekliyorum.

Repo içerisinde bulunan Jenkinsfile herhangi bir klasör altında olmadığı için sadece adını belirtmem yeterli olacaktır. Örneğin Jenkinsfile dosyam build adında bir klasör altında bulunuyor olsaydı; Script Path kısmına build/Jenkinsfile yazmam gerekirdi.

Adım 4: Dockerhub için kimlik tanımlanması

Bu adım oluşturulan docker image’in dockerhub’a push’lanması için gerekmektedir. Jenkins credentials sayfasında “docker-hub-credential” adında username-password tipinde bir kimlik tanımlanması yapıyorum. Bu alanlara dockerhub kullanıcı ve şifre bilgilerimi tanımlıyorum.

Adım 5: Pipeline build işlemi

Tüm işlemlerin ardından artık oluşturduğumuz pipeline test edilmeye hazır.

Pipeline’a erişim sağlayıp build işlemini başlatabiliriz.

Çalıştırma işlemi başladıktan sonra docker build işleminin gerçekleştirilmesi gerekiyor. docker build işleminde tag olarak git commit hashini kullanıyorum.

Build işlemi başarılı bir şekilde tamamlandıktan sonra oluşturduğumuz docker kimlik bilgileri kullanılarak dockerhub’a giriş işlemi gerçekleştirilir. Ardından oluşturulan docker image’inin dockerhub’a aktarılması sağlanır. Jenkinsfile’ın görevi bu noktoda başarılı bir şekilde son buluyor.

Dockerhub’da belirlediğimiz tag adına göre image kaydının oluşup oluşmadığını kontrol etmekte fayda var.

Her şey yolunda gibi görünüyor Jenkins shared library kullanarak oluşturduğumuz pipeline sayesinde dockerhub’da kullanıma hazır bir image’mız bulunuyor. Ayrıca artık farklı uygulamalar için yapacağımız docker build ve push işlemlerinde kullanıma hazır bir shared library’miz var. 🎉

Referanslar

https://www.jenkins.io/doc/book/pipeline/shared-libraries/
https://devopscube.com/jenkins-shared-library-tutorial/
https://phoenixnap.com/kb/jenkins-shared-library

--

--