背景:Jenkins 在 docker 容器內運行,效果很好,但根據設計,我們希望所有建置流程都在 docker 容器內運行,以最大限度地減少 Jenkins 容器內安裝的軟體。
問題:如何使用兩個不同的 docker 容器建立一個三階段流程,其中所有三個步驟共用檔案?
第 1 步:構建
- npm 建構
第 2 步:測試
- npm 測試`
步驟 3:執行 AWS 程式碼部署
- aws部署推送 --application-name app-name --s3-location s3://my-bucket/app-name --ignore-hidden-files
- aws deploy create-deployment --application-name app-name --s3-location bucket=my-bucket,key=app-name,bundleType=zip --deployment-group-name dg
如何將 Jenkins 檔案分解為多個階段,並為其他階段共用第一階段的輸出?
簡單的兩階段 Jenkinsfile
pipeline {
agent {
docker {
image 'node:10.8.0'
}
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
}
但是,當我在第三階段添加時,事情變得更有趣,因為我無法使用全域 docker 映像(代理)
pipeline {
agent none
stages {
stage('Build') {
agent {
docker { image 'node:10.8.0' }
}
steps {
sh 'npm install'
}
}
stage('Test') {
agent {
docker { image 'node:10.8.0' }
}
steps {
sh 'npm test'
}
}
stage('Deploy') {
agent {
docker { image 'coreos/awscli' }
}
steps {
sh 'echo "Deploying to AWS"'
sh 'aws help'
}
}
}
}
在上面,「npm test」失敗,因為建置階段的結果遺失。而且,程式碼部署將無法運作,因為所有建置工件都遺失了。
進行測試工作的解決方法是使用影像的「BuildAndTest」階段,但這會失去單獨步驟的一些優點。
pipeline {
agent none
stages {
stage('Build And Test') {
agent {
docker { image 'node:10.8.0' }
}
steps {
sh 'npm install'
sh 'npm test'
}
}
stage('Deploy') {
agent {
docker { image 'coreos/awscli' }
}
steps {
sh 'echo "Deploying to AWS"'
sh 'aws help'
}
}
}
}
另一種(超級難看)的解決方案是創建一個安裝了Node 和AWS 的自訂映像,但這意味著每次我們遷移到Node 和/或AWS 的較新版本時,我們都必須使用更新版本創建另一個docker 映像,而實際上它們是完全獨立的任務。
另一個解決方案是在所有實例之間安裝共用映像,但如何建立僅此建置共用並在建置完成後被刪除的「臨時」映像?
答案1
就在我發布問題後,我發現了一篇來自 Jenkins 開發人員的文章
https://jenkins.io/blog/2018/07/02/whats-new-declarative-piepline-13x-sequential-stages/
這就是我想出來的
pipeline {
agent none
stages {
stage('Build and Test') {
agent {
docker 'node:10.8.0'
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
post {
success {
stash name: 'artifacts', includes: "node_modules/**/*"
}
}
}
stage('Deploy') {
agent {
docker 'coreos/awscli'
}
steps {
unstash 'artifacts'
sh 'echo "Deploying to AWS"'
sh 'aws help'
}
}
}
}
Jenkins 現在允許聲明性內部有多個階段,而且我不知道「stash/unstash」指令,這對我來說非常有用。