GitHub上にあるファイルに対して、Lambdaで追記してgit pushしてみた

GitHub上にあるファイルに対して、Lambdaで追記してgit pushしてみた

Clock Icon2024.11.22

こんにちは、ゲームソリューション部のsoraです。
今回は、GitHub上にあるファイルに対して、Lambdaで追記してgit pushしてみたことについて書いていきます。

GitHub側の準備

GitHubにて、プライベートリポジトリを作成して、Lambdaで追記する用のファイルを配置します。
今回は以下のような構成にしました。
srcディレクトリにはLambda用のコードが入っていますが、GitHubに配置する必要はありません。

.
├── modifyfile
│   └── test.txt
└── src
    └── lambda_function.py

追記対象のtest.txtは、ファイルの新規作成+上書きではなく追記されていることをわかりやすくするため、適当な文字列を書いておきました。
sr-lambda-github-modify-01

次にPersonal access tokens(PAT)を作成していなければ作成します。
今回はPATを使用しますが、このやり方はセキュリティに良くないため、あくまで検証用途とご理解ください。
本番用途であれば、GitHub Appを使って一時的に権限を与えるなどした方が良いと思います。

Lambdaレイヤーの作成

Lambdaでgitを使用するために、レイヤーを作成します。
以下コマンドをローカルやEC2上などで実行してzipファイルを準備します。
私はAmazon Linux 2023のEC2上で準備しました。

# gitのインストール
sudo dnf install -y git

# Lambdaレイヤー用zipファイルの作成
mkdir -p layer/bin
cp /usr/bin/git layer/bin/
cp /usr/libexec/git-core/git-remote-https layer/bin/
cp /usr/libexec/git-core/git-remote-http layer/bin/
cd layer
zip -r layer.zip .

作成したzipファイルをローカルやS3に配置して、Lambda>レイヤー>レイヤーの作成でLambdaレイヤーを作成します。
※以下キャプチャでは試行錯誤していたため、バージョンが複数ありますが無視してください。
sr-lambda-github-modify-02

Lambdaの作成

最後にLambdaを作成します。
ランタイムはPython 3.13でソースコードは以下です。

lambda_function.py
import os
import subprocess
import urllib.parse

# GitHubリポジトリのURL(HTTPS形式)
REPO_URL = "https://github.com/xxxx/xxxx.git"

def lambda_handler(event, context):
    # Lambdaではtmp以外に書き込みができないため、tmpディレクトリを指定
    repo_dir = "/tmp/repo"

    # リポジトリをクローン
    username = os.environ['GITHUB_USERNAME']
    personal_access_token = os.environ['GITHUB_PAT']

    # ユーザー名をURLエンコード
    encoded_username = urllib.parse.quote(username)

    # URLに認証情報を埋め込む
    repo_url_with_auth = f"https://{encoded_username}:{personal_access_token}@github.com/xxxx/xxxx.git"

    # リポジトリをクローン
    subprocess.run(["git", "clone", repo_url_with_auth, repo_dir], check=True)

    # Gitのユーザー名とメールアドレスを設定
    subprocess.run(["git", "-C", repo_dir, "config", "user.name", "TestName"], check=True)
    subprocess.run(["git", "-C", repo_dir, "config", "user.email", "test@example.com"], check=True)

    # ファイルを取得して追記
    file_path = os.path.join(repo_dir, "modifyfile", "test.txt")
    with open(file_path, "a") as f:
        f.write("\nNew line added by Lambda!")

    # Git操作
    subprocess.run(["git", "-C", repo_dir, "add", "."], check=True)
    subprocess.run(["git", "-C", repo_dir, "commit", "-m", "Update test.txt"], check=True)
    subprocess.run(["git", "-C", repo_dir, "push"], check=True)

    return {
        'statusCode': 200,
        'body': 'File updated and pushed to GitHub'
    }

検証用で簡易的なもののため、ユーザ名やPATを環境変数から取得するようにしていますが、本来はSecrets Managerなどで扱った方が良いです。
(前述の通り、そもそもPATを使わない方が良いと思います。)

URLに認証情報を埋め込む際にそのまま入れるとエラーになったため、エンコードしています。

git commit時にユーザ名とメールアドレスの設定が必要だったため、git configで設定するようにしています。
値自体はなんでもよかったため、TestNametest@example.comとしています。

次に環境変数にGITHUB_USERNAMEGITHUB_PATを設定します。
sr-lambda-github-modify-03

レイヤーに先ほど追加したgitのレイヤーを追加します。
sr-lambda-github-modify-04

テスト

Lambdaのテスト実行をした後、GitHubのリポジトリを確認すると、ファイルに追記されて更新されていることが確認できました。
sr-lambda-github-modify-05

最後に

今回は、GitHub上にあるファイルに対して、Lambdaで追記してgit pushしてみたことを記事にしました。
どなたかの参考になると幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.