LoginSignup
7
3

More than 3 years have passed since last update.

前回の内容の応用です。
https://qiita.com/aocm/items/0eced705bde216b17919
※Teamsの通知の下準備の方法や、その他のチャットツールにプルリクエストを通知したい人は参考にしてください。

はじめに

とつぜんわいた疑問
CodeCommitって通知とばせないの?

「GithubにしろGitlabはメールとか届いてくれるんだけれどCodeCommitはなんか無いのだろうか。」
「チャットでいちいち伝えるの流れちゃいそう」
「実はいろいろ不便じゃないか?」

そんな声が上がり、不便で終わらせるのももったいない気がするので
なにかできることはないかと考えた結果、「とりあえずプルリクエストをTeamsで飛ばすぞ!」となりました。

もっとうまいやり方に心当たりある方はコメントいただけるととっても嬉しいです。

概要

CodeCommitの特定のイベント(コメント、プルリクエストの作成)をTeamsに通知する。
サンプルプログラムと使い方(仕込み方)をこの記事に書きます。

対象読者

  • 同じような疑問が湧いた人
  • CodeCommitのトリガーをもとになにかやりたい人
  • AWS Lambdaのコードサンプルが見たい人

準備

  1. AWSアカウントの準備(今回は持ち合わせのアカウントのを利用するので、初めて作る方は別の記事を参考にしてください)
  2. サンプルのリポジトリを作成(すでに通知を飛ばしたいリポジトリがあればそれで大丈夫です。作り直す必要はありません。)
  3. 通知したいTeamsのチャネルとWebhookURLの準備(もしくは他の通知したいチャットツールの下準備)

今回はサンプルリポジトリなので、手動で作成します。
image.png

適当なファイルを追加しておきます。
image.png

通知するために仕込む

流れ

  1. ローカルでソースコードを準備
  2. CodeCommitのリポジトリに通知ルールを作成
  3. Lambdaを作成

1. ローカルでソースコードを準備

macでやっていますが、なんでも大丈夫です。何ならnode_modulesごと(.gitignoreで除外せずに)Githubに公開しておくので、こちらのようにZipでダウンロードして2に進んでも大丈夫です。
https://github.com/aocm/lambda-codecommit-notify

image.png

% mkdir lambda-codecommit-notify
% cd lambda-codecommit-notify 
% git init
略
% npm init
略

lambda用のhandlerとTeamsに通知するためのfunctionを並べたindex.jsを作ります。
作ったものがこちら

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の通知を指定したいリポジトリを開き、左メニューの「設定」を選択します
image.png

通知ルールの作成をおします。
image.png

すると以下のような画面になるので、通知をトリガーするイベントに必要なチェックをいれ、
ターゲットの作成からSNSトピックを作成します。
image.png
image.png
Submitしたら以下のような画面になります。

image.png

3. Lambdaを作成

以下のように作成します。
image.png
すると、このような状態になります。
image.png

「トリガーを追加」から、先程つくった通知ルール(SNS)を登録します。
image.png

4. Lambdaに用意したZipファイルをアップロード

image.png

zipファイルをそのままアップロードすると、階層が一つ深くなってしまうので右図のように修正します。

image.png
環境変数の「TEAMS_URL」を設定して「デプロイ」ボタンを押したら完成です。
※TEAMS_URLにはTeamsのWebhookのURLを設定してください。くわしくは前回の記事にて

動作確認

プルリクエストをつくってみます。
image.png
以下のメッセージが届いていました!大丈夫そうです。
image.png

おわりに

突貫工事で作ってみたのですが、何もないよりかはマシだなと思いました。
よければ参考にしてください。

7
3
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
7
3