【Git入門】Gitを使った運用フローを自分用にまとめておく

はじめに

ちょくちょく使うことがあったGitですがいまいち自分の中で整理できていなかったのでGitを使った運用・作業フローを自分用にまとめておく

前提というか背景とやりたいこととか
・基本的に1人で開発(開発サーバーにSSHでログインして開発)
・お客さんが確認するためのステージング環境が必要
・開発(ステージング)サーバーと本番サーバーがある
PHPUnitを使いたい

で、あと以下をGitのフックスクリプトに設定
・PUSH時にPHPUnitを実行。エラーがあればPUSHを中断キャンセルする
・developとmasterブランチへのコミットはなしの想定なので行なわれた場合はPUSHを中断キャンセルする

で、今回考えた構成が以下
f:id:yoppy0066:20160806013351p:plain

開発のながれ

まずは開発作業。ざっくり言うとリモートリポジトリから最新のソースを落としてきてマージして開発用のブランチをきってそこで作業。
完了したらリモートリポジトリへプッシュ

No内容メモ
1masterブランチから開発用ブランチをきるgit fetch --prune; git merge origin/master; git checkout -b feature_0001
2プログラムの修正・テスト実施などなど
3コミットgit commit -m "コメント"
4プッシュgit push origin feature_0001:feature_0001;
4'自動で実施されるPHPUnitでエラーがあればエラーを潰すテストに成功しなければPUSHできない

ステージング環境へリリース

開発が終わったらステージング環境へリリースしてお客さんに確認してもらう。
開発用のブランチは複数あると思うのでリリースするブランチのマージを行う

No内容メモ
1ステージング用ディレクトリへ移動cd /path/to/staging
2開発用ブランチをフェッチgit fetch --prune
3リリースするブランチをマージgit merge --no-ff origin/feature_0001;
4コンフリクト等があれば修正
5プッシュgit push origin develop:develop
5'自動で実施されるPHPUnitでエラーがあればエラーを潰すテストに成功しなければPUSHできない

本番環境へのリリース

ステージング環境でお客さんのokが出たらいよいよ本番サーバーへ反映。
本番サーバーからGitのリポジトリへアクセスしてPULLすることも可能だが、僕は1度リリース用の環境にプログラムを1度落としてそこから本番サーバーへrsync等で反映する方法をとっている

No内容メモ
1本番リリース用ディレクトリへ移動cd /path/to/production
2開発用ブランチをフェッチgit fetch --prune
3リリースするブランチをマージgit merge --no-ff origin/feature_0001;
4コンフリクト等があれば修正
5プッシュgit push origin master:master
5'自動で実施されるPHPUnitでエラーがあればエラーを潰すテストに成功しなければPUSHできない
6プッシュが完了したら本番サーバーへ反映
7リリース済のリポジトリは不要となるので削除するgit push --delete origin/feature_0001

フックスクリプト

これで正しいのかわからないけど、今のところは期待した動きになってる。
重複するけどやりたいことは以下
・PUSH時にPHPUnitを実行してエラーがあればキャンセル
・developとmasterブランチへのコミットは禁止

/opt/git/example.com.git/hooks/pre-receive

#!/bin/sh                                                                                                                                                                                                          

# プロジェクトディレクトリ                                                                                                                                                                                         
basedir="/var/www/html/example.com

while read oldrev newrev refname; do

    # 実行された操作を取得 (commit, deleteなど)                                                                                                                                                                    
    if [ "$newrev" = "0000000000000000000000000000000000000000" ]; then
        newrev_type=delete
    else
        newrev_type=$(git cat-file -t $newrev)
    fi

    # プッシュされた環境を取得                                                                                                                                                                                     
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)

    # [master][develop]ブランチへの[commit][delete]は禁止                                                                                                                                                          
    if [ $branch == "master" ] || [ $branch == "develop" ]; then
        if [ $newrev_type == "commit" ] || [ $newrev_type == "delete" ]; then
               echo "${branch}へのcommitまたはdeleteは行えません"
               exit 1;
        fi
    fi

    # ブランチ削除ではテストは行わない                                                                                                                                                                             
    if [ $newrev_type == "delete" ]; then
        continue;
    fi

    # プッシュされた環境のテスト実行                                                                                                                                                                               
    if [[ $branch == "master" ]]; then
        envdir="app";
    elif [[ $branch == "develop" ]]; then
        envdir="stage-app";
    else
        envdir="dev-app";
    fi

    cd "${basedir}/${envdir}";
    /usr/bin/php oil test --group=App;

    # テスト結果がNGの場合は中断                                                                                                                                                                                   
    if [ $? != 0 ]; then
        exit 1;
    fi
done

おわりに

さらっと書いたけど他の人のやり方検索したり、フックスクリプトが上手く動かなかったりと意外と手間取った。
次回以降すんなり作業できるように他にも残しておいた方がいいことがありそうだけど。。。思いついたら随時追記する

本当はJenkinsも使ってみたいのだが、今のところでどこで使うか模索中。引き続き調査しよう

あと、具体的にPHPUnitでテストに入門したのはこちらに書いてみた
【fuelphp】phpunitでのテスト自動化入門〜使い方メモ - とりあえずphpとか

以上です