PythonのPyGithubでコンテンツをPushする

PyGithubを使って、PythonプログラムからGitHubに対してコンテンツをPushする方法について解説します。

  • 環境情報
  • PyGithubをインストールする
  • PyGithubを使ってコンテンツをPushする
    • create_fileメソッドを利用する
    • create_git_commitメソッドを利用する

環境情報


本記事は、以下の環境を基に解説します。

  • OS・・・MacOS Catalina 10.15.5
  • Python・・・Python 3.9.1
  • PyGithub・・・1.54.1

PyGithubをインストールする


pipコマンドを利用して、PyGithubをインストールします。

$ pip install PyGithub

PyGithubを使ってコンテンツをPushする


PyGithubでGithubにPushする方法として、以下二つがあります。本節では、これらの方法について紹介します。

  • create_fileメソッドを利用する
  • create_git_commitメソッドを利用する

create_fileメソッドを利用する


create_fileメソッドを利用すると、コンテンツをGitHubにPushするところまで実施します。

PyGithubのRepositoryクラスのメソッドで、引数は以下の通りです。branch、comitter、authorは必須ではなく、レポジトリのファイルパス(path)、Commit時のメッセージ(message)、ファイルの内容(content)が必須の引数です。

create_file(path, message, content, branch=NotSet, committer=NotSet, author=NotSet)

プログラムとして利用する場合は、以下のようにGithub.get_repoメソッドを利用してRepositoryクラスを定義する必要があります。

github_source = Github( base_url="https://github.com/api/v3", login_or_token=[GithubのToken] )
repo = github_source.get_repo( [GithubのOrganization/GitHubのRepository] )
repo.create_file( [ファイルパス],  [Commitのメッセージ], [ファイルの内容] )

しかし、create_fileメソッドは一つのファイルをPushします。従って、複数のファイルをPushする場合はファイルごとにPushするので、処理時間が長くなります。複数のファイルをまとめてPushしたい場合は、create_git_commitを利用します。

create_git_commitメソッドを利用する


create_git_commitを利用して、複数のファイルを一括でCommitしてPushする方法について解説します。

PyGithubのRepositoryクラスのメソッドで、引数は以下の通りです。author、comitterは必須ではなく、Commit時のメッセージ(message)、新たにアタッチするGitTree(tree)、GitTreeを追加したいCommit情報(parents)が必須の引数です。

create_git_commit(message, tree, parents, author=NotSet, committer=NotSet)

GitTreeとは、ファイルのコンテンツ(GitTreeElement)のリストです。つまり、既に存在するCommit情報がparents、新たにListに登録するファイルのコンテンツがtreeに該当します。

プログラムとして利用する場合は、以下の流れで記述します。

  1. InputGitTreeElementメソッドで登録したファイルコンテンツをlist(elements)に登録します(6~7行目)。ここでPushしたいファイルを複数まとめて登録できます。
  2. 既存のGitTree(base_tree)を取得し、ファイルコンテンツのlist(elements)をマージしたGitTree(new_tree)を作成します(9~12行目)。
  3. 最新のCommit情報(latest_commit)を取得します(13行目)。
  4. ファイルコンテンツをPushします(14~15行目)。
github_source = Github( base_url="https://github.com/api/v3", login_or_token=[GithubのToken] )
repo = github_source.get_repo( repo_path )
elements = list()

#ここでPushしたいファイルをfor文などを利用して複数登録する。
element = InputGitTreeElement( [ファイルパス], '100644', 'blob', [ファイルの内容] )
elements.append( element )

master_ref = repo.get_git_ref( [対象のブランチ名(masterの場合は、’heads/master’)] )
master_sha = master_ref.object.sha
base_tree = repo.get_git_tree( master_sha )
new_tree = repo.create_git_tree( elements, base_tree )
latest_commit = repo.get_git_commit( master_sha )
new_commit = repo.create_git_commit( [Commitのメッセージ], new_tree, [ latest_commit ] )
master_ref.edit( new_commit.sha )

Referenceを読み解くのは、意外に調査に時間がかかりますよね。。本記事がその時間を短縮してくれることを願います。

以上です。