Redmine on HerokuとBitbucketのGitプライベートレポジトリとの連携を実現するには

チケット駆動開発、スクラムなどの開発体制をとる話の一部で、gitレポジトリとRedmineなどのイシュー管理システム（バグトラッキングシステム、チケット管理システム）とを連動させる話があります。

レポジトリにpushする際のcommit logに、チケット番号を記載し、それをpushされると、レポジトリとイシュー管理システムが連携をとり、当該チケットを完了としcloseする、というような連携の仕方をさせることができます。

### 無料で実現する
Bitbucketは、無料でプライベートレポジトリ（非公開レポジトリ）を利用できます
また、herokuは、一定のトラフィック（など）範囲内であれば無料で利用できるPaaSであり、Redmineを配置できます。Redmineをローカルのvagrantやdocker上に置いても良いのですが、それだとどこからでもアクセスできないのでHeroku上に置いています。

Redmineは、Railsで実装されており、RailsはRuby言語でできており、そのRuby言語の開発者のmatzさんがherokuにいるという関係なので、できないはずはないのです。


### Redmine on herokuについては
いろいろなサイトで解説されていますので、herokuとRedmineの概要を理解していれば、なんとかできるかと思います。

 - [HerokuにRedmineをデプロイする方法 \- Qiita](http://qiita.com/ihatov08/items/a4e7b299486b90bd170a)
 - [herokuにruby2\.0、redmine2\.5\.3環境を構築するお話 \- Qiita](http://qiita.com/ex_SOUL/items/b39fc001efb268be3084)
 - [HerokuでRedmine使ってみた。 \- xxxcaqui\.log](http://xxxcaqui.hatenablog.com/entry/2013/04/30/011552)


### RedmineとBitbucketを連携させる手順
私のほうで、先ほど（2016年9月19日AM1時）試して出来た方法が以下の通りです。
作業PCのOSは、Macです。

1. Redmineのプラグイン[steveqx / redmine\_bitbucket — Bitbucket](https://bitbucket.org/steveqx/redmine_bitbucket)を利用します。（似たようなのがあるのでご注意ください。）
2. ローカルのherokuルートフォルダ下pluginsに移動
3. 当該プラグインをgit cloneします。`$ git clone git@bitbucket.org:steveqx/redmine_bitbucket.git`
4. cloneして出来上がったフォルダの`redmine_bitbucket`に移動
5. .gitフォルダを削除（heroku上でRedmineと違うgitレポジトリがあると別アプリと認識され、うまく動かないため）
6. herokuルートフォルダに戻る
7. ここで、tmpフォルダ以下に、あとで使うbitbucket_reposフォルダを作って、.gitkeepを置く*（tmp以下で無いとファイルが保持されない）*
	8. `$ mkdir tmp/bitbucket_repos`
	9. `$ touch tmp/bitbucket_repos/.gitkeep`
7. `$ mkdir .ssh` で.sshフォルダを作成し、移動。 `$ cd .ssh`
8. `$ ssh-keygen -t rsa -C "bitbucketにユーザ登録しているメールアドレス"`で、SSHキーペアを作成（生成先を聞かれるので、当該redmineルートフォルダ/.ssh/id_rsaを指定。パスフレーズも聞かれますが、無しでそのままEnterしてください。）
9. id_rsaファイルのパーミッションを変更。 `$ chmod 600 id_rsa`
10. id_rsa.pubの中身をコピー。`$ cat id_rsa.pub`で出てきたものをコピーしてもいいですし、`$ pbcopy < ~/.ssh/id_rsa.pub`とか。
11. ブラウザでbitbucketにログイン。右上のアカウント管理をクリック→アカウント管理→右メニューのSSHキーをクリック
12. 鍵を追加ボタンで、Labelは任意のもの。Keyにさきほどコピーしたid_rsa.pubの中身をペーストし、保存。
13. herokuルートフォルダから、herokuにpush。 
	14. `$ git add .`
	15. `$ git commit -m "add plugin file and ssh key for bitbucket-redmine"`
	16. `$ git push heroku master`
	17.  など
18. （pushに失敗していたら当該ファイルはアップロードされないのでご注意を。ちゃんとpush後に表示されるプロンプトを見て完了しているか見てください。）
19. `$ heroku run bash`で、herokuレポジトリ内にssh
20. ここからheroku内（`$`の色が違うなど）
21. `$ ssh -T git@bitbucket.org`を実行し、(yes/no)を求められるのでyes（すいません適当で）。そうすると、Redmineルートフォルダ/.ssh/以下にknown_hostsファイルが作成されます。
22. 当該known_hostsファイルは、ログアウトすると消えてしまうので、`$ cat .ssh/known_hosts`などして出てきたのをコピー
23. `$ exit`で、herokuからログアウト
24. ここからローカル
25. Redmineルートフォルダ下の.sshディレクトリ下に`$ vi known_hosts`などでknown_hostsファイルを作成し、さきほどheroku内でコピーしたものをペーストする。（vi では、pをおせばペーストされます。）
26. ふたたび、herokuルートフォルダから、herokuにpush。
	27. `$ git add .`
	28. `$ git commit -m "add known_hosts"`
	29. `$ git push heroku master`
	30. など
31. ブラウザでRedmineにアクセスし、管理者アカウントで管理メニューを開き、プラグインを開いて、プラグインが表示されているか確認。（「Redmine Bitbucket plugin」があるか。）
32. 当該プラグインの「設定」を開き、「Bitbucketサービスを有効化」にチェックが入っている、「自動cloneを有効化」にチェックが入っていることを確認。ローカルレポジトリパス「tmp/bitbucket_repos」であることを確認（tmp/を追記する必要がある）。
33. 次に同じくRedmineの管理メニュー→設定→レポジトリから、gitが有効になっているか確認し、その下の「コミットを自動取得する」が有効か、「リポジトリ管理用のWebサービスを有効にする」が有効かを確認し、無効なら有効にする（チェックを入れる）
34. その下のAPIキー部分の右側の「キーの作成」を押し、生成されたキーが入力されたら、画面下の［保存］ボタンで保存する
35. ブラウザで、Bitbucketにログインし、連携させたいレポジトリの設定→Servicesを開く。右メニューからPOSTを選択し［Add service］をクリックし、URLを以下のルールで入力し、Saveする。
	36. Redmineの連携させたいプロジェクトにブラウザからアクセスするURLが、`https://example.herokuapp.com/projects/hogehoge`だとすると、
	37. `https://example.herokuapp.com/hooks/bitbucket/hogehoge?key={上記でコピーしたRedmineのAPIキー}`
	38. を入力


という感じです。

スクリーンショットも無く、分かりづらいかもしれないですが、どうも情報が錯綜していましたし、古いものも散見されましたので、一応手順のまとめでした。


# 問題
どうもしばらくすると消えてしまう問題が発生。どうしたらよいか。herokuの構造？　なんとかできないか明日にでも検討予定。。。

*追記*
tmp/以下であればファイルが保持される。そのためtmp/以下にレポジトリを保存するように変更。どのくらい保持されるか、その他問題が無いかなどは不明。
 *→追記*: dynoの再起動時に消去される。2016年6月から無料プランでもクレジットカードを登録すれば1000時間無料になったので24時間稼働は可能だが、何かの拍子で再起動したら消える。ただし、Redmine上には設定が残り、そのままだと再びpushしても連動してくれないため、Redmine上のレポジトリの設定を消去する必要がある。なかなかめんどい。

*追記２*
gitのpush時にコミットコメントに「close #3」などを追記で、連携してチケットをclose出来ない。なんでだろう。設定を見直し中。
 *→追記３*：コミットメッセージを「close #3」など__から始めることで__pushでclose出来た。なるほど。（また複数チケットをcloseしたい場合は、「close #1 #2」などスペース区切りで。カンマ区切りだと動作しなかった。