Git
Jenkins

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

More than 3 years have 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 で管理するのは良いアイデアかもしれません。