前回の内容の応用です。
https://qiita.com/aocm/items/0eced705bde216b17919
※Teamsの通知の下準備の方法や、その他のチャットツールにプルリクエストを通知したい人は参考にしてください。
はじめに
とつぜんわいた疑問
CodeCommitって通知とばせないの?
「GithubにしろGitlabはメールとか届いてくれるんだけれどCodeCommitはなんか無いのだろうか。」
「チャットでいちいち伝えるの流れちゃいそう」
「実はいろいろ不便じゃないか?」
そんな声が上がり、不便で終わらせるのももったいない気がするので
なにかできることはないかと考えた結果、「とりあえずプルリクエストをTeamsで飛ばすぞ!」となりました。
もっとうまいやり方に心当たりある方はコメントいただけるととっても嬉しいです。
概要
CodeCommitの特定のイベント(コメント、プルリクエストの作成)をTeamsに通知する。
サンプルプログラムと使い方(仕込み方)をこの記事に書きます。
対象読者
- 同じような疑問が湧いた人
- CodeCommitのトリガーをもとになにかやりたい人
- AWS Lambdaのコードサンプルが見たい人
準備
- AWSアカウントの準備(今回は持ち合わせのアカウントのを利用するので、初めて作る方は別の記事を参考にしてください)
- サンプルのリポジトリを作成(すでに通知を飛ばしたいリポジトリがあればそれで大丈夫です。作り直す必要はありません。)
- 通知したいTeamsのチャネルとWebhookURLの準備(もしくは他の通知したいチャットツールの下準備)
通知するために仕込む
流れ
- ローカルでソースコードを準備
- CodeCommitのリポジトリに通知ルールを作成
- Lambdaを作成
1. ローカルでソースコードを準備
macでやっていますが、なんでも大丈夫です。何ならnode_modulesごと(.gitignoreで除外せずに)Githubに公開しておくので、こちらのようにZipでダウンロードして2に進んでも大丈夫です。
https://github.com/aocm/lambda-codecommit-notify
% mkdir lambda-codecommit-notify
% cd lambda-codecommit-notify
% git init
略
% npm init
略
lambda用のhandlerとTeamsに通知するためのfunctionを並べたindex.jsを作ります。
作ったものがこちら
const axios = require('axios')
const url = process.env.TEAMS_URL
exports.handler = async (event, context) => {
const response = {
statusCode: 200,
body: 'codecommitのイベントをTeamsに通知しました',
}
let message = ""
console.log("event ... ", event)
console.log("Sns ... ", event.Records[0].Sns)
try{
// ★地味にハマりどころ。MessageにはCodeCommitからの情報が入るらしく、ここでJSON.parseする必要がある。
let SnsMessageObj =JSON.parse(event.Records[0].Sns.Message)
switch (SnsMessageObj.detailType) {
case 'CodeCommit Pull Request State Change':
message = pullRequestMessage(SnsMessageObj)
break;
case 'CodeCommit Comment on Pull Request':
message = pullRequestCommentsMessage(SnsMessageObj)
break;
default:
message = `PR#${SnsMessageObj.detail.pullRequestId} 不明な通知です`
}
await teamsPost(message, url)
} catch (e) {
console.log(e)
await teamsPost("CodeCommitNotifyが失敗しました", url)
}
return response
}
/** プルリク時のメッセージ形成 */
function pullRequestMessage(SnsMessageObj){
let repositoryName = SnsMessageObj.detail.repositoryNames
let prId = SnsMessageObj.detail.pullRequestId
let title = SnsMessageObj.detail.title
let pullRequestStatus = SnsMessageObj.detail.pullRequestStatus
let from = SnsMessageObj.detail.sourceReference
let to = SnsMessageObj.detail.destinationReference
let body = SnsMessageObj.detail.notificationBody
let message =
`${repositoryName}:PR#${prId} "${title}" is ${pullRequestStatus} \n` +
`${from} → ${to} \n` +
`${body}`
return message
}
/** コメント時のメッセージ */
function pullRequestCommentsMessage(SnsMessageObj){
let message =''
let repositoryName = SnsMessageObj.detail.repositoryName
let prId = SnsMessageObj.detail.pullRequestId
let file = SnsMessageObj.additionalAttributes.filePath
if (SnsMessageObj.additionalAttributes.commentedLine){
let lineMessage = SnsMessageObj.additionalAttributes.commentedLine
let lineNum = SnsMessageObj.additionalAttributes.commentedLineNumber
message = `${repositoryName}:PR#${prId} ${file}:${lineNum}行目( ${lineMessage} )に対して新しいコメントがあります。`
} else {
message = `${repositoryName}:PR#${prId} ファイル:${file}に対して新しいコメントがあります。`
}
return message
}
/**
* Teamsに通知する
* @param {*} message 投稿するメッセージ
* @param {*} teams_url Incoming WebhookのURL
*/
async function teamsPost (message, teams_url){
try{
const url = teams_url
const text = message
await axios(
{
method: 'post',
url,
headers: {
'Content-Type': 'application/json',
},
data: {
"type": "message",
"text": text
},
}).then(response => {
console.log('res:', response.data)
}).catch(error => {
console.log(error)
})
}catch(e){
console.log(e)
}
}
つくったディレクトリごとZipに固めます。(やり方はなんでも。)
2. CodeCommitのリポジトリに通知ルールを作成
CodeCommitの通知を指定したいリポジトリを開き、左メニューの「設定」を選択します
すると以下のような画面になるので、通知をトリガーするイベントに必要なチェックをいれ、
ターゲットの作成からSNSトピックを作成します。
Submitしたら以下のような画面になります。
3. Lambdaを作成
以下のように作成します。
すると、このような状態になります。
「トリガーを追加」から、先程つくった通知ルール(SNS)を登録します。
4. Lambdaに用意したZipファイルをアップロード
zipファイルをそのままアップロードすると、階層が一つ深くなってしまうので右図のように修正します。
環境変数の「TEAMS_URL」を設定して「デプロイ」ボタンを押したら完成です。
※TEAMS_URLにはTeamsのWebhookのURLを設定してください。くわしくは前回の記事にて
動作確認
プルリクエストをつくってみます。
以下のメッセージが届いていました!大丈夫そうです。
おわりに
突貫工事で作ってみたのですが、何もないよりかはマシだなと思いました。
よければ参考にしてください。