Go/depを使ったJenkinsビルド

GoのソースをJenkinsからでビルドする方法をまとめてみました。
depを使って依存性を解決した上でビルドというのがなかなか見つけられなかったので色々と試行錯誤してみました。
世の中のプロダクト環境ではもっと良い方法があるのかなとは思いますが・・・

前提

  • Go 1.10.3
  • Jenkins 2.121.3
    • Go plugin 1.2
  • dep 0.5.0

私がGo初心者なのでGo界隈で常識的なやり方などは一切知りません。
そんなかで試行錯誤したやり方という前提でお読みください。

参考サイト

概要

やりたいこととしてはdepで依存性を解決してビルドなのですが、
同じJenkinsに複数のGoプロジェクトがあっても大丈夫なようにしたい。
というのがやりたないという感じでやっています。

そのため、GoのバージョンとGOPATHはプロジェクトごとに変えられるようにしています。

勉強用のコードで作ったものはこちらです。
(masterを参照すると将来的に変わりそうなので動いた当時のコミットです)

環境変数

環境変数の設定処理は下記。

    environment {
        PROJECT_NAME="go-crud-practice"
        TARGET_GO = tool name: 'Go.1.10.3', type: 'go'
        GOPATH = "${JENKINS_HOME}/workspace/${env.JOB_NAME}/GOPATH"
        GOBIN = "${GOPATH}/bin"
        CHECKOUT_DIR = "GOPATH/src/github.com/gloryof/${PROJECT_NAME}"
        PATH= "$PATH:${GOBIN}:${TARGET_GO}/bin"
    }

TARGET_GOはGo pluginから指定したバージョンのGoのパスを参照しています。
GOPATHにはプロジェクトごとのパスを設定します。
上記で設定した内容をPATHに指定してビルド時に使えるようにしています。

CHECKOUT_DIRにはGOPATHの中のdep準拠のディレクトリに構成になるようなパスを設定します。
このCHECKOUT_DIRはチェックアウト処理の時に使います。

depのインストール

depPrepareステージというものを作成して毎回インストールしています。
この書き方だとdepバージョン変わるので指定したバージョンの取り方は調べないと思いつつやってないです・・・

stage("Prepare") {
    steps {
        sh 'go get -u github.com/golang/dep/...'
    }
}

チェックアウト

checkout scmだと指定したパスにチェックアウトする方法を見つけられなかったので、
色々とパラメータを設定して指定したパスにチェックアウトしています。

stage("Checkout") {
    steps {
        checkout([
            $class: 'GitSCM',
            branches: [
                [name: '*/master']
            ],
            doGenerateSubmoduleConfigurations: false,
            extensions: [
                [$class: 'RelativeTargetDirectory', relativeTargetDir: "${CHECKOUT_DIR}"]
            ],
            submoduleCfg: [],
            userRemoteConfigs: [
                [url: 'https://github.com/gloryof/go-crud-practice']
            ]
        ])
    }
}

extensionsRelativeTargetDirectoryを使って指定したパスにチェックアウトします。
relativeTargetDirに先ほどの環境変数で設定したパスを指定します。

Jenkinsのプロジェクト設定

おそらく普通にパイプラインをチェックアウトするでも動くと思いますが、
追加処理のSparse Checkout pathsにパイプラインスクリプトのパスを設定しています。

Sparse Checkout pathsを指定するとパイプライン実行前のチェックアウトは
その指定したパスだけをチェックアウトするようになるのでファイルが少なくなります。

ビルド

あとはビルドでmakeコマンドを実行するだけです。
dirでワーキングディレクトリを変更しないと動きません。

stage('Build') {
    steps {
        dir("${CHECKOUT_DIR}") {
            sh "make"
        }    
    }
}

まとめ

個人的には実戦でも使えるクオリティのスクリプトができてんじゃないかなと思います。
将来的にJenkinsにdepプラグインが出てくればこういうの不要になりそうな気がしますが。