Slack に SVN(Docker) のコミット通知設定メモ

SVN でコミット通知する方法のメモ。

現在、個人の規模のプロジェクトで SVN を使用している。
(個人的には Git がいいなとは思いつつ、バイナリデータを多く扱うことやプログラマ以外が触ることが多いことなど…諸々の理由がある)

自分の場合、以前に書いたような Docker を使用することで、 比較的簡単な方法で SVN を外部公開している。

この環境下で Slack への通知を行いたい需要が出た。
Slack による通知機能などは今まで作ったことがなかったので、メモとして書き残しておく。

基本方針

Subversionのコミット通知をbashとcurlを使ってSlackのチャンネルに流す - Qiita
# 概要 Subversionのコミット通知をSlackに長そうとしたけど、bashと最小限のコマンドだけで実現したかったので、Subversionのhooks用シェルを作ってみたときの覚え書きです。 本来なら(htt...

基本的は上記の内容で問題なかった。
要するに、SVN のコミットをフックしてスクリプトを走らせ、Slack へ通知するという方法。

なお、post 内容の詳細に関しては、以下の記事が詳しかった。

Slack API attachmentsチートシート - Qiita
# attachmentsとは Slackのメッセージを装飾するもの。 通知系のBotで投稿するメッセージをリッチなものにするのに有効だったりします。 次の画像は、attachmentなしと、attachmentありの比較です。 ...

とりあえずそのままやってみた

自分の Docker 環境では、リポジトリのディレクトリが外部からアクセスできる状態にある。
なので、直接リポジトリ内の hocks/post-commit を編集するだけでよかった。

その結果がこれ。

なにかおかしい。

author とコミットメッセージ、svnlook changed の内容も表示するつもりでいたが、それらが一切表示されていない。

スクリプトの修正

シェルスクリプトをそのまま実行する限りは問題なく表示されたため、自分のDocker 環境が原因であるとわかった。

1. リポジトリパスがおかしい

そもそも、実行自体は Docker のコンテナ側から行われるので、コンテナ内からみた際のリポジトリパスになっていないといけない。

参考 URL 先では、何故か直接スクリプト内にリポジトリパスを直に記述しているが、スクリプトの実行時の第1引数がリポジトリパスなのでそちらに置き換えておく。

2. svnlook のパスもおかしい

よく考えたら、svnlook のパスもコンテナ内でのパスにでないといけない。
特に自分の使用していたコンテナでは、CollaboNet の SVN であり、通常のパスでない可能性が高かった。

そこでコンテナの内容を確認する必要が出てきた。
コンテナの中身にアクセスするには以下のようなコマンドを実行する。

docker exec -it ContainerName bash

ContainerName はアクセスしたいコンテナ名を記述する。

svnlook の所在を確認したところ、やはりパスが違っていたため修正を行った。

3. ロケールが正しく設定されてない

1,2 の修正により、author とコメント内容も表示されるようになった。
が、盛大にコメントが化ける。
スクリプト冒頭で LANG にロケール設定はしているはず・・・にもかかわらず以下の警告が出ている。

svn: warning: cannot set LC_CTYPE locale
svn: warning: environment variable LANG is ja_JP.UTF-8
svn: warning: please check that your locale name is correct

が、これもまたコンテナ内の環境でロケールが使えない状態かも?
ということで、コンテナ内で以下を実行してインストール済みのロケールを確認する。

locale -a

日本語がなかった・・・なので、以下のコマンドで追加しておく。

localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8

結果

上記の修正と、表示内容を整形した結果。

#!/bin/bash

export LANG=ja_JP.UTF-8

REPOS="$1"
REV="$2"
TXN_NAME="$3"

channel="sandbox"
username="svn"
iconemoji=":shell:"
webhookUrl="https://hooks.slack.com/services/HOGEHOGE"

#Docker上での svnlook コマンド fullpath
svnlook_path="/opt/csvn/bin/svnlook"
#Docker 外からの確認用パス
#svnlook_path="/usr/bin/svnlook"

author=$($svnlook_path author -r $REV $REPOS)
commit_msg=$($svnlook_path log -r $REV $REPOS | tr '\n' '\\' | sed 's/\\/\\n/g')
commit_summary=$($svnlook_path changed -r $REV $REPOS | tr '\n' '\\' | sed 's/\\/\\n/g')
header="New commit: rev${REV}\n${commit_msg}"
value="$commit_summary"

# Slackに通知
/usr/bin/curl -X POST --data-urlencode "payload={\"channel\": \"${channel}\", \"username\": \"${username}\", \"text\": \"${header}\", \"attachments\": [{ \"fallback\": \"${header}\", \"color\": \"good\", \"fields\": [{\"title\": \"${author}\", \"value\":\"${value}\"  }]  }], \"icon_emoji\": \"${iconemoji}\"}" ${webhookUrl}