Amazon Lightsail の Redmine (Bitnami) を Github と連携させたい

## TL; DR

![fig-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4899/3a22c803-ef90-0f09-cb5e-389dc4fb7aa7.png)

Amazon Lightsail [^1] で一発インストールした Redmine と、Github リポジトリを連携させるのに、こちらの記事 [^2] を参考にしてましたが、少し追加の作業が必要だったので、その備忘録です。

### Disclaimer

ちなみに、Ruby系の知識はあまりないので、bundle (bundler) とか gem とかは、実はよく分かっていません…

## サーバスペック(as in 2019/06)

今回の環境は、以下のようなかんじ。

* Amazon Lightsail: 1 GB RAM, 1 vCPU, 40 GB SSD
 * Apps: Redmine
 * Region: Tokyo, Zone A (ap-northeast-1a)
* OS: Ubuntu 16.04.6 LTS
* Apache: 2.4.39
* MySQL: Distrib 5.7.25
* Ruby: 2.5.5p157
* Rails: 5.2.2.1 [^3]
* Git: 2.19.1
* Redmine (Bitnami): 4.0.3.stable

なお、Lightsail で入る Redmine は(他のアプリの場合もだけど) Bitnami 版 [^4] になります。

## 1. Github プラグインのインストール

ここは、こちらのページ [^2] と同じ。
Lightsail のサーバに SSH ログインして、Github プラグイン(redmine_github_hook) [^5] を git clone します。

```shell-session
$ cd /home/bitnami/apps/redmine/htdocs/plugins/
$ git clone https://github.com/koppen/redmine_github_hook.git
```

## 2. Redmine 再起動→エラー

昔ながらの tmp/restart.txt ファイルを作成して、サイトにアクセスして再起動…というやり方は古い [^6] らしい。
なので、以下のように `passenger-config` を使って再起動します。

(ちなみに、このようなやり方 [^7] でミドルウェアをまるっと再起動もできるらしい。)

```shell-session
$ sudo passenger-config restart-app
Please select the application to restart.
Tip: re-run this command with --help to learn how to automate it.
If the menu doesn't display correctly, press '!'

 ‣   /opt/bitnami/apps/redmine/htdocs/
     Cancel
```

エンターを押して、再起動。
特にコンソールにはエラーも出ず、その後、 Redmine を開いてみると…

![fig-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4899/7c0b443c-1966-bde2-4ea5-0f22f6952d84.png)

だめじゃん…orz

## 3. エラーの修正 その1

Apache のエラーログ [^8] を見てみると、こんなエラーが出ていました。

```:/opt/bitnami/apache2/logs/error_log
[[[ snip ]]]

  Message from application: You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.

If this is a development machine, remove the /opt/bitnami/apps/redmine/htdocs/Gemfile 
freeze by running `bundle install --no-deployment`.

The list of sources changed
The dependencies in your gemfile changed
The gemspecs for path gems changed

You have added to the Gemfile:
* source: source at `/opt/bitnami/apps/redmine/htdocs/plugins/redmine_github_hook`
* redmine_github_hook ruby, ruby_18, ruby_19, ruby_20, ruby_21, ruby_22, ruby_23, ruby_24, 
ruby_25, mri, mri_18, mri_19, mri_20, mri_21, mri_22, mri_23, mri_24, mri_25, rbx, 
truffleruby
* rake
 (Bundler::ProductionError)

[[[ snip ]]]
```

なんか、いろいろ足りないっぽい。
ひとまず "If this is a development machine" のところに書いてあるように、Redmine の Gemfile のある場所で、 `bundle install` を実行します。

```shell-session
$ cd /home/bitnami/apps/redmine/htdocs/plugins/
$ bundle install --no-deployment

[[[ snip ]]]

Fetching gem metadata from https://rubygems.org/.............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...

[[[ snip many lines ]]]

Bundle complete! 29 Gemfile dependencies, 60 gems now installed.
Gems in the groups development, test and sqlite were not installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```

つらつらと、gem がインストールされていきます。
もう一度、Redmine にアクセスしてみると…

先ほどと同じ、エラー画面。(だめじゃん！)

## 4. エラーの修正 その2

再度、Apache のエラーログを見ると、今度は別のエラーが。

```:/opt/bitnami/apache2/logs/error_log
[[[ snip ]]]

  Message from application: undefined method `skip_before_filter' for 
GithubHookController:Class
Did you mean?  skip_before_action (NoMethodError)
  /opt/bitnami/apps/redmine/htdocs/plugins/redmine_github_hook/app/controllers/
github_hook_controller.rb:4:in `<class:GithubHookController>'

[[[ snip (stack trace) ]]]
```

んんん？
エラーメッセージで検索してみると、redmine_github_hook の Github ページに issue がありました。 [^9]

開発者の koppen 氏曰く、

> By the looks of things it seems that Redmine Github Hook isn't compatible with newer versions of Redmine. I don't think it has been tested on anything newer than the 2.x line, and especially the newer, Rails 5 based versions are likely not going to work.
- https://github.com/koppen/redmine_github_hook/issues/87#issuecomment-332433468

嫌な予感がするぞｗｗｗ (サーバスペック参照)
ただ、同じコメントで、次のようにも書いてます。

> The fix should be fairly simple, at least if the above error is the only problem; replacing skip_before_filter with skip_before_action should make things work, albeit in a non-backwards-compatible manner.
- https://github.com/koppen/redmine_github_hook/issues/87#issuecomment-332433468

・・・ソース直しちゃいますｗ

```shell-session
$ cd /opt/bitnami/apps/redmine/htdocs/plugins/redmine_github_hook/
$ vi app/controllers/github_hook_controller.rb
```

エラーの通り、4行目の `skip_before_filter` を `skip_before_action` として保存。
再度、Redmine にアクセスしてみると…

![fig-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4899/394014fd-07e7-b935-dd1a-13ddb6b3f3ec.png)

開いた！(3度目の正直)

また、 `管理` > `プラグイン` の画面でも、プラグインが認識されています。

![fig-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4899/4a5db323-687d-51f4-369a-766dbc52a22c.png)

## 5. Lightsail 側にミラー・リポジトリの作成

プラグインのインストールに手間取ったけど、ようやく本題。
Lightsail 側で Github からミラーするリポジトリを作成していきます。

### 5.1. 鍵ファイルの作成

Lightsail 側で、以下のように Github と接続するための鍵を生成します。

```shell-console
$ cd ~/.ssh/
$ $ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/bitnami/.ssh/id_rsa): id_rsa_github
Enter passphrase (empty for no passphrase): [enter]
Enter same passphrase again: [enter]
Your identification has been saved in id_rsa_github.
Your public key has been saved in id_rsa_github.pub.
The key fingerprint is:

[[[ snip ]]]

The key's randomart image is:

[[[ snip ]]]

$ cat id_rsa_github.pub
ssh-rsa [[[ snip ]]]
```

これで表示される、 `id_rsa_github.pub` の内容(公開鍵)を、Github の側に登録します。
Github にログインして、右上の `Settings` > `SSH and GPG keys` > `New SSH Key` を開いて、

![fig-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4899/760dbba8-49d4-6c78-c7a2-4157e84a1355.png)

`Title` の部分は Redmine 用って分かるようにな名前を適当に入力、`Key` の部分に、先ほどの公開鍵の内容をペーストして、 `Add SSH Key` で保存します。

### 5.2. git リポジトリの作成

再び Lightsail の方に移って、Redmine (Passennger) の実行ユーザーの `daemon` 用に、先ほどの鍵情報をコピー。[^10]

```shell-console
$ cd /usr/sbin
$ sudo mkdir .ssh
$ sudo cp ~/.ssh/id_rsa_github* .ssh/
$ sudo chown daemon .ssh/
$ sudo chown daemon .ssh/id_rsa_github*
```

また、鍵ファイル名をデフォルトから変えているので、 `.ssh/config` も作成。

```shell-console
$ cd /usr/sbin
$ sudo touch .ssh/config
$ sudo chown daemon .ssh/config
$ sudo vi .ssh/config
```

```:/usr/sbin/.ssh/config
Host github
    HostName github.com
    IdentityFile /usr/sbin/.ssh/id_rsa_github
    TCPKeepAlive yes
    IdentitiesOnly yes
    User git
```

続いて、リポジトリの保存先を作成して、Github からクローンします。(保存する場所は、お好みで)

```shell-console
$ cd /var
$ sudo mkdir github_repos
$ sudo chown daemon github_repos/
$ sudo -u daemon /bin/bash
$ cd /var/github_repos
$ git clone --bare github:<ユーザ名>/<リポジトリ名>.git
```

## 6. Redmine のプラグイン設定

Redmine 側にアクセスして、プロジェクトのページから `設定` > `リポジトリ` > `新しいリポジトリ` を選択して、(ローカルの) `リポジトリのパス` を設定します。
(これまでの手順通りなら、 `/var/github_repos/<リポジトリ名>.git` のはず)

![fig-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4899/618b1e37-3076-675d-b23b-d6773700de1e.png)

保存したら、プロジェクトのページから `リポジトリ` を開くと、中身が見られるようになってるかと思います。
(重いリポジトリだと、開くのに時間がかかるかと)

![fig-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4899/330ecc2b-1512-db13-c30b-1efdb9ecdd73.png)

## 7. Github で Webhook 設定

最後に Github 側に push した際に、Redmine 側のリポジトリも更新されるよう、Webhook の設定をします。
Github にアクセスして、対象のリポジトリのページから、 `Settings` > `Webhooks` > `Add webhook` を選択して、

![fig-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4899/7f0c5b36-63ee-5026-126c-8843be218882.png)

`Payload URL` に、`https://<RedmineのURL>/github_hook?project_id=<プロジェクトの識別子>` を入力して `Add webhook` で保存します。

そして、試しに push をしてみて、Redmine 側に反映されたら成功です。

## 8. git コミットと Redmine チケットの連携(これがやりたかった！)

これで、コミットのメッセージに `refs #403` とか `references #404` とか `IssueID #500` と入れると、該当のチケットからもコミット内容が参照できるようになります。[^11] *(※ 2019/07/10修正: チケット番号の前の # を忘れてました)*
(このキーワードは、Redmineの `管理` > `設定` > `リポジトリ` の箇所でへ確認・変更可能です)

ちなみに、コミットにチケット番号を付け忘れたり、間違えて付けたりした場合は、こちら [^12] の方法で修正可能です。

## Postscripts

去年の記事 [^13] とか、今年の記事 [^14] とかもあったので情報が古いって訳でもなく、すんなりインストールできるかなーと思ってたのだけど、意外に手間取った…

[^1]: https://aws.amazon.com/jp/lightsail/
[^2]: [AWS（Bitnami）上のRedmineとGitHubを連携させる - Qiita](https://qiita.com/ao89exb/items/c67a20e5dbc559297104)
[^3]: これが、のちのち問題をry
[^4]: [Bitnami: Packaged Applications for Any Platform - Cloud, Container, Virtual Machine](https://bitnami.com/)
[^5]: https://github.com/koppen/redmine_github_hook
[^6]: [Passenger の再起動コマンドがいつの間にか変わっていた件について - Qiita](https://qiita.com/QUANON/items/a321d2d1ca9c908d59e7)
[^7]: [AWSのlightsailのbitnamiで作成したredmineの再起動方法 - Qiita](https://qiita.com/noracorn92/items/8e6194db4839f1171c1c)
[^8]: [Amazon Lightsailの諸々ファイル置場 | /var/log/danishi.log](https://www.blog.danishi.net/2019/04/13/post-356/)
[^9]: [Error: undefined method `skip_before_filter' for GithubHookController:Class · Issue #87 · koppen/redmine_github_hook](https://github.com/koppen/redmine_github_hook/issues/87)
[^10]: nologin なユーザ用の鍵ファイルって、ここ(/usr/sbin/.ssh)に置けばよかったのね…
[^11]: [バージョン管理システムとの連携 - Redmine.JP](http://redmine.jp/tech_note/subversion/)
[^12]: [Redmine 1.4新機能紹介: チケットとリビジョンの関連づけの追加・削除 - Redmine.JP Blog](http://blog.redmine.jp/articles/new-feature-1_4/manage-issue-relations/)
[^13]: [RedmineとGitHubを連携する | CodeLab](https://codelab.website/redmine-github/)
[^14]: [GitHubとRedmineの連携 －Webhooks編－](https://www.macnica.net/github/blog_20190109.html/)