LoginSignup
1
0

More than 1 year has passed since last update.

【git-hooks】pushされたファイルをFTPでレンタルサーバーにアップロードする

Last updated at Posted at 2021-06-30

ある人曰く、

ある製品のホームページがあるんだけどさ、これまでバージョン管理すらしてなかったから、まずいと思ってとりあえずhtmlファイルを全部Gitリポジトリにぶち込んだんだよ。で、リモートリポジトリにpushするのと、FTPでレンタルサーバーにアップロードするので二度手間だから、pushしたら自動でアップロードされるようにしたいんだよね。

……うん。で、詳しく聞くと、要するに

  • 社内のファイルサーバーに、Webサイトのリモートリポジトリを置いた。
  • リモートリポジトリにpushしたら、更新されたファイルを自動でFTPでレンタルサーバーにアップロードしたい。
  • 各編集者は各自の作業ブランチで編集する。編集が終わったら管理者が変更内容をレビューし、OKなら管理者がmasterブランチにマージする。(プルリクエストなんてものは無い)
  • だから、
    • 管理者以外はmasterにpushできないようにして、
    • push先がmasterだったらアップロードすればいいと思う。

……ということだったので、書きました。

レンタルサーバーにSSHでログインできるなら、FTPでアップロードする処理は不要です。公開用ディレクトリにpullしさえすればいいです。たとえば、以下のページをご覧下さい。

また、レンタルサーバーがGitHubなどのホスティングサービスと連携できるならば、そちらの機能を使ったほうが便利で安全だと思います。

本稿の内容によって生じた問題に関して、筆者は責任を負いかねます。

概要

Gitには、フックという、特定の操作が発生したタイミングで、その操作に割り込んでスクリプトを実行する仕組みがあります。フックのスクリプトは、.git/hooks/またはhooksに実行タイミングに応じた名前のファイルで置かれます。

今回使用するフックは、pre-pushpost-receiveです。前者は、クライアント側のフックで、git pushでpushが行われる前に実行されます。後者はサーバー側のフックで、push処理が正常終了した後に実行されます。pre-pushフックで、push先のブランチがmasterであればpushを中止します。post-receiveフックで、push完了後に更新されたファイルをレンタルサーバーにアップロードします。

編集者がmasterへpushするのを禁止する

まず編集者がmasterに直接pushできないようにします。
下記のシェルスクリプトを各編集者ローカルリポジトリの./git/hooks/下にpre-pushという名前で配置してもらいます。

.git/hooks/pre-push
#!/bin/bash

while read local_ref local_sha1 remote_ref remote_sha1
do
  if [[ "${remote_ref##refs/heads/}" = "master" ]]; then
    echo 'You cannot push to the master branch!'
    exit 1
  fi
done

ファイルを作ったら、スクリプトに実行権限を付与します。

$ cd {ローカルリポジトリのルート}
$ chmod +x ./git/hooks/pre-push

push時にFTPでアップロードする

リモートリポジトリはファイルの実態を持たないので、リモートリポジトリがあるファイルサーバーに、デプロイ用のローカルリポジトリを作って一旦そこにpullするようにしました。

つまり、以下のような流れになります。

  1. 管理者が変更をpushする。(push先がmasterブランチでなければ何もしない)
  2. デプロイ用のディレクトリに、その変更がpullされる。
  3. 直前のpushで更新されたファイル名一覧を調べ、
    1. デプロイ用ディレクトリに存在していれば、更新されたとみなしてアップロードする
    2. 存在しなければ、削除されたとみなしてサーバーから削除する

デプロイ用のローカルリポジトリの準備

リモートリポジトリのあるサーバーに、デプロイ用のローカルリポジトリを作ります。

$ git clone {リモートリポジトリのパス} 

git-ftpのセットアップ

レンタルサーバーへのアップロードには、git-ftpを用います。インストール手順に従って、インストールして下さい。

続いて、デプロイ用のリポジトリで、git-ftpの初期設定をします。以下のコマンドで、レンタルサーバーに.git-ftp.logというファイルが作られます。

$ cd {デプロイ用リポジトリのルート}
$ git config git-ftp.url "ftp://{アップロード先のホスト}"
$ git config git-ftp.user "{ユーザー名}"
$ git config git-ftp.password "{パスワード}"
$ git ftp init

post-receiveフックの配置

以下のシェルスクリプトを、リモートリポジトリのhooks/下にpost-receiveという名前で配置します。

hooks/post-receive
#!/bin/bash

# Master branch name
MASTER='master'

# Path of the root directory of the repository to deploy
DEPLOY_DIR_ROOT="${HOME}/deploy" # デプロイ用のディレクトリのパスに変える

while read prev_sha curr_sha ref
do
  branch=${ref##refs/heads/}
  if [[ $branch != $MASTER ]]; then
    exit 0
  fi
done

echo 'run post-receive...'

cd $DEPLOY_DIR_ROOT
git --git-dir=.git pull # --git-dir option must be specified
git --git-dir=.git ftp push

echo 'post-receive done.'

たとえば、上記のシェルスクリプトがローカルのホームディレクトリにあるなら、以下のようにすればコピーできます。

$ scp ~/post-receive {ユーザー名}@{共有サーバーのアドレス}:{リモートリポジトリのパス}/hooks/post-receive
$ rm ~/post-receive

続いて、リモートリポジトリに配置したpost-receiveに実行権限を付与します。

$ ssh {ユーザー名}@{共有サーバーのアドレス}
$ cd {リモートリポジトリのパス}
$ chmod +x ./hooks/post-receive

以上です。
ぶっちゃけ、まずい点たくさんあると思うので、ご指摘下さい。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0