Jenkins是目前大多數(shù)中小公司使用的CI、CD工具,其中Jenkins的任務(wù)又分普通任務(wù)和流水線任務(wù),普通任務(wù)的構(gòu)建和部署在我之前的一篇文章中寫過使用教程# 基于 Docker 安裝 Jenkins,并配置使用 Jenkins 打包 Node 前后端服務(wù)部署到遠程服務(wù)器,但其中流水線任務(wù)可實現(xiàn)我們更復(fù)雜的需求也更自由,不過上手難度也稍微高點。
一、安裝Jenkins
推薦使用 Docker 來安裝Jenkins,更方便后期的遷移部署等,具體安裝步驟可參考
# 基于 Docker 安裝 Jenkins,并配置使用 Jenkins 打包 Node 前后端服務(wù)部署到遠程服務(wù)器
二、普通流水線
這里我將演示使用流水線來部署一個前端項目,其他項目也同樣是這幾個步驟
首先創(chuàng)建一個流水線任務(wù)
在流水線配置這有兩種方式,第一種是直接把流水線腳本寫在配置文本框這,第二種是把腳本寫在項目根目錄下,用Jenkinsfile
文件來寫入,圖下面可以看到有個流水線語法
的按鈕,是可以把具體操作用可視化的方式生成腳本。
我們在文本框這寫入以下腳本內(nèi)容:
pipeline {
agent any
stages {
stage('Build') {
steps {
nodejs('node16') {
sh '''
if hash pnpm 2>/dev/null;
then
echo "pnpm"
else
npm i pnpm -g --registry https://registry.npmmirror.com/
fi
pnpm i
pnpm run build
'''
}
echo '構(gòu)建完成'
}
}
stage('Zip') {
steps {
sh '''
tar -zcvf ${JOB_BASE_NAME}.tgz ./dist/*
rm -rf ./dist/*
mv ${JOB_BASE_NAME}.tgz ./dist
'''
echo '打包完成'
}
}
stage('Deploy') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'tencent', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo \'部署完成\'', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
Stages
: 這個字段下分了幾個單獨的stage
,會從上至下依次執(zhí)行stage
,如果是剛才說的第一種方式,應(yīng)該還會比上面多個拉取代碼的階段。具體拉取代碼的語法可以用上面的流水線語法
頁面可視化生成。
stage('Build')
: 代碼構(gòu)建階段,這里因為是前端項目,用到了node
來構(gòu)建,需要安裝NodeJS
插件,然后去全局工具配置里安裝一下具體的node
版本及設(shè)置下別名。
stage('Zip')
: 壓縮階段,因為我們前端代碼部署只需要部署dist目錄
,把這個目錄tgz壓縮
一下發(fā)到目標(biāo)服務(wù)器。
stage('Deploy')
: 部署階段,需要安裝一個Publish Over SSH
插件,然后通過上面的流水線語法
去可視化配置部署到服務(wù)器的配置,最后把生成的腳本粘貼到這就行。
到這我們構(gòu)建及部署代碼到服務(wù)器的基本配置就完成了,大部分項目其實發(fā)版流程就是這幾步,下面還有幾種流水線進階用法。
三、多環(huán)境部署流水線
有時候我們會遇到多環(huán)境部署的情況,如開發(fā)壞境,生產(chǎn)環(huán)境等,大概就是我們通過在流水線添加一個部署壞境的參數(shù)來控制,在每次構(gòu)建前選擇一下部署的壞境,具體腳本如下:
pipeline {
agent any
parameters {
choice(
description: '你需要哪個機器進行部署?',
name: 'deploy_hostname',
choices: ['tencent', 'dev01', 'tencent、dev01']
)
}
stages {
stage('Build') {
steps {
nodejs('node16') {
sh '''
if hash pnpm 2>/dev/null;
then
echo "pnpm"
else
npm i pnpm -g --registry https://registry.npmmirror.com/
fi
pnpm i
pnpm run build
'''
}
echo '構(gòu)建完成'
}
}
stage('Zip') {
steps {
sh '''
tar -zcvf ${JOB_BASE_NAME}.tgz ./dist/*
rm -rf ./dist/*
mv ${JOB_BASE_NAME}.tgz ./dist
'''
}
}
stage('Deploy to tencent'){
when {
expression { deploy_hostname == 'tencent' }
}
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'tencent', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo \'部署完成\'', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('Deploy to dev01'){
when {
expression { deploy_hostname == 'dev01' }
}
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'dev01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo \'部署完成\'', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('Deploy to tencent、dev01'){
when {
expression { deploy_hostname == 'tencent、dev01' }
}
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'tencent', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo \'部署完成\'', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
sshPublisher(publishers: [sshPublisherDesc(configName: 'dev01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo \'部署完成\'', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
可以看到除了我們之前配置的agent
和stages
還多了一個parameters
的參數(shù)配置,添加了一個deploy_hostname
的選擇參數(shù),有三個值'tencent', 'dev01', 'tencent、dev01'
在具體的stage
里面也多了when
的配置,就是根據(jù)我們選擇的部署環(huán)境參數(shù)來執(zhí)行相應(yīng)壞境的部署流程,當(dāng)when
里面的條件不滿足時,流水線會跳過里面的steps
四、多分支流水線
還有種情況是項目多分支的情況下,每個分支可能對應(yīng)的部署壞境,或者執(zhí)行條件不一樣,就會用到Jenkins的多分支流水線
在新建Jenkins任務(wù)時選擇多分支流水線
在分支源里配置對應(yīng)的git項目地址
和認證憑據(jù)
,保存后他會自動掃描項目里面的分支,我們需要在每個分支下創(chuàng)建一個Jenkinsfile
文件,把我們的腳本寫在這個文件里
具體的構(gòu)建部署腳本可參考之前的普通流水線,如果需要WebHook自動觸發(fā)的可參考下面腳本
pipeline {
agent any
triggers {
GenericTrigger (
causeString: 'Triggered',
genericVariables: [[key: 'ref', value: '$.ref']],
printContributedVariables: true,
printPostContent: true,
token: 'test01'
)
}
stages {
stage('Build') {
steps {
nodejs('node16') {
sh '''
if hash pnpm 2>/dev/null;
then
echo "pnpm"
else
npm i pnpm -g --registry https://registry.npmmirror.com/
fi
pnpm i
pnpm run build
'''
}
echo '構(gòu)建完成'
}
}
stage('Zip') {
steps {
sh '''
tar -zcvf ${JOB_BASE_NAME}.tgz ./dist/*
rm -rf ./dist/*
mv ${JOB_BASE_NAME}.tgz ./dist
'''
}
}
stage('Deploy to tencent'){
when {
branch 'master'
}
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'tencent', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo \'部署完成\'', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('Deploy to dev01'){
when {
branch 'dev'
}
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'dev01', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'echo \'部署完成\'', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/**')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
可以看到上面添加了一個triggers
配置,這個需要安裝Generic Webhook Trigger
插件,然后按上面那樣配置,其中的token配置可以隨意改動,就是我們最終觸發(fā)hooks的url最后面的參數(shù)。
配置完成后,就可以通知http://JENKINS_URL/generic-webhook-trigger/invoke?token=test01
來觸發(fā)我們的hook,一般我們需要在gitlab的Webhooks進行配置觸發(fā)hooks
文章來源:http://www.zghlxwxcb.cn/news/detail-470455.html
到此Jenkins多種流水線的配置介紹就完成了,具體細節(jié)有不了解的小伙伴可在下面評論區(qū)留言。關(guān)于流水線語法每個配置的詳解可參考# Jenkinsfile聲明式語法詳解文章來源地址http://www.zghlxwxcb.cn/news/detail-470455.html
到了這里,關(guān)于Jenkins 流水線多種使用場景詳解(Jenkinsfile,多環(huán)境部署,多分支部署)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!