gitの特定ブランチへのpushをフックしてJenkinsジョブを実行する
Jenkinsプラグインを使えば解決できるらしいけど、社内環境の都合でプラグインを入れるのが大変だったのでbareにフックを仕込んでみた。
Jenkinsジョブを用意
ジョブを作る際、ビルド・トリガでリモートからビルドをチェックする
認証トークンは任意の文字列なので適当に
bareブランチにフックを仕込む
今回はpushをフックしたいので、updateフックを作る
GIT_DIR/hooks/update.sampleをほぼ丸っと使わせてもらうことにした
- 例えばこんな感じで、case文の箇所でdevelopブランチにcommitが追加されたらjenkinsにcurlを投げてジョブを走らせる
- 標準出力に出力したものはpushを叩いたクライアント側に表示される
- Jenkinsのジョブを実行するURLは Jenkins-Host/job/my-job/build?token=文字列
- クエリでもPOSTのボディでもいい
- パラメータ付きで実行するならbuildWithParametersにして、クエリかボディを増やす
#!/bin/sh # --- Command line refname="$1" oldrev="$2" newrev="$3" # --- Safety check if [ -z "$GIT_DIR" ]; then echo "Don't run this script from the command line." >&2 echo " (if you want, you could supply GIT_DIR then run" >&2 echo " $0 <ref> <oldrev> <newrev>)" >&2 exit 1 fi if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then echo "Usage: $0 <ref> <oldrev> <newrev>" >&2 exit 1 fi # --- Check types # if $newrev is 0000...0000, it's a commit to delete a ref. zero="0000000000000000000000000000000000000000" if [ "$newrev" = "$zero" ]; then newrev_type=delete else newrev_type=$(git cat-file -t $newrev) fi case "$refname","$newrev_type" in refs/heads/develop,commit) # execute Jenkins job echo "Automatically execute my-job in jenkins" curl -i -X POST http://Jenkins-Host/jenkins/job/my-job/build?token=520d3a1b13aceb20cf229c1d7f85c4c6 > /dev/null 2>&1 ;; esac # --- Finished exit 0
ハマったこと
update.sampleをそのままコピーして、クライアントからpushを叩くとこんなエラーが出る
*** Project description file hasn't been set
これはupdate.sampleの中でdescriptionファイルを確認するこんなコードが入ってるからで、
該当箇所を消すか、GIT_DIR/descriptionを編集して適当な文字列に変えてやればOK
GIT_DIR/hooks/update.sample 52 # check for no description 53 projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 case "$projectdesc" in 55 "Unnamed repository"* | "") 56 echo "*** Project description file hasn't been set" >&2 57 exit 1 58 ;; 59 esac