背景:Jenkins 在 docker 容器内运行,效果很好,但按照设计,我们希望所有构建过程都在 docker 容器内运行,以尽量减少安装在 Jenkins 容器内的软件。
问题:如何使用两个不同的 Docker 容器构建一个三阶段流程,其中所有三个步骤共享文件?
步骤 1:构建
- npm 构建
第 2 步:测试
- npm 测试`
步骤 3:运行 AWS code-deploy
- aws deploy push --应用程序名称应用程序名称--s3-location s3://my-bucket/app-name --ignore-hidden-files
- aws deploy 创建部署 --应用程序名称 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'
}
}
}
}
另一个(超级丑陋的)解决方案是创建一个安装了节点和 aws 的自定义映像,但这意味着每次我们迁移到节点和/或 aws 的较新版本时,我们都必须使用更新版本创建另一个 docker 映像,而实际上它们是完全独立的任务。
另一个解决方案是在所有实例之间安装一个共享映像,但如何创建仅为此构建共享的“临时”映像,并在构建完成后删除?
答案1
在我发布问题后,我发现了一篇来自 Jenkins 开发人员的文章
https://jenkins.io/blog/2018/07/02/whats-new-declarative-piepline-13x-sequence-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'
}
}
}
}
詹金斯现在允许声明内部的多个阶段,我不知道“stash/unstash”命令,但这对我来说非常有用。