たくみん成長日記

開発したアプリやプログラミングの備忘録を不定期に上げていきます。

CIのテスト結果は黒澤ダイヤちゃんに言われたい

はじめに

こんちか!!たくみんです。久しぶりに記事を書きますが、今回はSlackBot(厳密にはBotではない)です。そろそろ僕もCircleCIとか使って、開発して自動でテストが走って、また開発してといういい感じの奴がしてみたいと思っていました。そこで、CircleCIについて調べているとテストの結果をSlackに通知してくれる奴(Chat Notifications)があるみたいなので、早速自分のSlackに導入してみました。 f:id:takuminv:20190524210110p:plain:w500

なんやこのおもんない通知は!

というわけで、自作で作ってみました。それが黒澤ダイヤBOTです。 f:id:takuminv:20190524210351p:plain:w500 f:id:takuminv:20190524210405p:plain:w500

各種バージョンと動作環境

このBotSinatraを使用しており、動作環境としてPaasのherokuを使用しました。

jp.heroku.com

Slackに通知する情報

テスト結果の情報として表示するのは以下の5つです。

  1. テスト結果
  2. ブランチ名
  3. コミットしたユーザ
  4. GitHubのコミットページのURL
  5. CircleCIのジョブページのURL

ソースコード

やってることはとても単純で、CircleCIから送られてきたJSONデータから、上記の5つの情報を抜き取り、SlackにPOSTしているだけです。 Sinatraを動作させるapp.rbとSlackに通知する情報を管理するpayload.rb(Payloadクラス)の2つを作成しました。

app.rb

require 'sinatra'
require 'json'
require 'dotenv'
require './payload.rb'

Dotenv.load

get '/' do

end

post '/' do

    params = JSON.parse request.body.read # 受け取ったJSONデータを格納 

   # JSONデータから必要な情報のみを取得
    payload = Payload.new(params['payload']['reponame'],
                          params['payload']['outcome'],
                          params['payload']['branch'],
                          params['payload']['committer_name'],
                          params['payload']['subject'],
                          params['payload']['all_commit_details'][0]['commit_url'],
                          params['payload']['build_url'],
                          params['payload']['build_num'],
                          ENV["WEBHOOKURL"])

    payload.post # SlackにPOST
end

payload.rb

require 'net/http'
require 'uri'

class Payload

    # コンストラクタ
    def initialize(reponame, outcome, branch, commiter_name, commit_message, commit_url, build_url, build_num, webhook_url)
        @reponame = reponame
        @outcome = outcome
        @branch = branch
        @commiter_name = commiter_name
        @commit_message = commit_message
        @commit_url = commit_url
        @build_url = build_url
        @build_num = build_num
        @webhook_uri = URI.parse(webhook_url)
        
        # CI結果によって、通知するコメントと、Payloadの色を変更
        @color = "good"
        @pretext = "テストが成功しましたわ!!"
        if @outcome === "failed"
            @color = "danger" 
            @pretext = "テストを失敗するなんてブッブーですわ!!"
        end
    end

    def post
        @post_data = {
            attachments: [
                {                   
                    title: "#{@title} CircleCI結果",
                    pretext: "<!channel> #{@pretext}",
                    text: @outcome,
                    fields: [
                     {
                         title: "branch",
                         value: @branch,
                         short: "true"
                    },
                     {
                         title: "committer_name",
                         value: @commiter_name,
                         short: "true"
                    },
                    {
                         title: "commit_url",
                         value: "<#{@commit_url} | #{@commit_message} >",
                         short: "true"
                    },
                    {
                         title: "build_url",
                         value: "<#{@build_url} | ##{@build_num} >",
                         short: "true"
                     }
                    ],
                    color: @color
                }
            ]
        }
        self.log # log出力
        Net::HTTP.post_form(@webhook_uri, {payload: @post_data.to_json}) # SlackにPOST
    end

    def log
        puts "reponame: #{@reponame}"
        puts "outcome: #{@outcome}"
        puts "branch: #{@branch}"
        puts "commiter_name: #{@commiter_name}"
        puts "commit_message: #{@commit_message}"
        puts "commit_url: #{@commit_url}"
        puts "build_url: #{@build_url}"
        puts "webhook_uri: #{@webhook_uri}"
        puts @post_data
    end

end

Githubのページ

github.com

おわりに

CircleCIから送られてくるJSONデータの構造を理解するのにとても手間取り、3日くらい作業がストップしてしまいました。最終的にpryで確認すれば良いことに気づいてなんとかBotを作ることができました。この表示が見やすいかどうかは人それぞれですが、僕は満足です。

参考ページ

api.slack.com

blog.excite.co.jp