文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

slack・hubot・jenkinsを連携してslackからjenkinsのジョブを実行する

slackとhubotとjenkinsを連携する方法をまとめてみます。連携に必要なnvm・io.jsのインストールの手順も含め、最初から最後までキッチリ手順をまとめてみます。

f:id:treeapps:20160216013218p:plain

最近のChatOpsのデファクトスタンダードである、Slack+Hubot+Jenkinsの連携方法をまとめます。連携するための手順は結構必要なので、連携するためのソフトのインストール・起動スクリプト等、少し長くなりますが極力全て記述します。

おおまかに概要を説明すると、以下の作業が必要になります。

  • slackのアカウント作成。(これは本記事では割愛します)
  • nvmのインストール。
  • io.jsのインストール。
  • hubotのインストール。
  • hubotのデーモン起動と起動スクリプトの作成、起動。
  • slackのチャットルームからjenkinsのジョブを実行する。


※ node.jsでなくio.jsでも動きます。
※ redisをインストールしなくても動きます。
※ slackのアカウントは既に存在する前提とします。

nvmのインストール

[vagrant@node1 ~]$ git clone git://github.com/creationix/nvm.git ~/.nvm
Cloning into '/home/vagrant/.nvm'...
remote: Counting objects: 3570, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3570 (delta 0), reused 0 (delta 0), pack-reused 3567
Receiving objects: 100% (3570/3570), 745.42 KiB | 392.00 KiB/s, done.
Resolving deltas: 100% (2049/2049), done.
Checking connectivity... done.

[vagrant@node1 ~]$ cd ~/.nvm/

[vagrant@node1 .nvm]$ ./install.sh
=> nvm is already installed in /home/vagrant/.nvm, trying to update using git
=>
=> Appending source string to /home/vagrant/.bashrc
=> Close and reopen your terminal to start using nvm

io.js

io.jsのバージョン一覧

[vagrant@node1 ~]$ nvm ls-remote | grep iojs
    iojs-v1.0.0
    iojs-v1.0.1
    iojs-v1.0.2
・・・略・・・
    iojs-v1.6.3
    iojs-v1.6.4
    iojs-v1.7.1

このように、現在インストール可能なio.jsのバージョンを確認できます。今回は「iojs-v1.7.1」を選択します。

mvmからio.jsをインストールする

[vagrant@node1 ~]$ nvm install iojs-v1.7.1
######################################################################## 100.0%
WARNING: checksums are currently disabled for io.js
Now using io.js v1.7.1

nvmをインストールすると、以下のように「~/.bashrc」に自動的にnvmにパスが通されます。

[vagrant@node1 ~]$ cat .bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

export NVM_DIR="/home/vagrant/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"  # This loads nvm
使用するio.jsを設定する

io.jsを一個しかインストールしていない場合は、以下のように新たにuseしないとio.jsは切り替わりません。

[vagrant@node1 ~]$ nvm use iojs-v1.7.1
Now using io.js v1.7.1
デフォルトのバージョンを設定する
[vagrant@node1 ~]$ nvm alias default iojs-v1.7.1
iojs-v1.7.1
default -> iojs-v1.7.1

デフォルトを設定しておくと、次回ssh接続時に自動的にdefaultに指定したバージョンへのバイナリパスが通ります。複数バージョンインストール時にこれを指定しないと、次回ssh接続時に目的のバージョンへのパスが通りません。
仕組み的には、defaultへのaliasは~/.nvm/alias/defaultのファイルで管理されており、aliasコマンドを実行するとdefaultファイルの中身が書き換わります。

[vagrant@node1 ~]$ cat ~/.nvm/alias/default
iojs-v1.7.1

ssh接続時のログインシェルが~/.bashrcを読み込んだ時に実行される↓が

[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"  # This loads nvm

~/.nvm/alias/defaultを読み込んで、デフォルトとしてパスを通してくれます。

現在インストールされているio.js一覧を見る

v1.7.1がインストールされ、選択中である事が解ります。

[vagrant@node1 ~]$ nvm ls
->  iojs-v1.7.1
node -> stable (-> N/A) (default)
iojs -> iojs-v1.7 (-> iojs-v1.7.1) (default)
インストールされたio.jsのバージョンを確認
[vagrant@node1 ~]$ node --version
v1.7.1

これでio.jsが使用可能な状態になりました。

hubot

yo, generator-hubot, coffee-scriptをインストールする

[vagrant@node1 hubot]$ npm install -g yo generator-hubot coffee-script
/home/vagrant/.nvm/versions/io.js/v1.7.1/bin/yo -> /home/vagrant/.nvm/versions/io.js/v1.7.1/lib/node_modules/yo/lib/cli.js

> yo@1.4.6 postinstall /home/vagrant/.nvm/versions/io.js/v1.7.1/lib/node_modules/yo
> yodoctor


Yeoman Doctor
Running sanity checks on your system

✔ Global configuration file is valid
✔ NODE_PATH matches the npm root
✔ No .bowerrc file in home directory
✔ No .yo-rc.json file in home directory

Everything looks all right!
generator-hubot@0.3.0 /home/vagrant/.nvm/versions/io.js/v1.7.1/lib/node_modules/generator-hubot
├── chalk@0.5.1 (ansi-styles@1.1.0, escape-string-regexp@1.0.3, supports-color@0.2.0, strip-ansi@0.3.0, has-ansi@0.1.0)
├── yosay@0.3.0 (string-length@0.1.2, ansi-regex@0.2.1, ansi-styles@1.1.0, pad-component@0.0.1, word-wrap@0.1.3, minimist@0.2.0, strip-ansi@0.2.2, chalk@0.4.0, taketalk@0.1.1)
├── npm-name@1.0.4 (log-symbols@1.0.2, registry-url@3.0.3, got@2.7.2)
└── yeoman-generator@0.17.7 (dargs@2.1.0, diff@1.3.2, rimraf@2.3.2, class-extend@0.1.1, text-table@0.2.0, mime@1.3.4, underscore.string@2.4.0, async@0.9.0, grouped-queue@0.3.0, isbinaryfile@2.0.3, nopt@3.0.1, cross-spawn@0.2.9, debug@1.0.4, shelljs@0.3.0, run-async@0.1.0, mkdirp@0.5.0, iconv-lite@0.4.8, glob@4.5.3, file-utils@0.2.2, github-username@1.1.1, findup-sync@0.1.3, lodash@2.4.1, request@2.55.0, download@1.0.7, cheerio@0.17.0, gruntfile-editor@0.2.0, inquirer@0.7.3)

yo@1.4.6 /home/vagrant/.nvm/versions/io.js/v1.7.1/lib/node_modules/yo
├── titleize@1.0.0
├── figures@1.3.5
・・・・・略・・・・・
├── lodash@3.7.0
└── inquirer@0.8.2 (ansi-regex@1.1.1, cli-width@1.0.1, through@2.3.7, readline2@0.1.1, rx@2.5.2)

hubot用フォルダを生成する

hubotをフォルダを作成し、sudoしなくていい権限を付与します。
(sudoが必要だと環境変数の受け渡し設定等が面倒になります)

[vagrant@node1 local]$ sudo mkdir -p /usr/local/hubot && sudo chown -R vagrant:vagrant $_
[vagrant@node1 local]$ cd /usr/local/hubot/

yoでhuboを生成する

インストール中に「Bot adapter:」を聞かれるので「slack」と入力して下さい。
(後から別途slackアダプタをインストールする事も可能です)

[vagrant@node1 hubot]$ yo hubot
? ==========================================================================
We're constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
More info: https://github.com/yeoman/insight & http://yeoman.io
========================================================================== Yes
                     _____________________________
                    /                             \
   //\              |      Extracting input for    |
  ////\    _____    |   self-replication process   |
 //////\  /_____\   \                             /
 ======= |[^_/\_]|   /----------------------------
  |   | _|___@@__|__
  +===+/  ///     \_\
   | |_\ /// HUBOT/\\
   |___/\//      /  \\
         \      /   +---+
          \____/    |   |
           | //|    +===+
            \//      |xx|

? Owner: User <user@example.com>
? Bot name: hubot
? Description: A simple helpful robot for your Company
? Bot adapter: (campfire) slack
? Bot adapter: slack
   create bin/hubot
   create bin/hubot.cmd
   create Procfile
   create README.md
   create external-scripts.json
   create hubot-scripts.json
   create .gitignore
   create package.json
   create scripts/example.coffee
   create .editorconfig
                     _____________________________
 _____              /                             \
 \    \             |   Self-replication process   |
 |    |    _____    |          complete...         |
 |__\\|   /_____\   \     Good luck with that.    /
   |//+  |[^_/\_]|   /----------------------------
  |   | _|___@@__|__
  +===+/  ///     \_\
   | |_\ /// HUBOT/\\
   |___/\//      /  \\
         \      /   +---+
          \____/    |   |
           | //|    +===+
            \//      |xx|

npm WARN install Refusing to install hubot as a dependency of itself
npm WARN peerDependencies The peer dependency hubot@2.x included from hubot-maps will no
・・・・・略・・・・・
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.

> ws@0.4.31 install /usr/local/hubot/node_modules/hubot-slack/node_modules/slack-client/node_modules/ws
> (node-gyp rebuild 2> builderror.log) || (exit 0)

make: ディレクトリ `/usr/local/hubot/node_modules/hubot-slack/node_modules/slack-client/node_modules/ws/build' に入ります
  CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
make: ディレクトリ `/usr/local/hubot/node_modules/hubot-slack/node_modules/slack-client/node_modules/ws/build' から出ます
hubot-scripts@2.5.16 node_modules/hubot-scripts
└── redis@0.8.4

hubot@2.12.0 node_modules/hubot
├── optparse@1.0.4
├── cline@0.8.2
・・・・・略・・・・・
└── redis@0.8.4
hubot-slack@3.3.0 node_modules/hubot-slack
└── slack-client@1.4.0 (log@1.4.0, coffee-script@1.9.2, ws@0.4.31)

hubotインストール後のフォルダ構成

[vagrant@node1 hubot]$ ll
-rw-rw-r--.  1 vagrant vagrant   24  417 11:42 Procfile
-rw-rw-r--.  1 vagrant vagrant 7808  417 11:42 README.md
drwxrwxr-x.  2 vagrant vagrant   34  417 11:42 bin
-rw-rw-r--.  1 vagrant vagrant  232  417 11:42 external-scripts.json
-rw-rw-r--.  1 vagrant vagrant    2  417 11:42 hubot-scripts.json
drwxrwxr-x. 17 vagrant vagrant 4096  417 11:43 node_modules
-rw-rw-r--.  1 vagrant vagrant  670  417 11:43 package.json
drwxrwxr-x.  2 vagrant vagrant   27  417 11:42 scripts

hubotをデーモン起動するためforeverをインストールする

普通にhubotを起動する対話型になり、デーモンとして起動してくれません。
hubotをslacのチャットルームに常駐させたいので、デーモン起動は必須です。

[vagrant@node1 hubot]$ npm install forever -g
/home/vagrant/.nvm/versions/io.js/v1.7.1/bin/forever -> /home/vagrant/.nvm/versions/io.js/v1.7.1/lib/node_modules/forever/bin/forever
forever@0.14.1 /home/vagrant/.nvm/versions/io.js/v1.7.1/lib/node_modules/forever
├── colors@0.6.2
├── timespan@2.3.0
├── optimist@0.6.1 (wordwrap@0.0.2, minimist@0.0.10)
├── nssocket@0.5.3 (eventemitter2@0.4.14, lazy@1.0.11)
├── cliff@0.1.10 (eyes@0.1.8, colors@1.0.3)
├── winston@0.8.3 (cycle@1.0.3, stack-trace@0.0.9, isstream@0.1.2, eyes@0.1.8, async@0.2.10, pkginfo@0.3.0)
├── nconf@0.6.9 (ini@1.3.3, async@0.2.9, optimist@0.6.0)
├── utile@0.2.1 (deep-equal@1.0.0, ncp@0.4.2, async@0.2.10, i@0.3.3, mkdirp@0.5.0, rimraf@2.3.2)
├── forever-monitor@1.5.2 (watch@0.13.0, minimatch@1.0.0, broadway@0.3.6, ps-tree@0.0.3)
└── flatiron@0.4.3 (optimist@0.6.0, director@1.2.7, broadway@0.3.6, prompt@0.2.14)

hubotからjenkinsを呼べるようにする

jenkins.coffeeを作成する
vi /usr/local/hubot/scripts/jenkins.coffee

を作成し、以下のスクリプトを貼り付けて下さい。

jenkins.coffeeを設定する

先ほど作成したjenkins.coffeeを以下のように設定してhubotが参照できるようにします。

[vagrant@node1 hubot]$ vi /usr/local/hubot/hubot-scripts.json
[
    "jenkins.coffee"
]

SlackのHUBOT_SLACK_TOKENを確認する

hubotがslacのチャットルームに参加するためには HUBOT_SLACK_TOKEN を設定する事が必須となります。

設定ページを開く

以下を開きます。(初回登録時のログが無いので登録後の手順となります)
https://XXXX.slack.com/services/new

hubotの設定ページを開く

f:id:treeapps:20150418015632p:plain

hubotの設定ページで環境変数を確認する

以下のように、設定するコマンドがズバリ書かれています。
f:id:treeapps:20150418015755p:plain

「export HUBOT_SLACK_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXX」という部分をコピーしておいて下さい。次項で使います。

また、Customize NameはSlack上でhubotを呼ぶ時に使用されます。他のユーザが別のhubotユーザを作成している可能性が高いので、ここのCustomize Nameは短くユニークになる名前をつけましょう。余り長いとチャット上でhubotを呼ぶためのタイプ数が増えてしまいます

このCustomize Nameもコピーしておいて下さい。

※ 対象チャットルームにhubotのintegrationをaddした時点で、Customize Nmaeをユーザ名として、hubotユーザが自動生成されます。ユーザ名「xxx-bot」で検索すると普通のユーザと同じ状態で登録されている事が確認できます。

Slackユーザを目的のチャットルームにjoinさせる

Slackでhubotを招きたいルームに入ります。
そのチャットルームで「/invite xxx-bot」と入力すると、先ほど作成したbotユーザをルームに招く事ができます。
(まだhubotを起動していないのでオフラインかと思います)

hubotの起動スクリプトを作成する

hubotの起動スクリプト

毎回foreverで起動するのは面倒なので、起動スクリプトを書いておきましょう。
先ほどコピーしておいた「HUBOT_SLACK_TOKEN」を以下のように貼り付けて下さい。

[vagrant@node1 hubot]$ vi /usr/local/hubot/hubot-slack.sh
#!/bin/sh
cmd=$1

usage() {
    echo "Usage: `basename $0` <start|stop|restart>"
    exit 1
}
start() {
    forever start -mc coffee node_modules/.bin/hubot --adapter slack --name hubot
}
stop() {
    forever stop -mc coffee node_modules/.bin/hubot --adapter slack --name hubot
}

export HUBOT_SLACK_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXX
cd /usr/local/hubot
case ${cmd} in
start)
    start
    ;;
stop)
    stop
    ;;
restart)
    stop
    start
    ;;
*)
    usage
    ;;
esac

起動スクリプトからhubotをforeverでデーモン起動する

[vagrant@node1 hubot]$ ./hubot-slack.sh start
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: node_modules/.bin/hubot
正しくデーモン起動しているか確認する

foreverの確認コマンドで確認してみましょう。

[vagrant@node1 hubot]$  forever list
info:    Forever processes running
data:        uid  command script                                               forever pid  id logfile                          uptime
data:    [0] 3-3x coffee  node_modules/.bin/hubot --adapter slack --name hubot 9072    9078    /home/vagrant/.forever/3-3x.log 1:6:12:11.785

foreverだけでなく、psコマンドでもhubotがデーモン起動している事が確認できます。
foreverで起動した時点で、Slackのチャットルームに常駐ログイン状態になります。foreverをstopすると、ログアウトします。

Slacからjenkinsのジョブを実行する

「xxx-bot jenkins build ジョブ名」という書式で発言すると、hubotが反応してくれます。
f:id:treeapps:20150418022444p:plain

何故か2件hubotが反応しているような表示になりますが、実際は1ジョブしか実行されないので問題ありません。

雑感

slack上で沢山タイプしたくないので、jenkinsのジョブ名も短くしておいた方がいいですね。

jenkinsはhttpリクエストでも実行できるので、hubot/scripts にカスタムのスクリプトを定義して、

curl -X POST http://xxxx:8090/jenkins/job/job名

を複数書くなりして非同期でまとめてジョブを実行、等も可能になります。


ちなみに私はslack・hubot・jenkinsの連携よりも、io.js・hubotのインストール周りで結構苦戦しました。特に、うっかりsudoでio.jsをインストールしてしまい、sudoでyo等をインストールしようとし、「yodoctor command not found」等とエラーが出たりしました。これは単にsudoした時に環境変数 PATH を引き継いでいないせいで、その辺りをvisudoのenv_keepでPATHを引き継ぐ設定等をする必要がありますが、いっそホームディレクトリにインストールされた 「~/.nvm」「~/.npm」等、node関連のフォルダをsudoが必要ないよう権限を変更するのも楽です(私はそうしました)。


これでいちいちjenkinsの画面を開いてジョブを実行しなくてもよくなります。
更に、暇な時に「xxx-bot ping」と発言すればhubotが話し相手になってくれますよ!

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

開発ツール徹底攻略 (WEB+DB PRESS plus)

開発ツール徹底攻略 (WEB+DB PRESS plus)

  • 作者: Junio C Hamano,大塚弘記,川口耕介,kana,大竹智也(tomoya),尾藤正人,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2013/04/10
  • メディア: 大型本
  • クリック: 1回
  • この商品を含むブログ (11件) を見る
システムテスト自動化 標準ガイド (CodeZine BOOKS)

システムテスト自動化 標準ガイド (CodeZine BOOKS)

  • 作者: Mark Fewster,Dorothy Graham,テスト自動化研究会,伊藤望,玉川紘子,長谷川孝二,きょん,鈴木一裕,太田健一郎,森龍二,近江久美子,永田敦,吉村好廣,板垣真太郎,浦山さつき,井芹洋輝,松木晋祐,長田学,早川隆治
  • 出版社/メーカー: 翔泳社
  • 発売日: 2014/12/16
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログ (4件) を見る