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

How to create a mechanism to write comments to Backlog when pushing to GitHub (using AWS Lambda) [Part 2]

last time:
■ How to create a mechanism to write comments to backlog when pushing to GitHub (using AWS Lambda) [Part 1]
https://fourmix-blog.myshopify.com/blogs/aws/220118

Continuing from the last time, I would like to use the webhook function of the GitHub repository and AWS Lambda to realize the function to automatically write comments to related issues in Backlog.

<Contents>

(0) Things to prepare (Part 1)

(1) Configure AWS Lambda and Amazon API Gateway (Part 1)

(2) GitHub webhook settings (Part 1)

(3) GitHub authentication with AWS Lambda (Part 1)

(4) Upload axios package

(5) Call Backlog API

(6) About AWS usage fee

(4) Upload axios package

We use the axios package to send requests to Backlog's API.

In your local folder, create a "nodejs" folder and open it in VS Code .

From the console run the following

npm i -y npm i axios

After running, zip the nodejs folder itself.

Next, from the layers in the AWS Lambda console, press "Create Layer" to create a layer.

Finally, add the added layer to the function's layer.

(5) Call Backlog API

Finally, implement the process of calling Backlog's API.

■ Adding assignment comments
https://developer.nulab.com/ja/docs/backlog/api/2/add-comment/

First, issue an API key from the personal settings on the Backlog side.

Next, add environment variables from the AWS Lambda console.

BACKLOG_APIKEY: API key issued earlier
BACKLOG_API_ENDPOINT: API endpoint
BACKLOG_TASKKEY_PREFIX: Fixed prefix of target task key

 // axiosの読み込みconst axios = require('axios').default; exports.handler = async (event) => { // ヘッダ取得 const headers = event.headers; // ボディ取得 
const body = event.body;

 // objectify the body
 const bodyObj = JSON.parse(body);

 // Run validation and handle errors
 if (!isValid(body, headers)) {

 // return error
 const response = {
 statusCode: 500,
 body: 'validation error',
 };
 return response;
 }

 // get commit info from body object
 const commits = getCommits(bodyObj);

 // Exit if there are no target commits.
 if(commits.length === 0){
 const response = {
 statusCode: 500,
 body: `There was no commit whose commit message started with "${process.env.BACKLOG_TASKKEY_PREFIX}"`,
 };
 return response;
 }

 // get branch name (common to all commits)
 const commit_ref = bodyObj.ref.replace('refs/heads/','');

 // get branch url (common to all commits) 
const branch_url = bodyObj.repository.url + '/tree/' + commit_ref;

 // processing for each commit
 for (const commit of commits) {

 // get task key and comment
 const {taskkey, comment} = getComment(commit_ref, branch_url, commit);

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

 // return a normal response
 const response = {
 statusCode: 200,
 body: Processed `${commits.length} commits. `,
 };
 return response;

 // validate if the request is from 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'];
 }

 // Get and return the target commit
 function getCommits(bodyObj){

 // Get commits whose commit message starts with the environment variable BACKLOG_TASKKEY_PREFIX
 let commits = bodyObj.commits.filter(function(i){

 // Get number of characters of BACKLOG_TASKKEY_PREFIX
 const len ​​= process.env.BACKLOG_TASKKEY_PREFIX.length;

 return i.message.slice(0,len) === process.env.BACKLOG_TASKKEY_PREFIX;
 })
 return commits;
 }

 // Assemble and return the comment
 function getComment(commit_ref, branch_url, commit){

 // get issue key from commit message
 const commit_messages = commit.message.split(' ');
 const taskkey = commit_messages[0];

 // build comment
 let comment = ` 
The fix below has been committed to github.

 [Branch]: ${commit_ref}
 [Branch URL]: ${branch_url}
 [Task key]: ${taskkey}
 [Name of committer]: ${commit.author.name}
 [Commit number]: ${commit.id}
 [Commit url]: ${commit.url}
 [Commit message]:
 ${commit.message}
 `;
 return {taskkey, comment};
 }
 };

Now, when you push to GitHub, the comment will be automatically added to the "Issue described in the commit message" as shown below.

(6) About AWS usage fee

Regarding the AWS usage fee, which is worrisome, it is as follows.
*The price is the price at the time of writing this article.

■ Amazon API Gateway
Up to 300 million monthly requests, 1,000,000 requests: 1.00 USD
* However, during the free period ( one year after creating an account), up to 1 million requests are free.

■ AWS Lambda
$0.20 per million requests
per GB-sec・・・0.0000166667 USD
*However, during the free period , 1 million free requests per month and 400,000 GB-s of computing time per month are free.

In other words, it is free during the free period. After the free period ends, it is assumed to be about 1.20 USD. (unless the number of commits is extremely high)

So, I summarized the linkage using AWS from GitHub's webhook. If you apply it, I think you can do CI checks on each push, send messages to Slack, and many other things.
Please take on various challenges.

Author name: Molly

Front-end engineer who loves React.

1 of 3