GitHubにプッシュしたときに、Backlogにコメントを書き込む仕組みの作り方(AWS Lambda使用)【後編】

GitHubにプッシュしたときに、Backlogにコメントを書き込む仕組みの作り方(AWS Lambda使用)【後編】

前回:
■GitHubにプッシュしたときに、backlogにコメントを書き込む仕組みの作り方(AWS Lambda使用)【前編】
https://fourmix-blog.myshopify.com/blogs/aws/220118

前回に引き続き、GitHubリポジトリのwebhook機能と、AWS Lambdaを使って、Backlogの関連課題に自動でコメントを書き込む機能を実現してみたいと思います。

<目次>

(0)準備するもの(前編)

(1)AWS LambdaとAmazon API Gatewayの設定をする(前編)

(2)GitHubのwebhook設定(前編)

(3)AWS LambdaでのGitHub認証(前編)

(4)axiosパッケージのアップロード

(5)Backlog APIの呼び出し

(6)AWS使用料について

 (4)axiosパッケージのアップロード

BacklogのAPIにリクエストを送るためにaxiosパッケージを使います。

ローカルフォルダで、「nodejs」フォルダを作成し、VS Codeで開きます。

コンソールから、下記実行

npm i -y
npm i axios

実行後、nodejsフォルダ自体をzip圧縮します。

次、AWS Lambdaコンソールのレイヤーから、「レイヤーの作成」を押して、レイヤーを作成します。

最後に、追加したレイヤーを関数のレイヤーに追加します。

(5)Backlog APIの呼び出し

最後に、BacklogのAPIを呼び出す処理を実装します。

 ■課題コメントの追加
https://developer.nulab.com/ja/docs/backlog/api/2/add-comment/

まず、Backlog側で個人設定からAPIキーを発行します。

 次にAWS Lambdaのコンソールから、環境変数を追加します。

BACKLOG_APIKEY:先ほど発行したAPIキー
BACKLOG_API_ENDPOINT:APIのエンドポイント
BACKLOG_TASKKEY_PREFIX:対象にする課題キーの先頭固定部分

// axiosの読み込み
const axios = require('axios').default;

exports.handler = async (event) => {

    // ヘッダ取得
    const headers = event.headers;

    // ボディ取得
    const body = event.body;

    // ボディをオブジェクト化する
    const bodyObj = JSON.parse(body);

    // バリデーション実行、およびエラー時の処理
    if (! isValid(body, headers)) {

        // エラーの返却
        const response = {
            statusCode: 500,
            body: 'バリデーションエラー',
        };
        return response;
    }

    // ボディオブジェクトからコミット情報の取得
    const commits = getCommits(bodyObj);

    // 対象となるコミットがない場合は終了する。
    if(commits.length === 0){
        const response = {
            statusCode: 500,
            body: `コミットメッセージが、「${process.env.BACKLOG_TASKKEY_PREFIX}」で始まっているコミットはありませんでした`,
        };
        return response;
    }

    // ブランチ名取得(全コミット共通)
    const commit_ref = bodyObj.ref.replace('refs/heads/','');
    
    // ブランチurlの取得(全コミット共通)
    const branch_url = bodyObj.repository.url + '/tree/' + commit_ref;

    // 各コミットごとの処理
    for (const commit of commits){
 
        // タスクキーおよびコメントの取得       
        const {taskkey, comment} = getComment(commit_ref, branch_url, commit);

        // api呼び出し
        await axios.post(`${process.env.BACKLOG_API_ENDPOINT}${taskkey}/comments?apiKey=${process.env.BACKLOG_APIKEY}`, {
          content: comment
        });
    }

    // 正常なレスポンスの返却
    const response = {
        statusCode: 200,
        body: `${commits.length}件のコミットを処理しました。`,
    };
    return response;

    // リクエストがgithubからのものかどうか、バリデーションする
    function isValid (body, headers) {
        const crypto = require('crypto');
        const hmac = crypto.createHmac('sha1', process.env.GITHUB_SECRET);
        hmac.update(body, 'utf8');
        const signature = 'sha1=' + hmac.digest('hex');
        return signature === headers['x-hub-signature'];
    }
    
    // 対象となるコミットを取得して返却する
    function getCommits(bodyObj){
        
        // コミットメッセージが、環境変数BACKLOG_TASKKEY_PREFIXで始まっているコミットを取得する
        let commits = bodyObj.commits.filter(function(i){
            
            // BACKLOG_TASKKEY_PREFIXの文字数取得
            const len = process.env.BACKLOG_TASKKEY_PREFIX.length;
            
            return i.message.slice(0,len) === process.env.BACKLOG_TASKKEY_PREFIX;
        })
        return commits;
    }

    // コメントを組み立てて返却する    
    function getComment(commit_ref, branch_url, commit){
        
        // コミットメッセージから課題キーを取得
        const commit_messages = commit.message.split(' ');
        const taskkey = commit_messages[0];
        
        // commentの組み立て
        let comment = `
            下記の修正がgithubにコミットされました。
            
            【ブランチ】:${commit_ref}
            【ブランチURL】:${branch_url}
            【課題キー】:${taskkey}
            【コミットした人の名前】:${commit.author.name}
            【コミット番号】:${commit.id}
            【コミットurl】:${commit.url}
            【コミットメッセージ】:
            ${commit.message}
        `;
        return {taskkey, comment};
    }
};

これで、GitHubにプッシュしたとき、下記のように「コミットメッセージに記述した課題」にコメントが自動で追加されます。

 (6)AWS使用料について

気になるAWSの使用料ですが、下記の通りです。
※金額はこの記事の執筆当時の価格です。

■Amazon API Gateway
月間リクエスト3億回までの、100万回リクエストの金額・・・1.00USD
※ただし、無料期間中(アカウントを作って1年間)は、100万回リクエストまで無料

■AWS Lambda
リクエスト 100 万件あたり・・・0.20USD
GB-秒あたり・・・0.0000166667USD
※ただし、無料期間中は1 か月あたり 100 万件の無料リクエストと、1 か月あたり 40 万 GB-s のコンピューティングタイムが無料

つまり、無料期間中は無料。無料期間終了後は、約1.20USDぐらいの想定です。(コミット数が極端に多くなければ)

ということで、GitHubのwebhookからの、AWSを使った連携をまとめてみました。応用すれば、プッシュごとにCIチェックを回したり、Slackにメッセージを送ったり、その他もろもろいろいろなことができると思います。
ぜひ、いろいろチャレンジしてくださいませ。

著者名:モリー

React大好きなフロントエンドエンジニア。