在開始說預計最後一個要優化的 - Git branch 之前,想先來談談 Git 的 version 管理,在基本的 prod/ staging /dev 中,我們可以預期在部分時間中,各個 branch 的 source code 是會有差異。故在做 CI Pipeline 時,需要依照不同的 branch ,提供對應的 pipeline。
在 Jenkins 中有針對可以因應不同 branch 下我們需要跑 CI / CD Pipeline 的需求的解決方案。
舉例來說,我們希望只有在 main branch 時,才去做 docker image 的 build。而在 branch 時,只需要做到 Test 即可。
stage("Build"){
when{
branch "main"
}
......
}
也可以在不同 branch 下,進行不同環境參數的引入。
接下來我們要來做一個 Multibranch Pipeline 的範例: ithome-crawler-ci
在建立 item 的頁面中,我們選擇 Multibranch Pipeline,在設定完名稱後,會進入一個與 Pipeline 設定時類似的頁面。
在 Branch Sources 中輸入我預先寫好的 github project https://github.com/ben4932042/ithome-crawler.git
這邊我們預設在 Github Project 有新的 branch 與 tag 時,我們將依序處理。並且這邊尚未設定 branch 的 discover 命名規則。所以預設將會處理 "所有" branch。
當完成時,Multibranch Pipeline 會開始嘗試拉取在 Github project,並且會依照 Jenkinsfile 開始每一個 pipeline 的執行。
Started
......
Fetching upstream changes from origin
> git config --get remote.origin.url # timeout=10
> git fetch --tags --force --progress --prune -- origin +refs/heads/*:refs/remotes/origin/* # timeout=10
Checking branches...
Checking branch main
‘Jenkinsfile’ not found
Does not meet criteria
Processed 1 branches
Checking tags...
Processed 0 tags
[Sun Sep 18 11:59:28 UTC 2022] Finished branch indexing. Indexing took 2.7 sec
Finished: SUCCESS
下面為範例 Jenkinsfile實作
pipeline{
agent {
label 'gcp-agent-1'
}
environment {
IMAGE_REFERENCE = "docker.pkg.github.com/ben4932042/ithome-crawler/scrapy:${env.BRANCH_NAME}"
}
stages{
stage("Setup registry auth"){
steps{
withCredentials([usernamePassword(credentialsId: 'github-registry-secret', usernameVariable: 'USER', passwordVariable: 'TOKEN')]){
script{
sh "docker login docker.pkg.github.com -u ${USER} -p ${TOKEN}"
}
}
}
}
stage("Setup virtual env"){
steps{
sh '''#!/bin/bash
virtualenv venv
source venv/bin/activate
pip3 install -r requirements.txt
pip3 install pylint
pip3 install pytest
'''
}
}
stage("Lint"){
steps{
sh '''
source venv/bin/activate
export PYTHONPATH=${PWD}
pylint --fail-under=10 src
'''
}
}
stage("Test"){
steps{
sh '''
source venv/bin/activate
export PYTHONPATH=${PWD}
pytest tests
'''
}
}
stage("Build"){
when {
branch "main"
}
steps{
sh "docker build -t ${IMAGE_REFERENCE} ."
}
}
stage("Push"){
when {
branch "main"
}
steps{
sh "docker push ${IMAGE_REFERENCE}"
}
}
}
post{
always{
cleanWs()
}
}
}
docker image 的 tag docker.pkg.github.com/ben4932042/ithome-crawler/scrapy:${env.BRANCH_NAME}
取決我們的當前的 branch 名稱。
可以看到只有當 branch 是 main 時,才會處理 Build
與 Push
,可以依照實際情況去更改對應規則。
每一個 branch 皆會成為單一的 pipeline。
https://github.com/ben4932042/ithome-crawler