เรื่องวุ่นๆของเงื่อนไขใน Jenkins Pipeline

พอดีได้วนกลับมาแก้ไข JenkinsFile เลยคิดว่าไหนๆก็มาแก้อีกรอบแล้ว มาเขียน Blog สรุปเลยดีกว่าใน Jenkins Pipeline ในตัว JenkinsFile เราสามารถเขียนเงื่อนไข หรือ Condition ได้กี่แบบ สำหรับผมจะแบ่งได้ 2 กลุ่ม ดังนี้

  • เงื่อนไข เพื่อให้ Stage นั้นทำงาน (ถูก Execute)
  • เงือนไขใน Step
    • Groovy Style
    • External Style

เงื่อนไข เพื่อให้ Stage นั้นทำงาน (ถูก Execute)

สำหรับในกลุ่มเงื่อนไขที่ที่บอกให้ Stage ทำงานขึ้นมาจะใช้คำสั่ง when โดยมีรูปแบบการใช้งานได้ ดังนี้

  • Branch - ทำต้องเมื่อ Branch ตรงกับที่กำหนดไว้ในเงื่อนไข
    อันนี้ใช้ได้เฉพาะ Job ที่เป็นประเภท multibranch Pipelines
stage('feature_check_health') {
    when {
        branch 'feature/*'
    }
    steps {
        echo 'Build & Test Feature Branch'
    }
}
  • Environment - Execute Stage ในกรณีที่ environment variable มีค่าตามที่ Pipeline กำหนด
stage('DEPLOY_PRODUCTION') {
    when {
        environment name: 'DEPLOY_TO', value: 'production'
    }
    steps {
        echo '.......'
    }
}
  • Expression - ตรงสอบเงื่อนไขตาม Operator
stage('BUILD INTERNAL') {
    when {
        expression {
            return env.BRANCH_NAME != 'master';
        }
    }
    steps {
        echo 'run this stage - when branch is not equal to master'
    }
}
  • Not - อย่าง Pipeline ด้านล่างจะเป็นบอกเงื่อนไขว่า ให้ทำกรณีที่ไม่ใช่ master
    ส่วนตัวผมไม่ค่อยได้ใช้งานนอกจากเคสคู่กับ Branch เลย 555
stage("DB Test") 
{
   when {
      not {
         branch "master"
      }
   }
   steps {
      echo "Execute DB Test."
   }
}
  • allOf - เงื่อนไข และ (AND) ทุก Condition ต้องเป็นจริง
stage ("PACK_DEPLOY_TO_QA")
{
   when {
      allOf {
         expression { return params.PACK_PACKAGE } 
         expression { return params.DEPLOY } 
         environment(name: 'DEPLOY_TO', value: 'qa')
      }
   }
   steps {
      ....
   }
}
  • anyOf - เงื่อนไข หรือ (OR) บาง Condition ต้องเป็นจริง
stage('Deploy') {
   when {
      expression {
         BRANCH_NAME ==~ /(production|sit)/
      }

      anyOf {
         environment name: 'DEPLOY_TO', value: 'production'
         environment name: 'DEPLOY_TO', value: 'sit'
      }
   }

   steps {
      //
   }
}

จริงๆมันมีอีกหลายตัวเลยครับที่ใช้ได้ใน When ลองดูได้จาก Link นี้เพิ่มเติมได้ครับ แต่ส่วนตัวที่ใช้หลักๆ expression / allOf / anyOf / branch และ Environment

คำสั่ง when ในตัว Pipeline ถูก Execute หลังจาก คำสั่ง agent / input / options ทำงานเรียบร้อยแล้ว ถ้าต้องการทำในส่วนของ when ก่อนก็ใช้ตัว beforeAgent / beforeInput / beforeOptions โดยกำหนดเป็น true ก่อนครับ

เงือนไขใน Step

สำหรับเงื่อนไขแต่ละ Step เขียนได้ 2 แบบ

  • Groovy Style เปิด Section Script แล้วเขียน If ได้เลย
steps {
   script {
      if (env.ZIP_KEEP_PACKAGE == 'true') {
         //Do you logic                         
      }
   }
}
  • External Style - เรียกภาษาอื่นๆ แล้วเขียน If เอาครับ เช่น bashshell / powershell ซึ่งบางตัวต้อง ลง Plugin เพิ่มด้วย
    - ตัวอย่างการใช้ PowerShell เขียนเงื่อนไข โดยสามารถใช้งานตัวแปรจาก Jenkins ได้เลย
    แต่ถ้าใช้ตัวแปรของ PowerShell เอง เติม \ ด้านหน้า Jenkins จะได้ไม่ตีความ เช่น \$_.VersionInfo.FileVersion
steps {
   powershell(script: """
   if (-not [string]::IsNullOrWhiteSpace("${ARTIFACTPATH_ALLOC}") -and (Test-Path "${ARTIFACTPATH_ALLOC}\\*"))
   {
      echo "ARTIFACTPATH_BUC : ${ARTIFACTPATH_ALLOC}"
      Get-ChildItem -Path '${ARTIFACTPATH_ALLOC}' -include (ds*.dll', 'ds*.exe') -Recurse | Select-Object -Property Name, @{Name = 'FileVersion'; Expression = {\$_.VersionInfo.FileVersion}} | Export-Csv -Path '${ARTIFACTPATH_ALLOC}\\ALLOC_${BUILDVERSION}.csv'
}
   """)
}

อ๋อ และก็เงื่อนไขแบบนี้นอกจากในส่วนของ Step ยังมาเขียนใน Post Action ได้ด้วย เช่น ในกรณี Sucess ให้ส่ง Notify เข้า mattermost และ TestReport เข้าเมล์ เป็นต้น

post {
   success {
      script {
         if (env.SENDNOTIFY == 'true' && env.ISACTIVENOTI == 'true') {
            mattermostSend (
               color: "#00f514",
               message: "Build SUCCESS: ${env.JOB_NAME} #${env.BUILD_NUMBER} (<${env.BUILD_URL}|Link to build>)"
            )
         
            emailext attachmentsPattern: 'TestResult.zip', body: '${FILE,path="TestSummary.html"}', subject: "${env.JOB_NAME} - Build # ${env.BUILD_NUMBER} - ${env.BRANCH_ON_GIT} - FROM ${env.JENKINS_URL} - ${env.BUILD_PURPOSE} - Test Results", mimeType: 'text/html', to: "${MAILLIST}"
         }
     }
   }
   ........
}                   

Reference


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts to your email.