LoginSignup
4
1

More than 5 years have passed since last update.

【GitHub Enterprise】Git Hub Enterpriseのwebhookが有効にならない【AWS CodeBuild】

Last updated at Posted at 2018-11-18

【事象】

AWSのサービスを利用し、デプロイメントパイプラインを作ろうとしていた際、Git Hub Enterprise(以後、GHE)とAWS CodeBuildのwebhook連携ができなくて辛かった。

【解決】

GHEのwebhookの設定で、「Content-Type」を、[application/json]にすることで、webhook連携が有効になった。

ヾ(ΦωΦ)/

01.変えた.jpg

【詳細】

Git Hub/Labを使っていると、ビルド以外にもチケットと連携させたりで、
webhook/service hookを多用することになると思います。
今回、AWSのデプロイメントパイプラインを作成していましたが、
ビルド → デプロイのうち、ビルドの部分で躓きました。

GHEのmasterブランチにソースがpush → pushを検知してwebhook連携 → AWS CodeBuildがビルドをする。
ここのwebhookがそもそもsucessしない!!GHEのコンソールで叱られる!!

GHEがおこな時のメッセージ
Invalid HTTP Response: 400

GHEとAWS CodeBuildによるビルド自動化の流れ

AWS CodeBuildのビルドの流れとしては、下記のような感じになります。

1.ビルド対象のソースコードがGHEのとmasterブランチにpushされる
2.pushを検知し、GHEがwebhookを飛ばしてAWSCodeBuildに知らせる
3.AWS CodeBuildが、ビルド仕様ファイル(build spec.yml)を元にビルドを実行
4.ビルドで生成されたjarなりzipなりをS3バケットに放り込む

AWS CodeBuildは、ビルド仕様ファイル(build spec.yml)の書き方次第で
色々いじれるみたいですね。今度また学んだらQiita書きます。
どうやら、ビルドテストを、自前のコンテナ内で動作させたりとかもできる模様...。

さてさて、AWS CodeBuildのビルドの流れを大きく4つに分けました。僕はこの中で、
2.pushを検知し、GHEがwebhookを飛ばしてAWSCodeBuildに知らせる
で上手くいきませんでした。

webhook連携失敗の詳細

今回はほぼGHEの話になります。
今一度AWS CodeBuild - GHE間のwebhook設定の流れをさらっと見てみましょう。
1.AWS CodeBuildでビルドプロジェクトを作成し、webhookのPOST先となる
「Payload URL」と、AWSへアクセスする「Secretキー」を受け取る。
2.GHEプロジェクトの[Settings]-[Webhooks]から色々設定します。
 設定内容

項目
Payload URL AWSから受けったペイロードURL
Content type Content-Typeヘッダー
Secret シークレットキー
Which events トリガーイベント

3.設定を反映
[Add webhook]で反映すると、GHEのコンソール画面にて疎通確認ができます。
webhooks_recent_deliveries (1).png

Creating Webhooks
https://developer.github.com/webhooks/creating/
Testing Webhooks
https://developer.github.com/webhooks/testing/

設定がおかしいと、ここで真っ赤っかになって叱られます。
僕は、ここでfailed (red x) になってしまいました。
Content typeを application/x-www-form-urlencoded から
application/json へ変更することで無事SUCCESSしました。
payloadといえば、json payloadだと誰もがわかるそうなのですが、
僕は知識足りず、普通に調べるまでわかりませんでした...。
オンプレの古いところだと、jsonのapiダメだったりするしなぁ〜。

さてさて

僕が今回失敗していたのは、Coontent-Typeヘッダーの設定でした。
では何故、 application/json だとうまくいって、
x-www-form-urlencoded では失敗したのか。

そもそも

今回疎通ができていなかったwebhookは、 イベントが発生したのをきっかけにして、
HTTP通信でターゲットにデータを通知する仕組みのことを言います。

何かしらイベントが発生にあたるイベントは、「masterブランチへのpush」でしたね。
そして、「HTTP通信でターゲットにデータを通知」 これが、今回問題となった
Coontent-Typeヘッダー の設定に関係があります。

IMG_1750.JPG
ターゲットとなるのは、PayloadURLで、データはPayloadURLへ JSON形式でPOSTされていました。
(この画力でマスターヨーダを見抜いた人も居ました...。)

webhookが使うHTTP通信のやりとり

masterブランチへのpushというイベントを受け取ったGHEは、
webhookを動かしHTTP通信でデータを送ります。
この際、送られるデータの中身は下記のような感じになっています。

○HTTPリクエストの中身
 ・リクエストライン
 ・HTTPヘッダー
 ・メッセージボディ

それでは一つずつちょろっと見てみましょう〜。
リクエストラインは、「HTTP通信で何をどうしたいか。」を記述します。
 例えばデータを投入(POST)したいのか参照(GET)したいのかとかにあたりますね。
 今回の場合、データは、「PayloadURL(CodeBuildのビルドプロジェクト)へ向けて
JSON形式でPOST(投入) 」されていました。

HTTPヘッダー、今回はここで躓きましたね。
 HTTPヘッダーは、読み込むリソースや、リクエスト送信者の情報のことを言います。
 Cookie持つ持たない、どこのプロキシを通った通ってないとかも書かれています。
 Content-Typeヘッダー というのは、データの形式を指定する記載でした。
 ターゲットのAWS CodeBuildは、 json形式 でデータを欲しがっていました。
 そのため、webhookを定義する際、
 GHEのコンソールで application/json を選択せねばなりませんでした。

どうやらAWSのwebhookでは、デフォルトではJson形式で情報を受け取る模様です。
AWSの公式にも載ってました〜!
CreateWebhook
Request Parameters
https://docs.aws.amazon.com/ja_jp/codebuild/latest/APIReference/API_CreateWebhook.html
The request accepts the following data in JSON format.

メッセージボディ
 実際のデータ内容

今回の場合は、データ形式が間違っていたんだということがわかりました〜。

application/json と x-www-form-urlencoded

今回の事象の原因となるHTTPヘッダーについても触りが理解できましたが、
application/jsonx-www-form-urlencoded
 二つの違い知りたくないですか?

application/json

JSON形式を指定していますね。
JSON形式では、値(バリュー)と、値の名前のキーのペアをコロン「:」で対にして、
それらをコンマ「,」で区切り、全体を波かっこ「{...}」で括って表現する形式です。
こんな感じになりますね。江戸川乱歩めっちゃ好きなので、本の宣伝もしちゃう。

"book1":{ "title": "Phantom twenty face","year": 2005 ,"page": 350}

application/x-www-form-urlencoded

この形式だと、キーバリューはキーとバリューを「=」で結合することで記述されます。
また、キーバリューセットがが複数ある場合は、「&」で区切られるそうです。
そして、dataはURLエンコードされるとありました。
URLエンコードというのは、表記できない文字の文字コードを16進数で表し、
「%」に続けて表記し、その文字を置き換える表記のことを言います。
そのため、パーセントエンコードとも呼ばれています。

 例えば、KINTAN表参道店だとこうかなぁ〜

データ形式の例:(Restaurant=KINTAN&where=Omotesando)
URLエンコードの例:焼肉 → %E7%84%BC%E8%82%89

atwata developer blog
 http://blog.atwata.com/web/2017/04/20/http-request-content-type.html
HTTPリクエストのContent-typeについては、この方のブログが一番綺麗にまとまっていました。

最後におまけ

HTTP通信を生で見ようかなと思って、curlして生で見てみました。
AbemaTVの「田端信太郎VS藤田孝典」面白かったですね〜。
田端さんがお話していた「全員気持ちよく金を使いたくなる社会」がいいと思いました。

そんなわけで、WEARにcurl (GETリクエスト) してHTTP通信を生で見てみました。
オプションが豊富で、いろんなプロトコルにも対応してくれてありがたいです。
HTTPメソッド のGET リクエストが送られていたり、TSL通信が始まったりするところも見れちゃいますね〜。

[root@cbbb33c66501 work]# curl --verbos https://wear.jp/ -o ./wear.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* About to connect() to wear.jp port 443 (#0)
*   Trying 175.111.83.51...
* Connected to wear.jp (175.111.83.51) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*   subject: CN=wear.jp,O="START TODAY CO., LTD.",OU=System,L=CHIBA-SHI,ST=CHIBA,C=JP
*   start date: Apr 26 03:11:04 2018 GMT
*   expire date: Jul 01 23:59:59 2020 GMT
*   common name: wear.jp
*   issuer: CN=GlobalSign Organization Validation CA - SHA256 - G2,O=GlobalSign nv-sa,C=BE
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: wear.jp
> Accept: */*
> 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Length: 141665
< Content-Type: text/html; Charset=UTF-8
< Set-Cookie: PreObjectID=; expires=Sat, 10-Nov-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: AF%5FPreObjectID=; expires=Sat, 10-Nov-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: AF%5FPreScreenID=; expires=Sat, 10-Nov-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: ObjectID=; expires=Sat, 10-Nov-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: PreScreenID=; expires=Sat, 10-Nov-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: ScreenID=; expires=Sat, 10-Nov-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: AF%5FScreenID=12; expires=Sun, 18-Nov-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: AF%5FObjectID=; expires=Sat, 10-Nov-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: LocaleID=MQ%3D%3D%2D%2D46be9f2f8609755b62badaba4488e04c3da0adf1237bddab7d78accebcadc3c8; expires=Tue, 18-Dec-2018 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: ZOZO%5FUID=%3A65177467%3A595854930; expires=Thu, 30-Jul-2020 15:00:00 GMT; domain=.wear.jp; path=/
< Set-Cookie: ASPSESSIONIDQQRDQBRB=JGFICODAMLDKKLJENAKKCJFC; path=/
< Date: Sun, 18 Nov 2018 02:15:31 GMT
< Set-Cookie: BIGipServerIN51_wear.jp_Pool=1649482250.20480.0000; path=/; Httponly
< Set-Cookie: TS01145b15=0182a260475cac19114f0c5a22225c7a08322e320179019429bc3095c2da4cb67d9623533dc2dfd8f7a73be26886dd07b3e755506a; Path=/
< Set-Cookie: TS0148206c=0182a260475cac19114f0c5a22225c7a08322e320179019429bc3095c2da4cb67d9623533dc2dfd8f7a73be26886dd07b3e755506a; path=/; domain=.wear.jp
< 
{ [data not shown]
100  138k  100  138k    0     0   146k      0 --:--:-- --:--:-- --:--:--  146k
* Connection #0 to host wear.jp left intact

<参考>

Webhookって何?を子どもでもわかるように描いてみた | kintone hive online
https://kintone-blog.cybozu.co.jp/developer/000283.html
サイボウズめっちゃ好きだ〜。
くま、可愛いかよ。

Using application/x-www-form-urlencoded format
https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format

Github Webhook Tutorial.md
https://gist.github.com/jagrosh/5b1761213e33fc5b54ec7f6379034a22

Web-hooks
https://developer.github.com/enterprise/2.10/webhooks/
https://developer.github.com/webhooks/

URLエンコード・デコード 日本語URLを扱う場合にどうぞ
https://tech-unlimited.com/urlencode.html

FormData オブジェクトの利用
https://developer.mozilla.org/ja/docs/Web/Guide/Using_FormData_Objects

MIME タイプ
https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1