miya’s blog

プログラミングの学習を通じて得た知識や感じたことをシェアするブログです。

CI/CDわからないけどJenkinsでパイプラインをつくってみた

目次

はじめに

Jenkins(ver2.0系)のパイプラインで手作業をジョブ化した初心者のメモ書きです。

公式ユーザガイドは情報量が多くて、どこから読むべきかなのか少々わかりにくかったので、Declarative Pipelineでジョブを実装するまでに調べたことを整理しました。

想定する読者レベル

  • Jenkins、CI/CDがよくわからない。
  • Jenkinsでパイプラインを作って動かしてみたい。

Jenkinsについて

できることは大まかに👇な感じ

  • リポジトリGitHubなど)の資材をコントローラやエージェントに展開できる
  • コントローラからエージェントに対して任意のコマンドを実行できる

ver2.0のリリースが2016年なので、2017年前後に書かれた情報が多い印象です。

使い方について

環境構築

「親機/子機」を「コントローラ/エージェント」といいます。かつての「マスター/スレーブ」 > 用語集

インストール

コントローラに「Jenkins本体 & Java」、エージェントに「Java」をいれます。

  • 手っ取り早くコントローラを構築したいならこちら
    • Dockerのインストールが前提。
    • APIキーの取得方法の説明もあります。
  • 公式な手順はこちら
    • OSに直接インストールする方式
    • Javaインストールの説明もあります。

コントローラとエージェントを紐付け

お試しで動かすだけならスキップして、エージェントなしでもOKです。

開発ツールを用意

お試しで動かすだけならスキップしてOKです。

パイプラインの書き方

Pipelineについて

Declarative Pipelineについて

Groovyについて

  • バージョン確認方法はこちら
  • 基本構文はこちら
  • デバッグ手法はこちら
    • JenkinsDSLとはそこそこ違う(例: ×echo ⚪︎println)ので、Script{}の実装を関数に切り出すと使いやすいかも。

パイプラインをパラメータ付きビルドで動かす

コントローラからファイルを取得します。実行環境は Ubuntu 22.04.3 LTS🐧

  • 動かし方は以下の通り

    1. 新規ジョブの作成 > パイプラインを選択 > パイプラインの定義にサンプルコードをコピペして保存。
    2. ビルド実行する(エラー終了)。画面を再ロードすると"パラメータ付きビルド"を選べるようになる。
    3. パラメータ付きビルドを実行して成功すれば、ビルドの成果物(ip.txt, hosts) をダウンロードしたり、Console Outputから実行ログをみれたりできます。
  • 公式資料は → Getting started with Pipeline

// Jenkinsfile

pipeline {
    agent any

    parameters {
        string(name: 'user_id', defaultValue: '999', description: '998 か 999 なら動くよ)')
        booleanParam(name: 'require_confirmation', defaultValue: true, description: '実行確認したければオン')
    }

    stages {
        stage('precheck') {
            steps {
                sh "uname -n; id; pwd; ls -l"

                script {
                    checkPermission(params.user_id)
                }
            }
        }

        stage('confirmation') {
            when {
                expression { params.require_confirmation.toBoolean() }
            }
            steps {
                input message: "やっていいかい # ${env.BUILD_NUMBER}",
                    ok: 'いいとも'
            }
        }

        stage('execute') {
            steps {
                sh "ip a > ip.txt"
                sh "cat /etc/hosts > hosts"
            }
        }
    }

    post {
        always {
            echo currentBuild.result
        }
        success {
            archiveArtifacts artifacts: '*', onlyIfSuccessful: true
        }
        cleanup {
            cleanWs()
        }
    }
}

def checkPermission(String userId) {
    def allowedIds = ['998', '999']
    if (!(allowedIds.contains(userId))) {
        error "Permission denied: ID ${userId} is not allowed."
    }
}

そのほか

  • グローバル変数について

    • env: Jenkinsfile内ならenvironment{}、Jenkins全体ならダッシュボード >【Jenkinsの管理】でセット
    • params: パラメータ付きビルド時のWeb画面からの入力欄の値(parameters{})
  • 環境変数(env)の制約

    • 文字列 or 戻り値が文字列となる関数 しかセットできないっぽい。これか..?
    • the Global Variable Reference only contains documentation for variables

  • 使いやすそうな環境変数

    • WORKSPACE、BUILD_USER_ID、JOB_NAME、GIT_BRANCH、GIT_URL とか?
  • "${xxx}" という変数の書き方

    • Jenkins全体の環境変数を参照するときの書き方
    • 式展開の書き方
      • echo は文字列しかとれないので、配列やハッシュを出力したい時とかに使う
  • ヒアドキュメントの書き方

  • エージェントを動かしたい

    • agent {} で指定する。
  • ハマったときは

感想

ハンズオンしていけば段々と公式ユーザガイドを読むのが苦でなくなります(多分)📚

あとはやりたいことをキャッチアップしつつ頑張ってください(← 筆者がいまココ)☕

Jenkinsの主な用途はCI/CDだと思いますが、それ以外の自動化にも活用できますので自動化に取り組みたい人の第一歩の助けになれば幸いです。

最後までお読んでいただきありがとうございました。