背景: Jenkins は Docker コンテナ内で実行されており、問題なく動作しますが、設計上、すべてのビルド プロセスを Docker コンテナ内で実行して、Jenkins コンテナ内にインストールされるソフトウェアを最小限に抑える必要があります。
問題: 2 つの異なる Docker コンテナを使用して、3 つのステップすべてでファイルを共有する 3 段階のプロセスを構築するにはどうすればよいですか?
ステップ1: 構築
- npmビルド
ステップ2: テスト
- npm テスト`
ステップ3: AWSコードデプロイを実行する
- aws deploy push --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 ファイルを複数のステージに分割し、最初のステージの出力を他のステージで共有するにはどうすればよいですか?
シンプルな2段階のJenkinsfile
pipeline {
agent {
docker {
image 'node:10.8.0'
}
}
stages {
stage('Build') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
}
しかし、第3段階を追加すると、グローバル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' は失敗します。また、ビルド成果物がすべて失われているため、コード デプロイは機能しません。
テストを機能させるための回避策の 1 つは、イメージを使用する「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'
}
}
}
}
もう 1 つの (非常に醜い) 解決策は、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」コマンドについては知りませんでした。