Redmineのプラグインアップデートチェックを試す

またもRedmineネタですが、ご了承下さい。
Redmineプラグインを公開したいなと思っている方は、末尾をお読みいただけると幸いです。

## 追加機能：プラグインアップデートチェックとは？

先日、Redmine2.5.2がリリースされました。
ここに [*Check for updates" functionality to installed plugins*](http://redmine.org/issues/3177) というチケットがありました。

* Ref. http://redmine.org/issues/3177

Redmineには、プラグインの自動アップデートや、アップデートチェックの機能は無かったので、早速気になってためしてみました。
ソースコードを見ると、ver2.5.2の時点では、プラグイン一覧の画面でjQueryを使ってのアップデートチェックとなっており、Railsのコード側には特に変更は無いようです。

## 実際に試してみる

ちょうどバージョンアップしようと思っていた自作プラグインがあったので、こちらを題材にすることに。

### Redmine2.5.2のプラグイン一覧画面

Redmineをバージョンアップすると、確かに『 **アップデートを確認** 』というリンクが追加されています。
そのままの状態では、プラグインのバージョンには、アイコンなどは表示されていません。

この段階で、『アップデートを確認』をクリック。
こんな処理がクライアント側で走ります。

* AjaxでRedmineのプラグインディレクトリに問い合わせに行く。
 * 宛先: http://www.redmine.org/plugins/check_updates?
* 画面のプラグインの名前とバージョンをパラメータにして問い合わせ。
 * プラグイン名は、init.rb の "Redmine::Plugin.register" で指定している名前

うまくマッチするプラグインが見つかると、こんな結果が返ってきます。 

```source:json
jQuery18303490722014103085_1404765907698(
{"redmine_banner":{"url":"http://www.redmine.org/plugins/redmine_banner","c":"0.1.0"},
"redmine_planning":{"url":"http://www.redmine.org/plugins/redmine_planning"}})
```

### プラグインアップデート前

ローカルでテストしているRedmine2.5.2には、1つ前のバージョンのBanner Pluginが入っています。
この状態で、まずはプラグインのアップデートのチェックをしてみます。

結果はこんな画面。

![plugin-update-check.png](https://qiita-image-store.s3.amazonaws.com/0/27976/da09ed62-88c5-fb1c-8a34-57de043b242b.png "plugin-update-check.png")

上記の通り、Ajaxリクエストの結果を受けて、プラグインの情報をアイコンを付けて表示します。
内訳はこの通り。

* ？マーク：Redmine本家のプラグインディレクトリに登録が無い。
 * もしくは、プラグインディレクトリでのIDとプラグイン名が一致しない。（後述）
* チェックマーク：最新版になっている。バージョンも適合している。
* マーク無し：プラグインディレクトリには登録があるが、どうやらプラグインディレクトリ側のバージョンが更新されていない。（手元のソースのほうがバージョンが上）


### プラグインアップデート後

さて、この状態で、自作のRedmine Banner Pluginのバージョンアップを行いました。
リポジトリ側に加えて、Redmineのプラグインディレクトリ側の情報も更新します。
バージョンは0.0.9から0.1.0をリリース。

ローカルのRedmineは、Redmine Banner Plugin 0.0.9のままなので、ここで『 **アップデートを確認** 』をクリックしてみます。

![plugin-update-check-after.png](https://qiita-image-store.s3.amazonaws.com/0/27976/a3be2017-8fa2-9e3a-34de-3aebe97b24b1.png "plugin-update-check-after.png")

JSONPの結果には、0.1.0と、"c" のフラグが付いて返って来ています。

```source:json
jQuery18303490722014103085_1404765907698(
{"redmine_banner":{"url":"http://www.redmine.org/plugins/redmine_banner","c":"0.1.0"},
"redmine_planning":{"url":"http://www.redmine.org/plugins/redmine_planning"}})
```

ローカルのバージョン番号と結果のバージョン番号を比較して、差があれば！マークを表示するようです。
また、！マークのアイコンのtitle属性には、『互換性のある最新バージョンは0.1.0だよ』というメッセージが付いてきました:)

### 残念ながらAutoUpdateはできません

上記の通り、うまくバージョンチェックが出来た模様です。
ただし、AutoUpdateはできませんので、ここは手動で更新となります。

ローカルのソースを0.1.0に上げて再度プラグインチェックをすると、今度は！マークから緑のチェックマークに代わり、最新バージョンが適用されていることが判りました。

## 注意点 (2014/07/08段階)

バージョンチェックには下記の制限があります。

### クライアント側の動作

* クライアントサイドでの問い合わせになるため、インターネットに出て行けない環境でRedmineをブラウズしているとチェックが聞かない。
* FirefoxではAjax Requestが通らずエラーになってしまう…。（こちらはlocalhostで試しているので、あとでサーバに上げて確認したら追記）

なお、アイコンの意味が判りにくいので、凡例（アイコンの説明）があるといいなあと思った次第です。
本家にリクエスト出してみようと思います。


### プラグイン開発者への注意

うまく動作して、自分のプラグインの更新を検知してもらうための注意点です。

* Redmine本家のプラグインディレクトリには、init.rb の "Redmine::Plugin.register" で指定しているのと同じID (identifier) を登録しないといけない。
 * もし違うIDで登録していても、IDは変更できる。（ただしプラグインディレクトリ側のURLは変わってしまう…)

わたしはBanner Pluginを"banner" というidentifierで登録していたのですが、jQueryでは "redmine_banner" で問い合わせに行ってしまいました。
すでにこのプラグインを利用している方も多いので、プラグインディレクトリ側のidentifierを"redmine_banner"に変更しないといけませんでした。

影響が少ないといいのですが…。

## 追記：20140711 

FirefoxだとどうもうまくAjax Requestが通らない件。
localhost:3000ではなく、リモートのサーバでhttpsで稼働させてみたのですが、やはりFirefoxだけ上手くいきませんでした。

* Chrome / Safari はOK
* Firefox 30.0はNG

わたしの場合は、Ajaxのerrorでタイムアウトになってしまってalertが出ていました。

### 『プラグインアップデートチェック用』のプラグインについて

Redmineの[該当のチケット](http://www.redmine.org/issues/3177)には、まだまく動かない…な報告が出ていなかったのですが、コメントに、『プラグインアップデートチェック用』のプラグインについての情報がありました。

* https://github.com/alexbevi/redmine_plugin_updates

せっかくなので、こちらも組み込んでみることにしました。

仕組みとしては下記の通り。

* Redmineのデフォルトのプラグイン一覧画面を上書き。
* バージョンチェックの基準は、init.rb内のurlで指定されているリポジトリ。
* Rails側（サーバサイド）でurlに指定されているリポジトリをチェックし、リポジトリのinit.rbを参照して、バージョンをチェックする。

![update_check_plugin.png](https://qiita-image-store.s3.amazonaws.com/0/27976/12eb746e-b0b1-72d8-a62b-e28b83d1320a.png "update_check_plugin.png")

この方法だと、redmine.orgに載っていないプラグインもバージョンッチェックが出来るし、JavaScriptのエラーで不具合が出る事もないので、動作としてはなかなかいいかも、と思いました。

ただし、制限が。

* Redmineの稼働しているサーバが、githubや外部のリポジトリとhttp/https通信ができないといけない。（ファイアウォール下とかプロキシを指定しないと外に出られない環境ではNG）
* 今のところ、ターゲットにしているのがGitHubなので、Bibucketがチェック対象になっていない。
* 通信要件でサーバ内での処理が出来ないと、プラグイン一覧の画面がServer Errorで真っ白になってしまう。

とはいえ、プラグインのソースコードを眺めるだけでもいろいろ参考になります。

さてさて本家の方はどうなるでしょうか。