ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

【CodePipeline】BacklogのGitでCI/CDパイプラインを作成してみた 【前編】

この記事を共有する

目次

はじめに

皆さんこんにちは!パーソル&サーバーワークスの小泉です。
当社では、社内の業務をもっとスムーズにするため、Slackアプリでお役立ちツールをいろいろ作っています。 ソースコードの管理には BacklogのGitリポジトリ を使うことが多いのですが、ふと「BacklogのGitって、CodePipelineと連携できるのかな?」と気になり、調べてみました。
結論から言うと、現時点ではBacklog Gitを直接CodePipelineのソースプロバイダーとして指定することができませんでした!
しかしCodepPipelineはS3をソースプロバイダーとして設定できるとのことだったので、LambdaとS3を組み込むことでパイプラインを作成することができるのか試してみることにしました!

構成図

構成図

処理の概要

  1. 開発サーバからBacklogのGitにpushをする
  2. BacklogのGitリポジトリでpushイベントを検知し、Webhookを使ってLambdaを実行する
  3. LambdaでWebhookのイベントを基にGitリポジトリをクローンしてS3にzipファイルをアップロードする(以降の作成手順ではここまでを対象としています!)
  4. S3にzipファイルがアップロードされたことをトリガーにCodePipelineが動く
  5. 本番用サーバにデプロイする
  6. Codepipelineの実行結果をAWS Chatbotを用いてSlackに通知する

作成手順

Backlog

  1. Backlogでリポジトリを作成します
  2. プロジェクトの設定からWebhookの追加で通知するイベントを「Gitプッシュ」webhookURLに「Lambda関数のURL」を設定します Backlog

Lambda(コンテナイメージからデプロイ※)

  1. 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

  1. zipファイルがアップロードされるS3バケットのバージョニングを有効にします S3

動作確認

開発サーバからgitpushしてS3にzipファイルが作成されているか確認してみます!

git push

$ git push origin main

webhook確認

Webhook

S3確認

S3バケット

無事にS3にzipファイルがアップロードされていることを確認できました!

最後に

次回の記事では本記事で書ききれなかった手順を含めて公開いたします!

この記事は私が書きました

小泉 和貴

記事一覧

全国を旅行することを目標に、仕事を頑張っています。

小泉 和貴

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。