純規の暇人趣味ブログ

首を突っ込んで足を洗う

GitoliteとRedmineを(ミラーを使わずに)連携する

      2016/07/16    HimaJyun

先日、UbuntuやRaspbianでRedmineをインストールする方法とGitoliteをセットアップする方法をご紹介しました。

次はRedmineとGitoliteを連携して、Redmine上からGitレポジトリを閲覧出来る様にする事なのですが、なぜかミラーを使う方法が多くヒットするので、ミラーを使わない方法をご紹介しようと思います。

Redmine += Gitolite;

RedminにGitレポジトリを連携させると、Redmine上からGitレポジトリ内のファイルを閲覧したり、diffを確認したり、チケット(issue)とコミットメッセージを連動したり、などなど、便利な機能がいくつか利用出来ます。(もちろん、プラグイン次第で可能性は無限大です。)

ただ、Gitoliteはファイルの所有者権限が少々ややこしいのでRedmineと連携させるにはなかなかの苦労を要します。

多くの方はここで諦めて(?)hookを利用してミラーレポジトリを作成、それを参照する、と言うやり方を取っているみたいですが、個人的にそれは少々気に入らなかったので、頑張ってミラーを使わずに連携するとしました。

前提条件

GitoliteとRedmineは「Ubuntu(またはRaspbian)でGitサーバ(Gitolite)をセットアップする」と「Ubuntu 16.04(またはRaspbian)にRedmineをインストールする」で紹介した方法で用意しているとします、すなわち以下の通り。

  • Gitoliteを動作させているユーザ(と言うよりグループ)は「git」
  • Redmineを動作させているユーザは「www-data」
  • Gitoliteのインストール先は「/var/git」(すなわち、レポジトリが「/var/git/repositories」)

さっそく連携させる

もったいぶらずにさっさとご紹介していきましょうか。

Redmineの実行ユーザをGitoliteのグループに追加

Redmineが動作するユーザは「www-data」、レポジトリの所有者は「git」……くっ、読めない!!

そんな時、*nixには「グループ」と言う概念があります。

ユーザ「www-data」をグループ「git」に追加してしまいましょう。

sudo gpasswd -a www-data git

レポジトリにグループ読み取り権を与える

先程の状態ではただ単にグループに追加しただけです。

レポジトリ内のファイルをグループから読み取れる様にする必要があります。

まずは設定変更、エディタで「/(Gitoliteをインストールした場所)/.gitolite.rc」を開きましょう。

sudo editor /var/git/.gitolite.rc

ファイルを開くと「UMASK => 0077」と言う設定項目があると思うので、0077を0027に変更しましょう。

UMASK => 0027

次に、レポジトリのディレクトリにグループに対するアクセス権を与えます。

sudo chmod 750 -R /var/git/repositories

Redmineに登録する

さて、先程の段階で権限が設定出来たので、後は普通にレポジトリを参照出来る様に設定してやればおk!!

プロジェクトのページ->設定->レポジトリ->新しいレポジトリへ進みましょう。
gitolite-redmine-001

以下の様な画面が表示されるかと思われるので、色々設定しましょう。
gitolite-redmine-002

各設定項目は以下の通りです。

  • バージョン管理システム:あなたはGitを使いたいのでしょう?、Gitを選ばなくてどうするの?
  • メインレポジトリ:レポジトリを複数利用する場合に使い分ける?、基本はチェック入でおk
  • 識別子:レポジトリを識別する一意な文字、プロジェクトの識別子と同じで良い(後で使いますので設定して覚えておいて下さい。)
  • レポジトリのパス:読んで字の如く(例:/var/git/repositories/test.git)
  • パスのエンコーディング:デフォルトUTF-8なので変えなくて良い
  • ファイルとディレクトリの最新コミットを~:基本ONで良い

これで追加すると、以下の様にレポジトリの中身がRedmine上から見られます。(何気に右上の統計からはグラフも見られる)
gitolite-redmine-003

おめでとう!!、じゃないんですよねぇ……

hookを利用してリアルタイムに同期

今のままでは先程のページにアクセスしないと、Gitで行った変更が反映されません。

それでは納得がいかないのですが、Redmineには変更を知らせるためのAPIがあります。

これを使って、Gitoliteのpost-receiveのhook発動時に知らせてやりましょう!!

APIキーの準備

まず最初に、Redmineにレポジトリの変更通知を行うためのAPIキーを準備しましょう。

管理->設定->レポジトリ、へと進んで、「リポジトリ管理用のWebサービスを有効にする」にチェックを入れてAPIキーを生産して下さい。

gitolite-redmine-004

このAPIキーは後で使うので覚えておいて下さい。

設定が終わったら保存しましょう、下の方にスクロールしたら保存ボタンがあります。(僕は良く保存を忘れて「動かないな~」とか言ってる)

設定の編集

次はpost-receiveが使える様に設定を変更しましょう。

先程と同じ様に、エディタで「/(Gitoliteをインストールした場所)/.gitolite.rc」を開きましょう。

sudo editor /var/git/.gitolite.rc

まずは「GIT_CONFIG_KEYS」にRedmine用の設定を追加しましょう。

GIT_CONFIG_KEYSの現在の設定に「redmine.*」を追加します。

GIT_CONFIG_KEYS => 'redmine.*'

ファイルの下の方、LOCAL_CODEをアンコメントします。(2つあるので間違えない様に注意)

LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local"

更にその下、repo-specific-hooksがコメントアウトされているのでこれもアンコメント

# allow repo-specific hooks to be added
'repo-specific-hooks',

Redmine用のpost-receive hooksを追加

ここからは普段使いでのPCでの作業です。

まず最初に、gitolite-adminレポジトリのディレクトリに入ります。

# もしまだcloneしていないのであればcloneを先に
git clone ssh://(GitサーバのURL)/gitolite-admin.git
cd gitolite-admin

「local/hooks/repo-specific/redmine」を作成しましょう。

mkdir -p local/hooks/repo-specific
touch local/hooks/repo-specific/redmine

「local/hooks/repo-specific/redmine」に以下のスクリプトを貼り付け(お手製なので雑な所あるかもです、気に入らなかったらご自身で修正して下さい。)

文字コードがCRLFだとシバンでエラーが出るので注意です。

#!/bin/bash

# レポジトリの識別子を取得
IDENTIFIER=$(git config redmine.identifier)
# 空なら何も行わない。
if [ -z "${IDENTIFIER}" ];then
  echo 'redmine.identifier does not exist.'
  echo 'Cancel Redmine updates.'
  exit 0
fi
# RedmineのURLを取得
URL=$(git config redmine.url)
# 空なら終了
if [ -z "${URL}" ];then
  echo 'redmine.url does not exist.'
  echo 'Check the repository configuration.'
  exit 0
fi
# RedmineのAPIキーを取得
APIKEY=$(git config redmine.apikey)
# 空なら終了
if [ -z "${APIKEY}" ];then
  echo 'redmine.apikey does not exist.'
  echo 'Check the repository configuration.'
  exit 0
fi

# curlで変更を通知
echo "Reflect the update to Redmine..."
curl -LsS -w 'Result:Code->%{http_code},Time->%{time_total}s\n' -o /dev/null -A 'Redmine update' "${URL}sys/fetch_changesets?key=${APIKEY}&id=${IDENTIFIER}"
exit 0

作成したファイルをgitに追加して実行権限を与えます。

git add local/hooks/repo-specific/redmine
git config core.filemode false
git update-index -add --chmod=+x local/hooks/repo-specific/redmine

「conf/gitolite.conf」をエディタで開いて、以下の様に設定を追加します。

ここでの(RedmineのURL)はRedmineの入っているサーバから見た時のRedmineのURLなので、VirtualHostを使ってる、とかで無い限りは「http://localhost/」でも大丈夫

repo @all
    config redmine.url = http://(RedmineのURL)/
    config redmine.apikey = (さっきメモったAPIキー)
    option hook.post-receive = redmine

また、各レポジトリの設定に以下の様に識別子を設定します。

repo test
    config redmine.identifier = (さっきメモった識別子)

後はいつも通り。

git commit -am "Add redmine hook."
git push origin master

確認

後は適当にcommitしてみれば良いです。

「remote: Reflect the update to Redmine...」とか出れば少なくとも同期は実行されています。

もし上手く行かない様であれば、Redmineのログを確認してみると良いでしょう。

Gitoliteのhooks追加はクセが強くて難しいため、説明するのもなかなか難しいですが、もしよろしければ参考にしてみて下さい。

 - サーバ運営 ,