GitlabのWebhookを使う話

はじめに

GitlabでWebhook使ってSlackにでも投稿しようか、という試み
Gitlabに限らずGithubにもあるのでそちらの場合は適宜ドキュメントを読む
ドキュメント読もうにもバージョンが分からん…って時は
https://ドメイン名/help
とか見れば分かる

※そもそもSlackへの通知は公式でサポートされてるのでわざわざ作る必要ないです

追記
Gitlabをオンプレで運用しててローカルネットへのWebhookが動かない!って場合は管理コンソールで内側ネットワークへのアクセスを許可しないと動きません.

バージョン

  • 8.5.1

Webhookとは

コミットとか各種イベントが発生した時に向こうからURLを叩いてくれる
のでURLの用意とそこで動くWebアプリだけ用意しておけば良い感じに受け取って処理出来る

Webhookの登録

どのバージョンのGitlabも
https://ドメイン名/ユーザー名/レポジトリ名/hooks
に登録画面がある
適宜必要なイベントにチェックする
今回はコミットログだけ拾えれば良いのでpushだけセレクト URLは適当に
チャンネル名を指定してもらうついでにただ適当にURL叩かれて動いても困るので適当なクエリをひっつけて一応Gitlabからってことを確認しておく
http://ドメイン名/パス/?channel=チャンネル名&secretkey=hogehoge
みたいな感じにした

アプリの作成

コード

とりあえずFlaskでサクッと作る
Jsonのフォーマットは
https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/web_hooks/web_hooks.md
こことか読みましょう

 1# -*- coding:utf-8 -*-
 2
 3import json
 4import requests
 5from flask import Flask, request, abort
 6app = Flask(__name__)
 7
 8secretkey = "hogehoge"
 9
10@app.route("/", methods=["POST"])
11def index():
12    if secretkey != request.args.get("secretkey", ""):
13        abort(400)
14
15    data = json.loads(request.data)
16
17    temp = u"""レポジトリ「{repo}」に{name}がコミットしました
18{msg}
19{url}"""
20    message = temp.format(
21        repo=data["repository"]["name"],
22        name=data["commits"][-1]["author"]["name"],
23        msg=data["commits"][-1]["message"],
24        url=data["commits"][-1]["url"],
25    )
26
27    target = request.args.get("channel", None)
28    if not(target is None) or not(target=="general"):
29        # Slackに投稿する処理
30        return "ok"
31    else:
32        abort(400)
33
34if __name__ == "__main__":
35        app.run(debug=True, host="0.0.0.0", port=8080)

みたいに作る
Slackに投稿する部分は端折りました

ハマったところ

  • メソッドはPOST
    GETだと思って10分くらいあれー?ってなりました
  • コミットは古い方から取れる
    data["commits"][0]とかすると古いのが取れます
    新→旧じゃなくて旧→新なので-1して後ろを取りましょう