開発者(個人)のためのJenkins - Git Plugin編

  • 652
    Like
  • 2
    Comment
More than 1 year has passed since last update.

はじめに

「開発者(個人)のための」としているのは、別に自分でやっても良いんだけど Jenkins に任せられるなら任せたい、くらいのモチベーションを表現したつもりです。

環境

  • Ubuntu 14.04 LTS
  • Jenkins 1.573
    • Bootstrap になって雰囲気が変わりましたね

初期設定

Jenkins 初期設定

Plugin のインストール

依存しているPluginも自動的にインストールされます。

Git Parameter Plugin は、ビルド時に Extended Choice Parameter plugin の Single Select ようなパラメータ形式で、リビジョンやタグを選択できるプラグインです。

Git 初期設定

Git Install

Git がインストールされていないなら、apt や yum でインストールしておいて良いでしょう。

一応、Jenkins にインストールして貰うことも可能です。
この場合、使用する Git のバージョンを自由に選べるので、最新版を使うこともできるのですが、sudo 権限が必要です。

Jenkins-Git-Install.png

とはいえ、Git に必要な native library もろもろをインストールするためにも、yum や apt でインストールしておいた無難で楽です。

tar.gz を展開してパスを通すだけで済むなら、Jenkins が勝手にやってくれるのですが、ソースコードからコンパイルする用の tar.gz しか見つからず...

Credential 設定

Jenkins は認証に関する情報をGUI上で設定できます。

Credential Plugin

設定できる情報

  • User/Password
  • SSH鍵
  • 証明書

Scope に Global と System とありますが、
System で設定した場合、ジョブの中で使用できません。
Git Pull/Push などで使用する認証は、Global で作成しましょう。

Jenkins-Credential-Setting.png

もっとも、github から checkout するだけなら認証は必要ありません。

ブランチの設定

あらゆるブランチを対象とする

Branch Specifier を空白にしておけば、全ブランチが checkout の対象となります。
Polling と組み合わせれば、あらゆる commit に対して処理を実行できますね。

特定のブランチを対象とする

Branch Specifier に「master」などと書けば済みますが、パラメータを使っておくと、後で違うブランチをちょっと試したい時に便利です。

Jenkins-Git-Specific-Branch-Param.png

Jenkins-Git-Specific-Branch-Setting.png

↓のように、develop ブランチを試したい時にはそう書いてしまえばよいです。

Jenkins-Git-Specific-Branch-Overwrite.png

Branch Specifier は、Tag や Revision でも指定できます。

ちなみに、変数名を GIT_BRANCH としてしまうと、Git Plugin が生成する環境変数と被るので、避けた方が良いでしょう。

commit があれば自動的にビルドする

手っ取り早いのは Polling です。
最近の Jenkins は、Polling の次実行予想時刻を教えてくれます。
cron 記法がよく分からなくても確かめながら設定できますね。

Jenkins-Git-Polling.png

ちなみに、本当は commit した瞬間にビルドされて欲しいのですが、このままでは、最短でも指定した間隔ごとにしかビルドされません。↑の場合は15分です。
とはいえ、そう頻繁にビルドされてもいちいち Jenkins チェックするの面倒だしなぁ、と個人的に思っているのでこれで良しとしています。
Polling しているジョブが増えて負荷になるようだったら考えます。

なお、hook や api を使って対処している先人たちが大勢いらっしゃいます。

push 前にビルドしたい

Repository URL に指定するのは、要するに、git clone できれば何でも良いので、ファイルパスを指定してしまう手があります。

Jenkins-Git-Local-Path.png

こうすれば、リモートに Push せずともビルドして色々試せます。

commit 前にビルドしたい

commit 前にビルドしたい場合もあるでしょう。

カスタムワークスペースを使うと意図したことができるかもしれません。

Jenkins-Custom-ws.png

この場合 jenkins がアクセスできるディレクトリでなければなりませんが、そのためにわざわざ権限の設定をせずとも、開発で使用しているアカウント or マシンに slave を作ってしまえばなんとでもなります。

commit してもらう

ジョブの中で、commit をしてもらう手もあります。
↑の commit 前にビルドしたい、と組み合わせて、commit の自動化ができます。
私は、jenkins の設定ファイルの backup をする際に活用しています。

git commit 時に、「あなたはだあれ?」と聞かれたら
  # Please tell me who you are. のこと
Custom user name/e-mail address を設定します。
Jenkins の設定で、グローバルな user name/e-mail address を設定できるので、ジョブが複数あって面倒ならこちらを。

merge を試して欲しい

Travis CI が、Pull Request を検知して勝手にマージを試してくれるのと似たようなイメージです。

Git Plugin の Merge before build が手っ取り早いです。

Jenkins-Git-Before-Merge.png

その名の通り、ビルド前(git checkout 直後)に Merge を実行します。
Name of repository には通常、origin を指定すれば良いでしょう。
Repository name は、Repositories の高度な設定で自由に指定できますが、特に指定しなければ origin となります。Jenkins ビルド結果の、コンソール出力 や Get Build Data で確認できるでしょう。

ここでの merge は、次のようなコマンドを実行しているようです。

 > git rev-parse origin/master^{commit} # timeout=10
 > git config core.sparsecheckout # timeout=10
 > git checkout -f origin/master
 > git merge 7357f49924b765627ccd36e0362081875933bdad # timeout=10
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 7357f49924b765627ccd36e0362081875933bdad

conflict が発生するような merge は失敗します。
merge が成功しない限り、ビルド処理は実行されません。

後述する、Git publisher と組み合わせるといい感じです。

例えば ci とか jenkins というブランチを用意しておくとします。
このブランチは、時間のかかるUTや、コードの静的解析、外部サービスの連携などに使用しているとします。
そこで、Merge before build を使って自動的に merge を試し、
時間の掛かる処理を行い、
うまくいったら Git publisher で push 、
とすれば、常に ci ブランチには何らかの処理がなされたファイルが push されるようになります。

よりTravis CIっぽい、Github Pull Request との連携は、GitHub pull request builder plugin でできるようです。まだ私は試したことが無いので割愛します。個人ではあまり使わないですしね。

代わりに参考になる先人方のページを貼っておきます。

http://d.hatena.ne.jp/oovu70/20130118/p1
http://please-sleep.cou929.nu/jenkins-github-pull-request-builder-plugin.html

push を代わりにして欲しい

先にちらりと紹介しましたが、Git publisher が便利です。
もちろん、シェルの実行で git push としても良いですが、Git publisher を使えば、先の「Credential 設定」で作成した認証を使えます。

Jenkins-Git-Publisher-Setting.png

Push Only If Build Succeeds は選択しておくべきです。
ビルドに失敗したものを Push する意味はありません。

Merge Results は、あまり効果を理解していません...
つけてもつけなくても、特に変わりがなかったです。

Tag

Jenkins-Git-Publisher-Setting-Tag.png

Create new tag をチェックしないと、Tagを作ってくれません。
また、すでに存在する Tag 名を指定すると、エラーになります。
Update new tag をチェックすれば更新してくれそうですが、私の環境ではうまく動作しませんでした。

(2015/11/03 追記)
@mechamogera さんのコメント から、 Force Push をチェックすれば、Update new tag が成功することが分かりました!

Jenkins-Git-Publisher-Setting-Tag-force.png

git push -f-f に該当する設定をしておく必要があったのですね。

失敗時のログ

 > git tag -a -f -m Jenkins Git plugin tagging with NewTag NewTag # timeout=10
Pushing tag NewTag to repo origin
 > git push /var/lib/jenkins/GitJenkinsSample NewTag
ERROR: Failed to push tag NewTag to origin
hudson.plugins.git.GitException: Command "git push /var/lib/jenkins/GitJenkinsSample NewTag" returned status code 1:
stdout: 
stderr: To /var/lib/jenkins/GitJenkinsSample
 ! [rejected]        NewTag -> NewTag (already exists)
error: failed to push some refs to '/var/lib/jenkins/GitJenkinsSample'
hint: Updates were rejected because the tag already exists in the remote.
(後略)

成功時のログ

> git tag -a -f -m Jenkins Git plugin tagging with NewTag NewTag # timeout=10
Pushing tag NewTag to repo origin
 > git push /var/lib/jenkins/GitJenkinsSample NewTag -f
Pushing HEAD to branch master at repo origin

Branch

Jenkins-Git-Publisher-Setting-Branch.png

リモートリポジトリに存在しないBranchにはPushできません。

Notes

コミットにコメントを付ける機能ですが、使用シーンがよく分からなかったので飛ばします。
Jenkins のコンソール出力やパラメータを Notes に記入して Git で管理するのは良いアイデアかもしれません。