GithubのWebhookを使って所謂レンタルサーバーでデプロイする(下準備編 サーバー側)
GithubのWebhookを使って所謂レンタルサーバーでデプロイする
下準備編 サーバー側
前提
- SSHでサーバーに入れる
- makeが使える
- 大体のlinuxコマンドが使える
- GitHubにリポジトリを作っておく。ここではgit@github.com:nagoring/sample.gitとします
- サーバーとGitHubとの認証鍵登録は済ませておく
レンタルサーバーでGITを使えるようにする準備
フォルダやファイルの準備
SSHでログインしてホームディレクトリに移動します。
まずはgitを入れるフォルダを作って下準備します。
cd ~
mkdir -p $HOME/opt/tmp
mkdir -p $HOME/opt/bin/git
cd $HOME/opt/tmp
gitのtarballを落として抽出します。
wgetしたときにファイルがない場合はこちらから任意のバージョンを落としてください
https://www.kernel.org/pub/software/scm/git/
wget https://www.kernel.org/pub/software/scm/git/git-2.9.4.tar.gz
tar xvfz git-2.9.4.tar.gz
Git のコンパイル&インストール
ソースをコンパイルします。
gettextが無いとエラーが出るのですがgitには使用されていないため無視します。
makeのオプションはエラーを無視するものです。
cd git-2.9.4
./configure --prefix=$HOME/opt/bin/git
make -i all
make -i all install
gitコマンドを使えるようにパス通し
~/binフォルダにシンボリックリンクを張ります。
cd ~/bin
ln -s $HOME/opt/bin/git/bin/git ./git
おそらく~/binにパスが通っていないためパスを通します。
viで.bashrcを開いてパスを加えます。
vi ~/.bashrc
export PATH=~/bin:$PATH
これで適当なフォルダでgitコマンドを売ってみてください
git --version
git version 2.9.4
これできちんとバージョンが表示されたらOKです。
リポジトリの準備
公開ディレクトリの下にgitのリポジトリを作っておきます。
git initしてリポジトリを登録しておきます。
私はmixhostというレンタルサーバーを使っているので以下のような感じになります。
例
$HOME/public_html/xxx.xxx.mixh.jp/public
publicフォルダが公開ディレクトリのためにその一個下のディレクトリでリポジトリを作ります。
public_htmlというフォルダはデフォルトドメインの公開ディレクトリなので紛らわしいですが気にしないようにしてください。
cd $HOME/public_html/xxx.xxx.mixh.jp/
git init
git remote add origin git@github.com:nagoring/sample.git
GitHubからWebHookデプロイ
GitHubのWebHookからデプロイをする
こちらの参考にしました。
http://isometriks.com/verify-github-webhooks-with-php
GitHubのWebHookの設定を行う
リポジトリの画面のSettingsをクリック。(無い場合は下矢印ボタンを押下すると出てきます)
サイドメニューのWebhooksを選択
右上にあるAdd webhookをクリック
Payload URLを入力する(通知を受け取るプログラムのURL)
Content Typeを application/json
Secretを入力 (通知を受け取るプログラム内で使用します)
Which events would you like to trigger this webhook?で以下をチェックします
– Push
– Pull request
– Release
Add webhookボタンをクリックして作成
通知を受け取るプログラムを用意します
実行内容は以下です。
- 先程入力したSeacretからhashを生成してX-Hub-Signatureと一致するかチェックする
- デプロイするフォルダを設定する
- デプロイするためのGitのコマンドを打つ
X-Hub-Signatureのチェック
date_default_timezone_set('Asia/Tokyo');
$LOG_FILE = dirname(__FILE__).'/hook.log';
$SECRET_KEY = 'Secret Key';
$headers = getallheaders();
$hubSignature = $headers['X-Hub-Signature'];
list($algo, $hash) = explode('=', $hubSignature, 2);
$payload = file_get_contents('php://input');
$payloadHash = hash_hmac($algo, $payload, $SECRET_KEY);
if ($hash !== $payloadHash) {
file_put_contents($LOG_FILE, date("[Y-m-d H:i:s]")." Bad secret", FILE_APPEND|LOCK_EX);
exit('Bad secret');
}
$data = json_decode($payload);
//masterリポジトリだけ反映させたいための処理
if($data->ref !== 'refs/heads/master'){
file_put_contents($LOG_FILE, date("[Y-m-d H:i:s]")." Bad ref", FILE_APPEND|LOCK_EX);
exit("Not master");
}
deployするためのフォルダを設定してgitコマンドを打ってデプロイする
$options = [
'directory' => '/path/to/public_html/xxx.xxxx.mixh.jp',
'log_file_path' => __DIR__ . '/deploy_log_filename.log',
'branch' => 'master',
'date_format' => 'Y-m-d H:i:sP',
'git_bin_path' => '~/bin/git',
];
$deploy = new Deploy($options);
$deploy->execute();
class Deploy {
private $_date_format = 'Y-m-d H:i:sP';
private $_git_bin_path = 'git';
private $_directory;
private $_branch;
public function __construct(array $options = []) {
$this->_git_bin_path = $options['git_bin_path'];
$this->_date_format = $options['date_format'];
$this->_branch = $options['branch'];
$this->_directory = $options['directory'];
}
public function execute() {
$commandPul = $this->_git_bin_path . ' pull';
exec($commandPul);
$commandCheckout = 'cd ' . $this->_directory . ' && ' . $this->_git_bin_path . " checkout -f {$this->_branch}";
exec($commandCheckout);
}
}
これでmasterにマージかpushしたときにデプロイ出来るようになりました。