Jenkins pipeline

jenkins pipeline 基本介紹

Gary Ng
16 min readOct 18, 2020
  1. 首先要先去管理 jenkins 套件的地方檢查是否有安裝 pipeline 套件

pipeline 基本語法

1. agent

指定整個 pipeline 或特定的 stage 將執行在 jenkins 的哪個位置

agent 的參數

a. any

在任何可用的機器上執行 pipeline

b. none

設置為 none 的話代表不設定 global 的 agent, 這樣的話就要在 stage 上去設定 agent

c. docker

d. dockerfile

2. stage

pipeline 的執行階段, 由多個 steps 所組成

3. steps

pipeline 主要執行的任務步驟

4. environment

設定變數給 stage 使用

5. when

可以用來執行程式碼執行的邏輯

6. post

在 pipeline 或 stage 結束時的操作,可以根據 pipeline or stage執行狀態去執行特定的操作, 需搭配 post-condition (always 、changed 、 failure、success、unstable、aborted)

always

無論 pipeline 執行的狀態為何都要執行

changed

當前的 pipeline 與先前的 pipeline 執行狀態不同時執行

failure

pipeline 執行失敗時執行

unstable

當前 pipeline 具有不穩定狀態才會執行

aborted

pipeline 被終止時執行

Pipeline 測試語法

pipeline 實作

  1. 首先要先抓取專案下來也就是用 git
pipeline {
agent any
stages {
// 抓取專案
stage('git clone') {
steps {
git branch: 'main',
url: 'https://github.com/xgaryng/test_php.git'
}
post {
// git clone 失敗
failure {
echo "[*] git clone failure"
}
// git clone 成功
success {
echo '[*] git clone successful'
}
}
}
// more stage

}
}

2. 執行語法檢查 (在 more stage 添加)

stage('Check style') {
// 執行 phpcs 並生成報告檔於 build/checkstyle.xml,
// 副檔名為 php, 且檢查標準使用 PSR2 並忽略 autoload.php 以及 vendor
// check style 的 pattern 使用剛剛產生出來的報告 steps {
sh 'phpcs --report=checkstyle --report-file=`pwd`/build/checkstyle.xml --standard=PSR2 --extensions=php --ignore=autoload.php,vendor/ . || exit 0'
checkstyle pattern: 'build/checkstyle.xml'
}
}

3. 檢查 php code 的 copy paste detection

stage('Copy paste detection') {
steps {
sh 'phpcpd --fuzzy --exclude=vendor/ --log-pmd=`pwd`/build/pmd-cpd.xml src/ || exit 0'
dry pattern: 'build/pmd-cpd.xml'
}
}

4. php unit + 程式覆蓋率

倘若有跑 laravel專案的話需要再 docker file 加入以下指令

apk add php7-pdo_sqlite php7-pdo_mysql php7-session php-bcmath php-gmp php-curl php-pdo php-gd php-ctypestage('Php unit') {
// 跑 phpunit 測試
steps {
sh 'phpunit --coverage-html build/report --whitelist src/ test'
}
}
// 顯示程式覆蓋率
stage('code coverage') {
steps {
publishHTML( [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'build/report/',
reportFiles: 'index.html',
reportTitles: 'Code Coverage',
reportName: 'Code Coverage'
] )
}
}

10. ssh

a. 首先要先生成 jenkins 的 ssh key 以及安裝 ssh

在 docker file 增加以下指令並重新 build

apk add --no-cache openssh ssh-keygen -t rsa -C "jenkins" -m PEM -P "" -f /var/lib/jenkins/.ssh/id_rsa (指定的路徑)

b. 安裝 publish over ssh套件

c. 設定全域的 ssh 設定

先進入到 jenkins 的 system configuration

拉到最下面配置 ssh

d. 將檔案移到遠端主機

stage('deploy') {
steps {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: '在 configuration 設定的 ssh 名稱',
transfers: [
sshTransfer(
cleanRemote: true,
excludes: 'vendor/**, .env, build/**, Jenkinsfile',
execCommand: '',
execTimeout: 120000,
flatten: false,
makeEmptyDirs: false,
noDefaultExcludes: false,
patternSeparator: '[, ]+',
remoteDirectory: '/data/test_php', // 傳到遠端的哪個位置
remoteDirectorySDF: false,
removePrefix: '',
sourceFiles: '**/*' // workspace 整個資料
)
],
usePromotionTimestamp: false,
useWorkspaceInPromotion: false,
verbose: false,

)
],
continueOnError: false,
failOnError: true,
)
}
}

完整 pipeline

pipeline {
agent any
stages {

stage('git clone') {
steps {
git branch: 'git branch',
credentialsId: 'git credentials',
url: 'git url'
}
post {
// git clone 失敗
failure {
echo "[*] git clone failure"
}
// git clone 成功
success {
echo '[*] git clone successful'
}
}
}

stage('Build') {
steps {
sh 'mkdir -p build'
sh 'cp .env.example .env'
sh 'php artisan key:generate'
sh 'composer dump-autoload'
sh 'composer install'
}
}

stage('Check style') {
steps {
sh 'phpcs --report=checkstyle --report-file=`pwd`/build/checkstyle.xml --standard=PSR2 --extensions=php --ignore=autoload.php, vendor/ ./app || exit 0'
checkstyle pattern: 'build/checkstyle.xml'
}
}

stage('Copy paste detection') {
steps {
sh 'phpcpd --fuzzy --exclude=vendor/ --log-pmd=`pwd`/build/pmd-cpd.xml src/ || exit 0'
dry pattern: 'build/pmd-cpd.xml'
}
}

stage('Php unit') {
steps {
sh 'php -d memory_limit=-1 /usr/bin/phpunit -c phpunit.xml tests'
}
}

stage('code coverage') {
steps {
publishHTML( [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'build/report/',
reportFiles: 'index.html',
reportTitles: 'Code Coverage',
reportName: 'Code Coverage'
] )
}
}

stage('deploy') {
steps {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: 'ssh config 名稱',
transfers: [
sshTransfer(
cleanRemote: true,
excludes: 'vendor/**, .env, build/**, Jenkinsfile',
execCommand: '',
execTimeout: 120000,
flatten: false,
makeEmptyDirs: false,
noDefaultExcludes: false,
patternSeparator: '[, ]+',
remoteDirectory: '/data/test_php',
remoteDirectorySDF: false,
removePrefix: '',
sourceFiles: '**/*'
)
],
usePromotionTimestamp: false,
useWorkspaceInPromotion: false,
verbose: false,

)
],
continueOnError: false,
failOnError: true,
)
}
}
}
}

倘若要設定 github webhook

  1. 先進入到 github 的 setting

2. 點選 developer settings

3. 點選 personal access token

4. 點選 generate access token (之後產生出來的 token 要記住)

5. 接著設定 jenkins 的 github server

6. 進入 configuration system

7. 找到 github server

8. github server 名稱輸入可辨識的名稱

9. 點選 credentials 旁邊的 add

10. 將 kind 選擇 secret text

11. secret 貼上剛剛在 github 生成的 personal access token, 而 description 輸入可辨識的文字

12. 設定 github webhook

13. 點選 github repository 的 settings

14. 選擇 webhooks

15. add webhooks

16. 輸入 url

注意: 網址格式必須為 https://domain/github-webhook/

/ 很重要, 倘若沒有最後的 / 會出錯!!!!

17. 之後就可以觸發 github push 的 event 了

18. 也要確定 pipeline 有加以下這段

triggers {
githubPush()
}

19. 完整的 github

參考資料:

--

--

Gary Ng
Gary Ng

Written by Gary Ng

軟體工程師、後端工程師

No responses yet