Jenkins スクリプトパイプラインの作成

Beginner

はじめに

Jenkins には 2 種類のパイプラインスタイルがあります。宣言的パイプライン(Declarative Pipeline)は構造化された pipeline { ... } ブロックを使用しますが、スクリプトパイプライン(Scripted Pipeline)は nodestage、およびステップ呼び出しを含む Groovy コードを使用します。スクリプトパイプラインは、ワークフローにおいてより直接的な Groovy 制御フローが必要な場合に非常に有用です。

この実験では、scripted-pipeline-demo という名前のパイプラインジョブを作成し、シンプルなスクリプトパイプラインを実行した後、if 条件と try/finally クリーンアップブロックを追加して更新します。

基本的なスクリプトパイプラインの作成

このステップでは、スクリプトパイプラインの最初のバージョンを作成します。node ブロックは、Jenkins に対してエグゼキュータとワークスペースの割り当てを要求します。その内部で、stage はワークフローの可視化された部分を定義し、sh はシェルコマンドを実行します。

/home/labex/project/scripted-pipeline.groovy を作成します:

cat > /home/labex/project/scripted-pipeline.groovy <<'GROOVY'
node {
    stage('Prepare') {
        echo 'Preparing scripted pipeline'
        sh 'pwd'
    }

    stage('Build') {
        echo 'Building with scripted syntax'
        sh 'echo Compiling scripted pipeline demo'
    }
}
GROOVY

構造を確認するために、行番号付きでファイルを表示します:

nl -ba /home/labex/project/scripted-pipeline.groovy

Prepare ステージと Build ステージを含む node ブロックが確認できるはずです。

スクリプトからパイプラインジョブを作成

このステップでは、Groovy スクリプトをインラインで保持する Jenkins パイプラインジョブを作成します。Jenkins のパイプラインジョブは、/var/jenkins_home/jobs 配下に XML として保存されます。Python を使用して Groovy スクリプトを XML エスケープし、引用符や中括弧などの文字が安全に保持されるようにジョブ設定を書き込みます。

パイプラインジョブの設定を生成します:

python3 - <<'PY'
from html import escape
from pathlib import Path

script = Path("/home/labex/project/scripted-pipeline.groovy").read_text()
config = f"""<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
  <actions/>
  <description>Run a Jenkins scripted Pipeline example.</description>
  <keepDependencies>false</keepDependencies>
  <properties/>
  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
    <script>{escape(script)}</script>
    <sandbox>true</sandbox>
  </definition>
  <triggers/>
  <disabled>false</disabled>
</flow-definition>
"""
Path("/home/labex/project/scripted-pipeline-config.xml").write_text(config)
PY

ジョブ設定を Jenkins にコピーしてリロードします:

docker exec jenkins mkdir -p /var/jenkins_home/jobs/scripted-pipeline-demo
docker cp /home/labex/project/scripted-pipeline-config.xml jenkins:/var/jenkins_home/jobs/scripted-pipeline-demo/config.xml
/home/labex/project/reload-jenkins.sh

Jenkins がパイプラインジョブを読み込めることを確認します:

curl -fsS http://localhost:8080/job/scripted-pipeline-demo/api/json | grep -o '"name":"scripted-pipeline-demo"'

スクリプトパイプラインの実行

このステップでは、パイプラインジョブをトリガーして結果を確認します。Jenkins は POST リクエストを Crumb(CSRF トークン)で保護しているため、最初のコマンドで Crumb を要求し、一致するクッキーを再利用します。

最初のビルドをトリガーします:

CRUMB=$(curl -fsS -c /tmp/jenkins-scripted-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -b /tmp/jenkins-scripted-build.cookies -H "$CRUMB" -X POST http://localhost:8080/job/scripted-pipeline-demo/build

ビルド #1 が完了するまで待機します:

until curl -fsS http://localhost:8080/job/scripted-pipeline-demo/1/api/json >/tmp/scripted-build-1.json 2>/dev/null && grep -q '"building":false' /tmp/scripted-build-1.json; do
  echo "Waiting for scripted pipeline build #1..."
  sleep 3
done

ビルド結果を確認します:

curl -fsS http://localhost:8080/job/scripted-pipeline-demo/1/api/json | grep -o '"result":"SUCCESS"'

成功という結果は、Jenkins がスクリプトパイプラインの構文を受け入れ、シェルステップを実行したことを証明しています。

Groovy 制御フローの追加

このステップでは、Groovy 制御フローを使用してスクリプトパイプラインを更新します。if ブロックは Test ステージを実行するかどうかを決定します。try/finally ブロックは、ステージが失敗した場合でもクリーンアップメッセージが確実に実行されるようにします。

パイプラインスクリプトをより高度なバージョンに置き換えます:

cat > /home/labex/project/scripted-pipeline.groovy <<'GROOVY'
node {
    def runTests = true

    try {
        stage('Prepare') {
            echo 'Preparing scripted pipeline'
            sh 'pwd'
        }

        stage('Build') {
            echo 'Building with scripted syntax'
            sh 'echo Compiling scripted pipeline demo'
        }

        if (runTests) {
            stage('Test') {
                echo 'Tests enabled by Groovy condition'
                sh 'echo Running scripted pipeline tests'
            }
        }
    } finally {
        echo 'Pipeline cleanup complete'
    }
}
GROOVY

ジョブ設定を再生成し、Jenkins をリロードします:

python3 - <<'PY'
from html import escape
from pathlib import Path

script = Path("/home/labex/project/scripted-pipeline.groovy").read_text()
config = f"""<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
  <actions/>
  <description>Run a Jenkins scripted Pipeline example.</description>
  <keepDependencies>false</keepDependencies>
  <properties/>
  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
    <script>{escape(script)}</script>
    <sandbox>true</sandbox>
  </definition>
  <triggers/>
  <disabled>false</disabled>
</flow-definition>
"""
Path("/home/labex/project/scripted-pipeline-config.xml").write_text(config)
PY
docker cp /home/labex/project/scripted-pipeline-config.xml jenkins:/var/jenkins_home/jobs/scripted-pipeline-demo/config.xml
/home/labex/project/reload-jenkins.sh

更新されたジョブ設定に新しい Test ステージのテキストが含まれていることを確認します:

docker exec jenkins grep -n 'Tests enabled by Groovy condition' /var/jenkins_home/jobs/scripted-pipeline-demo/config.xml

更新されたパイプラインログの確認

このステップでは、更新されたスクリプトパイプラインを実行し、コンソール出力を確認します。ログには、条件付きの Test ステージメッセージと finally ブロックからのクリーンアップメッセージが表示されるはずです。

2 回目のビルドをトリガーします:

CRUMB=$(curl -fsS -c /tmp/jenkins-scripted-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -b /tmp/jenkins-scripted-build.cookies -H "$CRUMB" -X POST http://localhost:8080/job/scripted-pipeline-demo/build

ビルド #2 が完了するまで待機します:

until curl -fsS http://localhost:8080/job/scripted-pipeline-demo/2/api/json >/tmp/scripted-build-2.json 2>/dev/null && grep -q '"building":false' /tmp/scripted-build-2.json; do
  echo "Waiting for scripted pipeline build #2..."
  sleep 3
done

重要なコンソール行を表示します:

curl -fsS http://localhost:8080/job/scripted-pipeline-demo/2/consoleText | grep -E 'Tests enabled|Running scripted pipeline tests|Pipeline cleanup complete|Finished: SUCCESS'

デスクトップインターフェースから Firefox を開き、http://localhost:8080/job/scripted-pipeline-demo/2/console にアクセスしてください。コンソールページには Test ステージの出力とクリーンアップメッセージが表示されているはずです。

Jenkins スクリプトパイプラインのコンソール出力

まとめ

nodestageecho、および sh ステップを使用して Jenkins スクリプトパイプラインを作成し、それをパイプラインジョブとして実行しました。さらに、Groovy の if および try/finally 制御フローを追加しました。Jenkins のビルド結果とコンソール出力を通じて、両方のパイプラインバージョンが正しく動作することを確認しました。