DEV Community 👩‍💻👨‍💻

Cover image for ลด duplicate code ของ Jenkins ด้วย Jenkins shared library
Joe walker
Joe walker

Posted on

ลด duplicate code ของ Jenkins ด้วย Jenkins shared library

ถ้าเกิดว่าใครที่กำลังทำ pipeline แล้วมีการแก้ instruction อะไรบ้างอย่างใน stage นั้นๆ แล้วต้องตามไปแก้ code แบบนี้ในทุก ๆ โปรเจ็กมันก็ไม่จะไม่สนุกใช่ป่ะ

    stage('Build') {
      println("mvn clean install")
    }
    stage('Test') {
      println("mvn clean test")
    }
    stage('Deploy') {
      // Deploy to AWS
    }

สมมติว่าผมมี pipeline อยู่ 10 pipeline แล้วแต่ล่ะ pipeline ก็จะมี code ตามตัวอย่างข้างบนนี้อยู่ทุก pipeline เหมือนกัน

2 เดือนผ่านไป Dev Lead เดินมาบอกว่า เราต้อง deploy app เราทั้ง 10 app ไปที่ google cloud แทนนะ ทำไง??

Solution 1

ง่ายๆเลย ก็เขียน script deploy ใหม่แล้วก็ copy code ไปไว้ที่ pipeline อื่นด้วย

    stage('Deploy') {
      // Deploy to AWS
    }

ข้อเสีย

  • เกิดข้อผิดพลาดได้ง่าย ถึงแม้ว่าจะสามารถ copy script ข้ามไป pipeline อื่นได้แต่ก็ต้องมีการแก้ไข params บางอย่าง ตรงนี้แหละที่อาจจะทำให้เกิดข้อผิดพลาดได้
  • ใช้เวลาในการแก้ไขมากขึ้นถ้าจำนวน pipeline เพิ่มมากขึ้น

Solution 2

ให้เรา export deployment script ออกมาเป็น libs ซะแล้วก็เรียกใช้ deployment libs ตัวนี้แทน แล้วทำไงล่ะ?

Jenkins ได้ provide module ที่ชื่อว่า Global Pipeline Libraries ซึ่งสามารถให้เราเรียกใช้ share libs ใน Jenkins ได้นั้นเอง

ก่อนอื่นเราก็ต้องสร้าง git repo ขึ้นมาใหม่เพื่อใช้เก็บ libs source code ซะก่อน
หลังจากสร้าง repo เสร็จแล้วก็ให้สร้าง file ตามนี้

(root)
+- vars
|   +- maven.groovy
|   +- aws.groovy
|   +- gcp.groovy
|   +- deploy.groovy

สำหรับ file ที่ create ภายใต้ folder vars นั้นจะ expose เป็น variable ทั้งหมด ส่วนชื่อ file ก็คือชื่อ variable นั้นแหละ สามารถอ่านเพิ่มเติมเรื่อง directory structure ได้ ที่นี่

ผมได้ทำการสร้าง libs โดยแยกชื่อไฟล์ตามการทำงานของมันดังนี้

maven.groovy - สำหรับอะไรที่เกี่ยวกับ maven ผมจะใส่ไว้ในนี้ เช่น install dependency, run maven test etc.

aws.groovy - script สำหรับ deploy ไปที่ aws

gcp.groovy - script สำหรับ deploy ไปที่ google cloud

deploy.groovy - script สำหรับ deploy (ขอข้ามรายละเอียดไปก่อนนะ เดี่ยวอธิบายข้างล่าง)

ที่นี้ก็ได้เวลามาเริ่ม export script มาไว้ที่ libs แล้ว

// maven.groovy
def Build() {
    println("mvn clean install")
}

def Test() {
    println("mvn clean test")
}

// aws.groovy
def DeployToECS(app = null) {
    println("deploy ${app} to ecs")
}

// gcp.groovy
def DeployToGKE(app = null) {
    println("deploy ${app} to gke")
}

//deploy.groovy
/**
 * @Param string platform - เลือกว่าจะ deploy platform อะไร (aws, gcp)
 * @Param string app - ชื่อ application
*/
def call(platform = null, app = null) {
    if (platform == "aws") {
        aws.DeployToECS(app)
    } else {
        gcp.DeployToGKE(app)
    }
}

สำหรับ deploy.groovy จะเห็นว่าผมประกาศ function ชื่อว่า call ซึ่งมันจะทำหน้าที่เป็นเหมือน constructor method อ่ะครับ ส่วนหน้าที่ของ method นี้คือรับ params 2 ตัวคือ platform = เลือกว่าจะ deploy platform อะไร กับ app = ชื่อ application แล้วก็ check ว่าถ้า

เสร็จแล้วเราก็ push code ตัวนี้ขึ้น github เป็นอันว่าเสร็จแล้ว

หลังจากนั้นก็เข้าไปที่หน้า Jenkins แล้วไปที่เมนู Jenkins -> Manage Jenkins -> Configure System ไปที่เมนูชื่อ Global Pipeline Libraries หรือว่าเข้าผ่าน url http://<jenkins_host:8080>/configure ก็ได้ครับ

Alt Text

อธิบาย
name ชื่อ library
default version ในที่นี้หมายถึง git branch

ถ้าเกิดว่าไม่อยากจะให้ Jenkins load library เข้ามาให้เลย ก็ติ๊กเครื่องหมายถูกที่ option Load implicitly ด้วย

เสร็จแล้วก็ save

ทีนี้เราก็มาลองสร้าง pipeline สำหรับ test library โดยที่ไปที่หน้า Jenkins dashboard (http://localhost:8080) ของ Jenkins จากนั้นกด New Item -> Pipeline จากนั้น scroll down ไปที่ Pipeline แล้ว copy code ข้างไปไว้ที่ Script

@Library("my-lib") _

node() {
    stage("build") {
        maven.Build()
    }

    stage("test") {
        maven.Test()
    }

    stage("deploy") {
        deploy("aws", "backend")
        deploy("gcp", "frontend")
    }
}

วิธีการเรียกใช้ Library ให้เพิ่ม @Library(ชื่อ lib) _ บรรทัดแรก
อีกวิธีก็คือเลือก option Load implicitly ตอนที่ config Global Pipeline Libraries

Alt Text

พอ create job เสร็จแล้วก็ลองกด build ดูว่า work ป่าว?

Alt Text

ถ้าดูจาก log ข้างล่างจะเห็นว่ามันทำงานได้ถูกต้องตามที่เราต้องการ

Alt Text

สรุป
จะเห็นว่าการ config Jenkins shared libraries ไม่ได้ยากอะไรเลยใช่ม่ะ นอกจากจะช่วยลด duplicate code แล้วยังช่วยลดเวลาในการเพิ่ม ลบ แก้ไข pipeline เราอีกด้วย จะได้เอาเวลา improve pipeline ในส่วนอื่นๆ

ลองอ่าน document เต็มๆ ได้ที่นี่

Top comments (0)

Create an Account! The only reason people scroll to the bottom...  
is because they want to read more.

Create an account to bookmark, comment, and react to articles that interest you.