GitPython / git-ftp.py を使って git commit した時に FTP アップロードも行う方法


経緯

FTPには編集したファイルのみをアップロードすべきだと思っています。

開発しながらアップして、という感じで、量が少なければいいのですが
jpgを50枚近く差し替え(しかもディレクトリがばらばら)みたいな依頼があって
手動でやるのが億劫だったので何か良い方法はないかと思ったところ
git と Pythonでできそうだったのでやってみたメモ。

最近は git push した時に自動でデプロイなんて方法がいくらかあるようですが
事情により ssh 接続できない。。ということがあったので方法の一つとしてやることにしました。

また、 git-ftp を使うともっと簡単にアップできるようだったのですが、
初回に git ftp init をして、リポジトリにある全ファイルをFTPでアップしないといけなかったりと、
ちょっといろんな人に影響がでそうだったので(サーバーはみんなのもの。。)今回の方法を行いました。

ちなみに Python はど素人。

GitPython とは

GitPython は git を Python から扱えるようにした Python のライブラリ

git-ftp.py とは

git-ftp.py は早くそして効率的にgit repository を FTP 経由で公開してくれる優れもの、だそうです。

行なった際の環境

macOS High Sierra ver 10.13.5
Python 2.7.15 *1
git 2.15.2

*1 3系で試してたら動かなかった

なお、本記事では、もろもろの必要なツールは homebrew で install しています。

手順

mac であれば git と Python はデフォルトで入っていていると思います。
それが利用できるようであればその手順はスキップして頂いて良いです。

git を install

git が入っている人はスキップ。

mac なら system の git 入ってると思うので問題ないと思いますが
なんとなく流れ的に homebrew でいれました。

以下コマンドでバージョンを確認

$ git --version

macならおそらく system の git が利用されていてその version が返ってくる。

以下は homebrew での install

$ brew install git

homebrew でいれた git に path を通す

~/.bash_profile に以下の1文を追記。

export PATH="/usr/local/Cellar/git/2.5.0/bin:$PATH"

書き込んだら変更を読み込むために以下を実行

source ~/.bash_profile

以下のコマンドを打ってバージョンを確認しておく

$ git --version

Python をインストールする

Python が入っている人はスキップ。

以下コマンドでバージョンを確認

$ python --version

mac だとデフォルトで入っているようですが、( おそらく system のバージョンが返ってくる )
今後書くかもわからないのでバージョン管理ツール( pyenv )でインストールすることにしました。

まず Python のバージョン管理ツール pyenv を install

homebrew で install します。

$ brew install pyenv

homebrew でいれた pyenv にパスを通す

.bash_profile を編集してパスを通す

export PATH="$PYENV_ROOT/bin:$PATH"
export PYENV_ROOT="$HOME/.pyenv"
eval "$(pyenv init -)"

書き込んだら変更を読み込むために以下を実行

$ source ~/.bash_profile

pyenv を使って Python を install

インストールできるバージョンを確認してみましょう。

$ pyenv install --list

で install 可能なバージョンが確認できます。

私は 3.7.0 にしたので以下のように version を指定して install します

$ pyenv install 3.7.0

3.7.0 だと動かなかったので 2系の最新を入れることにした。

$ pyenv install 2.7.15

install したら 利用するバージョンを指定します

pyenv で入れている切り替え可能なバージョンを確認します

$ pyenv versions

以下のように返ってきました。

* system (set by /Users/ユーザー/.pyenv/version)
  2.7.15
  3.7.0

global で利用したければ $ pyenv global 2.7.15
local の利用にしたければ $ pyenv local 2.7.15
を打ちましょう。

$ pyenv global 2.7.15

以下のコマンドで指定したバージョンに切り替わっているか確認しましょう

$ python --version

GitPython を install

Python もはいったところでようやく GitPython を入れます。

$ pip install gitpython

※ pip は Python のパッケージ管理ツールとのこと

git-ftp.py を local にダウンロードしてくる

今回の記事のキモです。

github にソースが公開されているので local のお好みの場所に clone してくる

$ cd お好みの場所
$ git clone https://github.com/ezyang/git-ftp.git

そしてこれが実行できるようにパーミッションも変えておきましょう

$ chmod +x お好みの場所/git-ftp/git-ftp.py

レポジトリに設定ファイル ( ftpdata ) を置く

git 管理しているリポジトリフォルダの中.git/ftpdata でファイルを作成。
中には以下の内容を記述。

なお、 [master] や [staging] は branch 名と関係していて、
そのブランチで push されたら それぞれの設定したサーバーへ FTPをしてくれる仕組み
ssl の yes は Python 2.7 以降で使える模様(試してはない)

[master]
username=FTPのユーザー名
password=FTPのパスワード
hostname=FTPのホスト
remotepath=/htdocs/などなど
ssl=yes

[staging]
username=FTPのユーザー名
password=FTPのパスワード
hostname=FTPのホスト
remotepath=/htdocs/staging/などなど
ssl=no

それぞれ設定することで違うサーバーへFTPされるようにできますね。

post-commit をつくって git-ftp.pyを実行できるようにする

リポジトリのフォルダ/.git/hooks/post-commit
のファイルを作って以下を記述。
pathは clone してきたところへ

#!/bin/sh

お好みの場所/git-ftp/git-ftp.py

そしてこれが実行できるようにパーミッションも変えておきましょう

$ chmod +x リポジトリのフォルダ/.git/hooks/post-commit

tips

通常、開発は feature/no1 など feature ブランチを切って開発することになると想定されます。
その場合は stagingmerge されたタイミングでFTPされるのも必要になるとおもうので
post-commit と同様の内容で リポジトリのフォルダ/.git/hooks/post-merge もおいて置くと良さそう。

サーバーに git-rev.txt のファイルを配置する

これがリモートサーバーにないと push するたび毎回全ファイルアップしてしまう みたいです。

中身は最新コミットのハッシュを一文書いてください。
その記述された最新コミットのハッシュと次の push 時にコミットとの
差分のあるファイルのみをアップロードしてくれます。

git-rev.txt の配置場所ですが
レポジトリに設定ファイル .git/ftpdata の中
remotepath で書いたディレクトリに それぞれ ( [master] / [staging] )
にこのファイルをアップしましょう。

※ [master] / [staging] でハッシュが異なる場合はそれぞれのハッシュを書きましょう。

push してみましょう

リポジトリ内でファイル編集、コミットしてpushしてみます。
ここからは git のコマンドです。

ファイルを編集してコミットします。

チェックアウトします。

$ git checkout -b staging

ファイルを編集してコミットします

$ git commit -a -m 'コミットメッセージ'

すると、このコミットする時に git-ftp.py が呼び出されてFTPを行ってくれています!

INFO: Using .git/ftpdata
INFO: Base directory is /htdocs/staging/などなど
INFO: Uploading 更新したファイル1
INFO: Uploading 更新したファイル2

更新されているか staging 環境をブラウザで確認してみましょう。

参考にさせていただいたページ

Using GIT FTP and GIT Python
CentOS6.4にGitlab入れて、さらにpushされたらftpでデプロイ出来るようにした話 - Pastalablog in はてな
Karappo web design room » git-ftp.pyを使ってGitで管理しているFTP経由でローカルとリモートのファイルを同期
git で push したファイルを FTP 経由で差分アップロードするよ - ヤルキデナイズドだった
GitPythonを使う - Qiita
gitpython つかってみた - 俺は面倒が嫌いなんだ