Slack×Hubot×GitLabでレビューを効率化しよう

この記事はSlack Advent Calendar 2014 - Qiitaの22日目の記事です。

内容

チーム内でのちょっとした開発にはGitLabを使っているのですが、MargeRequest(以下MR)を投げた時にレビューを効率化するためにの方法を説明したいと思います。

Slack導入以前

別にMRが発生したらメールを投げればいいのですが、メールだとすぐに見ないことも多いのも事実。 そこで、Slackを入れる前はMRが起こるたびにYoを送ってMRが飛んだよーということを気づかせるようにしていました。

ちょうどYoが無駄に流行っている時期でもあったし、Yo APIもあったのでしばらくこれでしのいでいました。

そのとき作ったのがこれです。

Flask-yo

しかし、最初のうちは楽しくてみんな反応していたのですがだんだんと反応しなくなりました。結局Push型でみんなにYoが行くので、誰かレビューするだろ?ってなっちゃうんですよね。

Slackの導入

チーム内のコニュニケーションを円滑にするためにSlackを導入しました。 Slackいいですよね。チーム内のコニュニケーションがかなり活性化されたと思います。 業務中はだいたいのメンバーはSlackに常駐しているのでGitLabのMRもこっちに流そうと思いました。

やりたいこととしては以下となります。

  • MRが飛んだらMRのタイトルと内容とリンクを特定のチャネルに通知
  • 合わせて、@でランダムでレビュワーを割り当てる
    Slackの通知をスマートフォンアプリでも

これによりMRがいつ飛んだのか、誰がレビューするべきかを明確にします。

導入準備

まず今回試しているGitLabのバージョンは「GitLab 7.4.3」となります。

  1. SlackにHubot Integration
    まずはこれが必要です。ちょうどちょっと前にSlack APIのアップデートがあり以前とちょっと方法が変わっています。 すばらしいことにSlack Advent Calendar 2014の4日目にKeitaMoromizatoさんがこの新しいIntegrationの導入方法の記事を書いてくれていますので詳細はこちらを参照して下さい。
    SlackのHubot Integrationが知らぬ間にアップデートされてた
    また、hubot-slackもバージョンアップされておりこれによりプライベートチャネルにもHunotが常駐できるようになりました!素晴らしい!これが出るまではXMPP経由でHubotの設定をしなくてはならず若干面倒くさかったのですよね。。。

  2. Hubotの用意
    様々な記事があるようにHerokuに立てるのが一番楽だと思います。これも参考になる記事がいくつもあるので以下をご参照下さい。他にもググれば参考になる情報がたくさんでてきます。
    slackにHubotを導入(Heroku経由)

  3. GitLabの設定
    スクリプトを作成する前にGitLab側の設定を行いましょう。GitLabにはWebHookの機能がありますのでこれを使用します。
    設定したいプロジェクトの「Setting」→「WebHook」を選択します。

f:id:braitom:20141222133302p:plain

ここを見てもらえると分かるのですが、GitLabでは以下のタイミングでWebHookを使うことができます。
・Push events
・Tag push events
・Issues events
・Merge Request event

今回はMRだけ取りたいので「Merge Request event」にチェックを入れます。そしてURLにはリクエストを送る先のURL(Hubotが動いているURL)を入力して「Add Web Hook」を押します。
もちろんMR以外のイベントもHookして取り回したいという場合はスクリプト側でハンドリングしてあげればOKです。

スクリプトの作成

まずスクリプトの全体は以下となります。これをHubotのscriptsフォルダにおけばOKです。

hubot-gitlab mearge request review

特に難しいことはしていません。ポイントを解説すると、

Slack APIを直接たたいている

hubot-slackを使えば楽ちんなのですがHubotからSlackへ投稿すると@(メンション)と#(チャネル)はデフォルトでリンクとなりません。 こんな感じにただのテキストとして扱われてしまいます。これだとメンション扱いにならないので気付かずにスルーしてしまいそうですよね。

f:id:braitom:20141222134330p:plain

この辺のSlackの仕様は以下のリンク先で確認して下さい。

Slack API Message Formatting

今回は@できちんとメンションとして通知したいという目的がありますのでこの方法でいきました。

4行目のBASE_URLでSlack API Tokenを設定しています。

BASE_URL = 'https://slack.com/api/chat.postMessage?token=xxxx-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxx-xxxxxxx' #replace your Slack API key!

44行目のurlの一番最後に&link_names=1を付与しています。これにより@がきちんとメンションとして機能するようになります。

url = BASE_URL + 'channel=' + channel + '&text=' + encodeURIComponent(message) + '&link_names=1'

レビュアーのランダム化

Hubotのrandom関数を使うようにしています。

random = require('hubot').Response::random

使い方は簡単です。36行目です。

assignee = random members

これでassigneeに6行目のmembersで定義したメンバーがランダムに入ってきます。

GitLabからのHook先

hubotにはrouterの機能があるので指定したURLにPostが来たときの動作を書くことができます。14行目ですね。

robot.router.post '/hubot/gitlab', (req, res) ->

これでhttp://HubotのURL/hubot/gitlabにPostが来た時にこの関数が呼ばれます。 つまりこのURLを上で述べたGitLabのWebHook設定時のURLに指定するわけです。

GitLabからのHook内容をハンドリングする

これは21行目〜24行目で行っています。GitLabが実際にどのようなJsonを送ってくるかは以下を参照して下さい。

GitLab Web hooks

※このJsonの内容はGitLabのバージョンによって変わってきますのでお使いのGitLabのバージョンのドキュメントをきちんと確認して下さい。

Pushでも反応させたい、MRクローズ時も反応させたい等の機能はここを書き換えることになります。

まとめ

この状態でMRが飛ぶと以下のようにメンション付きでbotが教えてくれます。

f:id:braitom:20141222134853p:plain

この方法でMRをレビューすることで前より効率がよくなった気がします。あと、おみくじ的な感じでなかなか面白いです。(また俺が担当かよー!みたいなこともありますが。)

今後もいろいろ改善していきたいですね。よいSlackライフを!

iBeaconで濡れしらず

この記事はおうちハック Advent Calendar 2014 の18日目の記事です。

お題目

外出してから雨が降ってきて、「傘がない!」という経験がある方は多いと思います。 天気予報を見る習慣がある方はいいのですが無い方もそれなりの数いると思います。

こんな悩みを解消しよう!というのが今回の目的です。

ちなみにこのコンセプトのプロダクトは実はもう既に世の中には存在しております。

KickStarter案件だとairfy Beaconというプロジェクトが存在しています。 日本国内だと最近、そら用心というものがリリースされて一部の間でちょっとした話題となっております。

こういったものを自分でも比較的簡単に作れるよ!というのを知ってもらうのも目的であったりもします。

使用する技術要素

今回はAppleのiBeaconを使用します。私の知っている範囲だとiBeaconを決済のものと思い込んでいる方も世の中にはまだそれなりにいるようなので、こういう使い方をするものなのだよということを示したいのでiBeaconでやってみました。

iBeacon自体の詳細は今回は述べません。ググればたくさんヒットすると思いますのでそちらを参照して下さい。

一つだけお勧めするとしたら以下の書籍です。非常に良くまとまっているのでこれを読んどけば大体は分かるかと思います。

使用する機器

  • 以下のいずれかのiOS搭載デバイス
    ※なお今回のサンプルはiOS8以降での動作を確認しております。動作させるためには端末のBluetoothがONになっている必要があります。

  • Beacon
    Beaconを自分で用意する必要があります。昨今けっこういろいろと出てきているので、「iBeacon モジュール」とかで検索してみて自分の好きなモノを選んで下さい。電波強度が調整できるものを選択した方が良いです。以下にいくつか紹介しておきます。

実装

今回はObjective-Cで実装します。気が向いたらSwift版のサンプルも用意したいと思います。

天気情報の取得ですがいくつかのサービスがAPIを提供しています。有名どころで言うとlivedoorのお天気Webサービスでしょうか。 今回は傘を持っていくかどうかを知りたいので降水確率が欲しいです。しかしlivedoorAPIは降水確率が取得できません。他のサービスも調べてみると降水確率が取得できるものが全然ありません。

そんな中見つけたのがこれです。

1分間に10リクエスト、一日で500リクエストまでは無料とのことなのでこれを使うことにしました。

※予報の情報が正しいかは保証できません。ちょっと試している限り問題無いとは思うのですが。。。もっと降水確率の精度を求めるのならば気象庁の予報ページとかをスクレイピングして情報を取得するのも手かもしれません。

ソースコードの全体は以下に上げてありますのでこちらをご覧下さい。

UmbrellaNotifier

動作確認

  1. まずはBeaconを玄関の隅の方に置きます。
  2. アプリを端末にインストールして玄関に近づきます。
  3. 今日は傘を持っていくべきかどうかを通知してくれます。

f:id:braitom:20141218004910p:plain

f:id:braitom:20141218010024p:plain

さいごに

このように比較的簡単に目的のものが作成できました。iBeaconを使うと他にも、「家に帰ってきたらhueのスイッチをONして電気を付ける」とか、「IRKitを使ってTVとエアコンのスイッチをオン」とかも今回の応用でできます。

みなさんも是非いろいろなおうちハックをしてみてはいかがでしょうか?

補足

  • Beaconの設定とか細かいことは購入した製品の説明書をお読み下さい。
  • このサンプルはiBeaconによる降水確率の通知にのみ焦点を当てています。CoreDateのベースだけ作ってあるので通知情報を保存したい場合はそのように実装し直して下さい。(つまり細かい実装をサボりました。。。すいません。必要あれば言って下さい。)
  • サンプルだとBeaconのリージョンに入った時に情報を通知するようにしています。ですので、帰宅時も通知が来てしまいます。これを回避したい場合はリージョンの入出も管理して帰宅時は通知をしないように実装し直して下さい。

pod installでエラーが出るときの対応

pod installしたときに以下のようなエラーが出ることがある。

[!] The `master` repo requires CocoaPods 0.32.1 -

こんな時は、CocoaPodsをバージョンアップしてあげればOKです。

gem install cocoapods

無事アップデートされたら再度、pod installしてあげれば問題なく動くはずです。

Mac OSXのDockerを1.0にあげる

Docker1.0がリリースされましたね。

IT’S HERE: DOCKER 1.0

早速アップデートしたのでメモ。

古いBoot2Dockerをアンインストール

既に1.0より前のDockerを入れている人はbrew経由でDockerを入れているはずです。今回からインストーラーが提供されているようなので古いバージョンのものはアンインストールしておきましょう。

あれDocker入れてたっけな?という人は以下コマンドでBoot2Dockerが入っているかを brew ls コマンド確認しましょう。

入っていたらアンインストールしましょう。

$ brew uninstall boot2docker

Boot2Dockerのインストール

公式サイトからpkgをダウンロードしましょう。

boot2docker/osx-installer

あとはポチポチ押してインストールしていけばOK。

環境変数の設定

Docker1.0からDocker Serverのポート番号が「4243」から「2375」に変わっているようです。

各自の環境に合わせて、.zshrcなり.bash_profileなりを書き換えましょう。

export DOCKER_HOST=tcp://localhost:2375

動作確認

Boot2dockerのDocker VMをアップグレードします。 ターミナルで以下を実行すればOK。古いDocker VMの削除、新しいVMのダウンロード、init、立ち上げまで行っています。

$ boot2docker delete
$ boot2docker download
$ boot2docker init
$ boot2docker up

止めるときは、

$ boot2docker down

念のためdockerのバージョンを確認しておきましょう。

$ docker version
Client version: 1.0.0
Client API version: 1.12
Go version (client): go1.2.1
Git commit (client): 63fe64c
Server version: 1.0.0
Server API version: 1.12
Go version (server): go1.2.1
Git commit (server): 63fe64c

上がっていますね!

あとはDockerを今までどおり使いましょう。

さいごに

ついにDockerも1.0がでましたね。今後のコンテナ型の仮想化が流行っていくことを期待しましょう。

ちなみに、より詳しい手順は公式サイトを見てください。

Installing Docker on Mac OS X

このサイトでは、

$ boot2docker stop
$ boot2docker download
$ boot2docker start

と書いてありますが、boot2dockerのヘルプを見ると、「start」は「up」、「stop」は「down」が正式なのかな?と思いこの記事ではupとdownを使っています。

Brewfileとbrew-caskとを使ってのMacのセットアップ

Macの初期セットアップをするにはBoxen使うよりもBrewfileとHomebrew-cask使うのが良いかと思います。

現時点ではこの方法が一番だと個人的には思っております。

BrewfileとHomebrew-caskについての記事はいろいろな方が書かれているので詳細はそちらを参照して下さい。

Boxenはなぜダメなのか?

Boxenが全然イケてないよという訳ではありません。上で上げた記事でもみなさん述べているのですが、Boxenは大掛かりすぎるのですよね。最初はBoxen使えば個人的にMac買い替えた時に便利だなーとか、みんなの環境揃えられるかなーと思ってちょっと調べていたのですがいろいろ面倒くさい。

あと、なんやかんやでPuppet覚えないといけないのもちょっと。Boxen触り始めて初めてPuppetを触り始めたのですが最初ちょっと辛かった。まあ慣れてしまえばどうってことないのですが。この最初の敷居がチーム内に浸透させにくそうだと感じました。

そして一番の原因が自分の環境がイマイチよく分からなくなること。Boxenの動きをきちんと理解すれば問題ないのでしょうが、rbenvとかもろもろ勝手に入れられてしまうのでなにがどこにあるのか私的には分からなくなりました。

そんなこともあり、結局仮想マシン上のOS Xでいろいろと試行錯誤しましたが結局使うことをやめました。

(ここが結構大事なところで私はチキンなのでいきなりローカル環境で試す気にはなりませんでした。安全策をとってこの方法仮想マシン上で実験しました。結果、これで良かったと心から思っております。)

Brewfile

HomebrewはMacで開発している方ならほとんど使っているはずです。(MacPortsを使っている人もいるかと思いますが。。。)。なのでbrewの延長線上で環境を管理できるので違和感なく導入できるのが最大のメリットだと思います。

そして非常にシンプル。Brewfileを用意してそこにインストールしたいものを記述しておけば、brew bundleコマンド一発でセットアップができます。

しかもこのコマンドをたたいた時に、既にインストールされているものは「既にインストールされています」とスキップしてくれます。これ地味に便利。

Homebrew-cask

brewだけでできることはあくまでもbrewに登録されているパッケージを管理することだけです。そこでbrew-caskが必要になってきます。これを使うとdmgやpkg形式の普通のアプリケーションもインストールできるのです。素晴らしい。

私が普段使っているアプリは全てcaskのリポジトリに登録されていたので全く問題なかったです。もし自分が使っているアプリが登録されていなくても簡単なRubyのコードを書いてあげればOKなので拡張性も高いです。

まあアプリケーションのインストールはBoxenでもできるのですが、何度も言うように Brewの延長上でできる ということが最大の肝だと思います。

補足

インストール方法についてはここでは特に触れません。それぞれのドキュメント読むなり、冒頭であげた方々の記事を読めば詳しくのっております。

一応、各ツールのリンクだけ張っておきます。

まとめ

私のBrewfileはdotfilesの一部としてあげておきました。

こうしておけば以前書いた記事のようにhomesickを使って、いつでもどこでも自分の環境を作りなおすことが可能です。

チーム開発を行う場合はチームでのdotfilesを用意しておけば良いだけです。

すごいべた褒めな感じでBrewfileとHomebrew-caskを紹介しましたが不満点が無いわけではありません。

以下に今のところの私の不満点をあげておきます。もしかしたら何かしら方法があるかもしれないので「それできるよ!」というものがあったら@braitomまで教えていただけると助かります。

  • OS Xの設定ができない

    • BoxenではDockを左側にするとかそういったOS Xに関する設定ができました。brew-caskだとこれができません。
  • App Storeのアプリはインストールできない

    • これは致し方無いきもしますが、AppStoreの履歴からポチポチするのがダルいです。
  • brew-caskでインストールするものの中にはたまにpassword入力が必要なことがある

    • 私の場合、Google日本語入力がpasswordの入力が必要で途中で処理が止まっていました
  • コマンド実行が必要なものをいれられない

    • 私の場合、nodeのバージョン管理にはnodebrewを使っています。 こいつはperlコマンドをたたいてあげる必要があるのですがこれができる方法が無いです。あとoh-my-zshもこの理由により入れることができません。

この辺を解決できる手段があればまさに最強のツールになるのですが、たいした手間でも無いので私的には全然許容範囲です。

Xcodeおすすめプラグイン

今のところ使っていて便利なXcodeプラグインをつらつらと記録しておきます。

今後いいものを見つけたら更新していく予定。

Xcodeプラグインのインストール方法

  • 基本的にはgithub等に上がっているソースコードを落としてきてローカルでビルドすれば勝手に入ってくれます。

  • アンインストールするときは基本、   

~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins

に入っている.xcpluginファイルを消せばOK。

現在使っているプラグイン

最後に

とりあえずまだこれくらいしか使っていません。   

いいプラグインがあればぜひ教えて下さい!! 

Macのdotfilesをhomesickで管理する

扱うMacの台数が増えてきたので、そろそろ本気でdotfiles(.zshrcとか.vimrcとか)を管理してみることにしました。

単にGithubでdotfilesを管理するだけでもいいのですが、調べてみるとhomesickというgemを使うのが今はイケてるっぽい。

1. homesickを入れる 

とりあえずhomesickを入れます。

$ gem install homesick

rbenv使っている場合はrbenv rehashを忘れずに。(私はいつも忘れます。はい。)

2. GitHubにdotfilesリポジトリを作る

Web上から空のリポジトリを作っておいてもいいし、brewhub入れてるならhubコマンドで作ってもいいです。

そしたら、ローカルの適当な場所に、dotfilesという名前でディレクトリを作成します。ここでgit initしておきます。

$ mkdir ~/dotfiles && cd ~/dotfiles

$ git init

さらにdotfilesの下にhomeという名前でディレクトリを作成します。そしたらこの中に、管理したいdotfile達をコピーしていきます。

$ mkdir home && cd home

$ cp ~/.zshrc .

$ cp ~/.vimrc .

$ cp ~/.tmux.conf .

管理したいファイルをすべてコピーしたらgit add .してからコミットしましょう。あとは先ほど作ったリポジトリにpushすればOKです。

(Gitの使い方とかGitHubへのpush方法は割愛します。)

3. homesickを使う

では早速homesickを使っていきましょう。

homesick cloneコマンドでdotfilesをhomesickの管理下に置けます。引数に、[GitHubのユーザ名]/[リポジトリ名]を渡すといい感じにcloneしてくれます。

私の場合は以下の様なコマンドとなります。

$ homesick clone braitom/dotfiles

そうすると以下の場所にcloneされます。

~/.homesick/repos/dotfiles

これで準備は整いました。後は実際に使う場所からsimlinkをはります。

私の場合はhomeで使いたいので以下の様な感じとなります。

$ cd ~

$ homesick symlink dotfiles

そうすると自動で~/.homesick/repos/dotfiles/homeフォルダの下にある全部のファイルにsymlinkが貼られます。

なお、ファイルが既にある場合は上書きするかどうか聞いてきます。以前のファイルを念のためバックアップしておきたい方はバックアップしておくことを忘れずに。

念のためls -laできちんとsymlinkが貼られているか確認しておくことをお勧めします。

これ以降は~/.homesick/repos/dotfiles/をGitで管理していくことになるので、この時点で手順2で最初に作成した dotfilesデレクトリは消してしまってOKです。

なお、homesickでcloneするとremote.origin.urlがhttpsになっているのでsshに変更しておきましょう。特にGitHubに2段階認証を設定している場合は面倒なので変更しておくことをお勧めします。

$ git config remote.origin.url git@github.com:braitom/dotfiles.git

GitHubssh設定が分からない方は以下に手順が書いてありますので参考に。

ちなみにhomesick listでcloneしているリポジトリが分かります。

$ homesick list

   dotfiles  git@github.com:braitom/dotfiles.git

あとは、~/.homesick/repos/dotfiles/homeのdotfile達を変更、追加する場合は通常のGitリポジトリとして管理していけばOKです。

ファイルを変更した場合は、

$ homesick commit dotfiles

#vimが開くのでコミットメッセージを入れて保存

$ homesick push dotfiles

これでコミットされてpushされます。

ファイルを追加した場合は、homesick addみたいなコマンドがないようなので、

$ cd ~/.homesick/repos/dotfiles

$ git add .

して、あとは変更時と同じようにコミットしてpushすればOKです。

3. 違うMacでhomesickを使ってdotfilesを同期する

だいたい分かるかと思いますが一応書いておきます。細かいことは上で書いた手順と同じなので割愛します。

  • homesickのインストール
$ gem install homesick
$ homesick clone braitom/dotfiles
  • symlinkをはる
$ homesick symlink dotfiles

4. 運用方法

これであとはどのMacでもdotfilesの追加、更新をhomesick経由で管理していけばOKです。

違うMacで変更した設定を反映させるには以下のコマンドで。

$ homesick pull dotfiles

5. まとめ

このようにお手軽にdotfilesをGithub上で管理できるようになります。

いやーhomesick便利ですねー。

ちなみに私のdotfilesは以下にありますので興味がある方はご覧く下さい。各ファイルともまだまだまだ貧弱なのでアドバイスとかいただけると嬉しいです。