【Jenkins】Pipelineジョブを使ってみよう ~ 基本編 ~

CI/CD
freeillustratedによるPixabayからの画像


はじめに

こんにちはSREエンジニアのMakiです。
この記事ではJenkins Pipeline ジョブの作成方法について紹介します。
Pipelineジョブを使うのが初めての方に向けて基本的な使い方を説明していきたいと思います。

Jenkins Pipelineジョブを使ってみよう ~ 基本編 ~

シナリオ

【Jenkins】フリースタイルジョブを使いこなそう!~ かわいい子猫の画像を取得してみる ~

こちらの記事で紹介した猫の画像を取得するフリースタイルジョブと同じことをパイプラインジョブで実現します。

Pipelineジョブを作成する

  1. 新規アイテムの作成
    新規アイテムの作成

  2. kitten_image_generator_pipeline という名前でPipelineを作成する
    Pipeline作成

設定の入力

実行部分以外の設定はフリースタイルジョブの作成と同じ要領で入力します。

  1. 説明
  2. Throttle Concurrent Builds
  3. ビルドのパラメータ化
  4. 古いビルドの破棄
    設定の入力
スクリプト作成1 (型を理解する)

Pipelineのスクリプトはここに書いていきます。

Pipeline作成

ですが、、、

ここに直接Pipelineを書いていくのは書くスペースが小さくて非常に効率が悪いです。

Visual Studio Code にPipeline編集用に以下のプラグインがあるのでインストールして使うのがおすすめです。

  • JenkinsFile Support

    Jenkins Pipelineの書式に従ってハイライトしてくれたり、コードサジェストしてくれたりと、Pipeline開発を強力にサポートしてくれます。

  • Jenkins Pipeline Linter Connector

    Pipeline のシンタックスチェックを行ってくれるプラグインです。
    Jenkins Pipeline はお作法に則って書かないとすぐにシンタックスエラーとなってしまうので、こまめにこのプラグインを使ってチェックすることで効率よく開発が行えるようになります。

また、Pipeline SyntaxというPipelineの作成をサポートしてくれる機能がJenkinsに標準搭載されています。
これもとても便利な機能なので合わせて使っていくとより素早くPipelineを作れるようになると思います。


ここからは Visual Studio CodePipeline Syntaxの説明を交えながら実際にパイプラインを作っていきます。

  • まずはVSCodeの言語設定で JenkinsFile を選択します。

    画面右下から言語選択をします。

    VSCode

  • JenkinsFileを選択します。
    VSCode

  • pipeline と入力してサジェストされたらそのままエンターを押してください。
    pipeline

  • Pipelineの型が出来上がります。
    pipeline

  • ここに修正を入れていきます。

pipeline{               // <--- A
    agent{              // <--- B
        label "node"    // <--- C
    }
    stages{             // <--- D
        stage("A"){     // <--- E
            steps{      // <--- F
                echo "========executing A========"   // <--- G
            }
            post{  // <--- H
                always{
                    echo "========always========"
                }
                success{
                    echo "========A executed successfully========"
                }
                failure{
                    echo "========A execution failed========"
                }
            }
        }
    }
    post{
        always{
            echo "========always========"
        }
        success{
            echo "========pipeline executed successfully ========"
        }
        failure{
            echo "========pipeline execution failed========"
        }
    }
}

必ず記載するブロック

A) pipeline

Pipeline ブロックはDeclarative Pipelineを書く時のおまじないです。
java で言うpublic static void main(String[] args) です。
とりあえず書きましょう。

B) agent

実行するノードを記入します。
特に指定しない場合は agent any
スレーブを設定している場合は labelを使って指定しましょう。

C) lavel

スレーブに設定してある名前を書くことで実行ノードを制御できます。

今回は slave1 と書きます。

D) stages

さらに続くstage のセクションを包むブロックです。

E) stage

処理の固まりを表現するブロックです。本で例えると章立ての部分がstage になります。
Pipelineを作ることはストーリーを作ることだと思います。わかりやすいストーリーにするためには章立てが大事です。
誰にでも伝わるストーリーにするためにもstageブロックにどのような文言を入れるかはしっかり吟味しましょう。

今回は download kitten image としたいと思います。

F) steps

stepsブロックの中に必要な処理を書いていきます。

必要に応じて記載するブロック

G) echo

パイプラインのコンソールにメッセージを出力するステップです。
本当にただのechoです。

H) post

特定の処理が行われた後に実行する後処理を記載することができるブロックです。stepsまたはstagesの後ろに書くことができます。

その際にstepsや、stagesの処理が成功したかどうかに応じて内容を振り分けることが可能です。

always 常に実行
success 前の処理が成功時のみ実行
failure 前の処理が失敗時のみ実行

このように使い分けることが可能です。

これらは特に必要がなければ書く必要はありません。

今回は、猫の画像をダウンロードするのに成功したら保存。

処理が終わったら成否に合わせてSlack通知の実行、加えてワークスペースの削除を行いたいので以下のものを残したいと思います。

  1. steps > post > success
  2. stages > post > always
  3. stages > post > success
  4. stages > post > failure

  • スクリプトを修正
pipeline{
    agent{
        label "slave1"
    }
    stages{
        stage("download kitten image"){
            steps{
                echo "=== start download kitten image ==="
                echo "=== end download kitten image ==="
            }
            post{
                success{
                    echo "======== executed successfully ========"
                }
            }
        }
    }
    post{
        always{
            echo "========always========"
        }
        success{
            echo "========pipeline executed successfully ========"
        }
        failure{
            echo "========pipeline execution failed========"
        }
    }
}

ではこれをもとに行いたい処理を追加していきます。

やりたいことおさらい

  1. shellを実行して猫の画像を取得する
  2. 取得した画像を成果物として保存する。
  3. Slackに通知をする。
  4. ワークスペースを削除する。
スクリプト作成2 (shellを実行して猫の画像を取得する)

shellの実行は sh ステップを使います。

VSCodeではサジェストされないのでJenkins標準のSnippet Generatorを使います。

  • Pipeline Syntax を選ぶ
    Pipeline Syntax
  • 左のメニューで Snippet Generatorを選ぶ
  • Stepsから項目を選べるのでsh を選択します。
    sh
  • Shell Scriptに実行処理を入れて Generate Piepeline Scriptを実行する。
    sh
  • shステップの中身が作成されるのでこれをPipelineに書き込みます。
    sh

※注意点

スクリプトのシングルクォーテーション(')の中身はすべて文字列として判断されるので、変数展開がされません。
この例だと${KITTEN_IMAGE_FILE_NAME} の部分が該当します。変数展開されるようにするためには代わりにダブルクォーテーション(")で囲んであげる必要があります。

NG: シングルクォーテーションなので変数展開されない。

sh label: '', script: 'curl --fail -o ${KITTEN_IMAGE_FILE_NAME} http://www.randomkittengenerator.com/cats/rotator.php'

OK: ダブルクォーテーションなので変数展開される。

sh label: '', script: "curl --fail -o ${KITTEN_IMAGE_FILE_NAME} http://www.randomkittengenerator.com/cats/rotator.php"

ここまでのスクリプト

pipeline{
    agent{
        label "slave1"
    }
    stages{
        stage("download kitten image"){
            steps{
                echo "=== start download kitten image ==="
                sh label: '', script: "curl --fail -o ${KITTEN_IMAGE_FILE_NAME} http://www.randomkittengenerator.com/cats/rotator.php"
                echo "=== start download kitten image ==="
            }
            post{
                success{
                    echo "======== executed successfully ========"
                }
            }
        }
    }
    post{
        always{
            echo "========always========"
        }
        success{
            echo "========pipeline executed successfully ========"
        }
        failure{
            echo "========pipeline execution failed========"
        }
    }
}
スクリプト作成3 (画像を成果物として保存する)

成果物の保存も先ほどと同じようにSnippet Generatorから行います。

使用するステップはarchiveArtifactsです。

archive

先ほど同様シングルクォーテーションをダブルクォーテーションに修正してスクリプトに記載します。

ダウンロードが成功したときに実行したいのでstageのpostブロックに記載します。

pipeline{
    agent{
        label "slave1"
    }
    stages{
        stage("download kitten image"){
            steps{
                echo "=== start download kitten image ==="
                sh label: '', script: "curl --fail -o ${KITTEN_IMAGE_FILE_NAME} http://www.randomkittengenerator.com/cats/rotator.php"
                echo "=== start download kitten image ==="
            }
            post{
                success{
                    archiveArtifacts "${KITTEN_IMAGE_FILE_NAME}"
                }
            }
        }
    }
    post{
        always{
            echo "========always========"
        }
        success{
            echo "========pipeline executed successfully ========"
        }
        failure{
            echo "========pipeline execution failed========"
        }
    }
}
スクリプト作成4 (Slackに通知・ワークスペース削除)

ここでも書き方は同じです。Snippet Generatorからスクリプトを作成します。

利用するステップは以下の通りです。

  • Slackに通知: slackSend
  • ワークスペース削除: cleanWs

slackSendの設定

  • Message: "started ${env.JOB_NAME} ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)"
  • Channel: "#topic_step_up_jenkins"

成功時

  • color: "good"

失敗時

  • color: "danger"
slackSend channel: '#topic_step_up_jenkins', color: 'good', message: "finished ${env.JOB_NAME} ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)"

archive

cleanWsの設定

archive

これで完成!! 完成したものをJenkinsの設定に書きましょう。

pipeline{
    agent{
        label "slave1"
    }
    stages{
        stage("download kitten image"){
            steps{
                echo "=== start download kitten image ==="
                sh label: '', script: "curl --fail -o ${KITTEN_IMAGE_FILE_NAME} http://www.randomkittengenerator.com/cats/rotator.php"
                echo "=== start download kitten image ==="
            }
            post{
                success{
                    archiveArtifacts "${KITTEN_IMAGE_FILE_NAME}"
                }
            }
        }
    }
    post{
        always{
            cleanWs()
        }
        success{
            slackSend channel: '#topic_step_up_jenkins', color: 'good', message: "finished ${env.JOB_BASE_NAME} ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)"
        }
        failure{
            slackSend channel: '#topic_step_up_jenkins', color: 'danger', message: "finished ${env.JOB_BASE_NAME} ${env.BUILD_NUMBER} (<${env.BUILD_URL}|Open>)"
        }
    }
}

Pipelineジョブを実行する

  • パラメータ付きビルド
    execute
  • ビルド
    execute
  • Slack通知
    execute
  • ビルド結果確認
    execute

フリースタイルジョブと同様のことを行うことができました。

これでPipelineジョブの基本編は終わりです。


参考になるページ

Jenkins Official

agentstageなど、Pipelineを利用するにあたり必要な型の説明が書かれています。

shechoなど、Pipelineで使うステップの説明が書かれています。

Qiita

私が書いた記事です。1年以上前に書いたものですが、22610回以上閲覧されています。
色々なサンプル作ってあるので是非見てください。

関連 ページ

この記事で書いたパイプラインジョブをフリースタイルジョブで実現するやり方を記載しています。

初めてJenkinsパイプラインについて学ぶ人に向けて書いた記事です。

おすすめ書籍


[改訂第3版]Jenkins実践入門 ――ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)

初めてJenkinsを学ぶ方におすすめです。


Jenkins

Jenkinsでできることについてもう少し詳しく学びたい方におすすめです。


◆Twitterで最新情報を配信していきます。フォローお願いします。

◆無料でLINE@にて最新情報を配信していきます。登録お願いします。
友だち追加

◆SREに関する相談や質問を受け付けております。
問い合わせ

コメント

タイトルとURLをコピーしました