702
692

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-08-12

はじめに

「開発者(個人)のための」としているのは、別に自分でやっても良いんだけど 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 で管理するのは良いアイデアかもしれません。

702
692
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
702
692

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?