- 公開日
- 最終更新日
【CodePipeline】BacklogのGitでCI/CDパイプラインを作成してみた 【前編】
この記事を共有する

目次
はじめに
皆さんこんにちは!パーソル&サーバーワークスの小泉です。
当社では、社内の業務をもっとスムーズにするため、Slackアプリでお役立ちツールをいろいろ作っています。
ソースコードの管理には BacklogのGitリポジトリ を使うことが多いのですが、ふと「BacklogのGitって、CodePipelineと連携できるのかな?」と気になり、調べてみました。
結論から言うと、現時点ではBacklog Gitを直接CodePipelineのソースプロバイダーとして指定することができませんでした!
しかしCodepPipelineはS3をソースプロバイダーとして設定できるとのことだったので、LambdaとS3を組み込むことでパイプラインを作成することができるのか試してみることにしました!
構成図
処理の概要
- 開発サーバからBacklogのGitにpushをする
- BacklogのGitリポジトリでpushイベントを検知し、Webhookを使ってLambdaを実行する
- LambdaでWebhookのイベントを基にGitリポジトリをクローンしてS3にzipファイルをアップロードする(以降の作成手順ではここまでを対象としています!)
- S3にzipファイルがアップロードされたことをトリガーにCodePipelineが動く
- 本番用サーバにデプロイする
- Codepipelineの実行結果をAWS Chatbotを用いてSlackに通知する
作成手順
Backlog
- Backlogでリポジトリを作成します
- プロジェクトの設定からWebhookの追加で通知するイベントを「Gitプッシュ」webhookURLに「Lambda関数のURL」を設定します
Lambda(コンテナイメージからデプロイ※)
app.pyを作成する
import subprocess import os import boto3 import shutil import json def lambda_handler(event, context):
イベント内容をログに出力して、構造を確認する
print(f"Received event: {event}") try: # event['body'] をJSONとしてパース body = json.loads(event['body'])# content -> ref を取得 ref = body['content']['ref'] branch_name = ref.split('/')[-1] # refs/heads/{branch_name} から {branch_name} を取り出す # mainブランチ以外の場合はアップロードをスキップ if branch_name != 'main': print(f"Currently on {branch_name} branch, skipping upload to S3.") return { 'statusCode': 200, 'body': f'Upload skipped because branch is {branch_name}.' } # 認証情報を含んだGitリポジトリのURL git_url = 'https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.git' # 作業ディレクトリとして/tmpに指定 clone_dir = '/tmp/aaa-bbb-ccc' # Gitリポジトリを/tmpにクローン result = subprocess.run(['git', 'clone', git_url, clone_dir], capture_output=True, text=True) # クローンに失敗した場合は処理を中止 if result.returncode != 0: return { 'statusCode': 500, 'body': f"Git clone failed: {result.stderr}" } # リポジトリをZIP形式に圧縮 zip_file = '/tmp/simple-web-app1.zip' shutil.make_archive(zip_file.replace('.zip', ''), 'zip', clone_dir) # S3にアップロード s3_client = boto3.client('s3') bucket_name = 'aaa-bbb-ccc' # S3バケット名 try: s3_client.upload_file(zip_file, bucket_name, 'aaa-bbb-ccc.zip') print(f'Uploaded {zip_file} to s3://{bucket_name}/aaa-bbb-ccc.zip') except Exception as e: print(f'Error uploading {zip_file}: {str(e)}') # 最後にクローンしたディレクトリを削除 if os.path.exists(clone_dir): shutil.rmtree(clone_dir) return { 'statusCode': 200, 'body': 'Git clone, zip, and S3 upload completed.' }
except KeyError as e: # KeyErrorが発生した場合のエラーハンドリング print(f"Error: Missing key {str(e)} in event") return { 'statusCode': 500, 'body': f"Error: Missing key {str(e)} in event" } except json.JSONDecodeError as e: # JSONパースエラーのハンドリング print(f"Error decoding JSON: {str(e)}") return { 'statusCode': 500, 'body': f"Error decoding JSON: {str(e)}" }
※コンテナイメージからデプロイする方法に関しては以下を参考ください 【Lambda】LambdaでGitコマンドを使用する方法
S3
- zipファイルがアップロードされるS3バケットのバージョニングを有効にします
動作確認
開発サーバからgitpushしてS3にzipファイルが作成されているか確認してみます!
git push
$ git push origin main
webhook確認
S3確認
無事にS3にzipファイルがアップロードされていることを確認できました!
最後に
次回の記事では本記事で書ききれなかった手順を含めて公開いたします!
この記事は私が書きました
小泉 和貴
記事一覧全国を旅行することを目標に、仕事を頑張っています。
