Github Flow

チームソフトウェア開発のためのワークフロー

チームでソフトウェアを開発するとき,チームメンバーがバージョン管理システムをどのように利用するかは非常に重要な課題である.各メンバーが好きなようにコミットを行い,勝手に開発をすすめるようなことになれば,完成したソフトウェアがどこにあるのか分からなくなったり,開発中のソースコードが完成版のソフトウェアに紛れ込んだりといった様々な問題が発生してしまうことになる.

そのため下記のように,版管理システムの利用ルールを決めたチームソフトウェア開発のためのワークフローが数多く提案されている.

  • Gitの開発者らによって提案されているGit-flow
  • Gitlab1と呼ばれるgitリポジトリのホスティングツール・サービスの開発者らによって提案されているGitlab flow
  • 本演習で対象とする同じくgitリポジトリのホスティングサービスGithub2の開発者らによって提案されているGithub Flow

これらのワークフローでは,チームでのソフトウェア開発の様々な局面において,各メンバーがどのように版管理システムを利用・操作するべきであるかが示されている.本演習では既存のワークフローの中で最もシンプルなものの一つとされているGithub Flowについて紹介し,演習を行う.本節ではGithub Flowの6つのルールと関連するGitリポジトリの操作について説明する.

Github Flowにおける6つのルール

Github FlowとはGithubの開発者によって提案された以下に示す6つのルールから構成されている非常にシンプルなワークフローである.以降に示すルール及びその詳細はGab-km氏によるGithub Flow(japanese translation)にもとづくものである.

  1. masterブランチにあるものは何でもデプロイ可能である
  2. 新しい何か(機能追加やバグ修正などなんでも)に取り組む際は,説明的で分かりやすい名前のブランチをmasterから作成する
  3. 作成したブランチにローカル(開発者のマシン)でcommitし,サーバー上にも定期的に作業内容(commitしたもの)をpushする
  4. フィードバックや助言が欲しいとき,あるいは作成したブランチでの作業内容をmasterブランチにmergeしても良いと思ったときは,Pull Requestを作成する
  5. Pull Request自分以外の誰かがレビュー(作業内容の確認)をしてOKを出してくれたときのみmasterブランチにmergeしてよい
  6. mergeをしてmasterへpushしたら,直ちにデプロイをする

以降では各ルールについて詳述する.

ルール1:masterブランチにあるものは何でもデプロイ可能である

デプロイとはソースコードをアプリケーションとして正常に実行された状態に処理し,配備することを示す.例えばWebアプリケーションの場合,ソースコードをコンパイルし,Webアプリケーションリソースとしてまとめ,アプリケーションサーバのしかるべきところに置き,アプリケーションサーバを必要に応じて再起動する.これによってWebアプリケーションとして利用できる状態になる.このような一連の操作のことをソフトウェアのデプロイ(配備)と呼び,デプロイ可能とはソースコードをデプロイによって正常にアプリケーションとして利用可能な状態にすることができることを表す.

Gitではリポジトリ作成時にmasterと呼ばれるブランチが作成される. ルール1はこのmasterブランチにあるソースコードが常にデプロイできる状態であることをチームに対して求めている.

上図に示すようなリポジトリがあるとする.ここではある開発者がローカルリポジトリを作成し,何らかの開発作業を行い,ローカルリポジトリにCommitを行った後,そのリポジトリをGithub(リモートリポジトリ)にPushしている.同じように複数の開発者がmasterブランチにCommitし,Pushした結果,初期Commit(リモートリポジトリmasterブランチの一番左の灰色の丸)から右に3回のCommitが行われている.

ここで2つ目,3つ目,4つ目のCommit終了時にリポジトリ内のソースコードをCompileし,Runしてみると,2つ目と4つ目はソフトウェアが正常に動作したが,3つ目ではエラーが発生し,正常に動作しなかった.

ルール1では,このようなmasterブランチに対して行われたCommitの結果,ソフトウェアが正常に動作しない状態になることを禁止している.すなわち,masterブランチにあるソースコードは常に正常に動作することを保証することで,開発途中のソースコードや正常に動作しないままのソースコードがmasterブランチに混じらないようにするべきであると示している.

本演習ではProcessingを用いて開発を行うため,ソースコードが正常にコンパイル可能であり,実行時エラーが発生するようなことがなければ正常に実行が可能である.そのため,本演習におけるルール1はmasterブランチにあるソースコードは常に正常にコンパイル可能であり(コンパイルエラーが発生しない),実行可能であり(実行時エラーが発生しない),チームの意図した機能が意図した仕様で動作することを維持し続けることを目指すものとする.

実際にこのルール1を守るためには,masterブランチに対して開発者がいきなりCommitを行うようなワークフローでは難しい.そのため,開発者によるCommit内容を他の開発者が確認し,問題なければmasterブランチに取り入れるといったフローが必要となる.


ルール2:新しい何か(機能追加やバグ修正などなんでも)に取り組む際は,説明的で分かりやすい名前のブランチをmasterから作成する

デプロイ可能なmasterブランチのソースコードに対して機能追加やバグ修正,あるいは可読性を改善するためのソースコードの修正(コメントをつける等)等を行う際,ルール1で示したようにmasterブランチに対して直接手を入れるようなことをしてはいけない.

上図が示すようにGitではリポジトリ作成時に生成されるmasterブランチ以外にもブランチを自由に作成できる.ブランチによって元のソースコードに影響を受けない開発履歴を保存することが可能となる.この例の場合,add_cpu_logicブランチでのCommitはmasterブランチに影響を及ぼさない.そのため,Gitを利用した開発では通常,バグ修正や機能追加といった新しい開発作業を始めるたびにブランチを作成する.

自由に作成できるブランチだが,Github Flowではその作成において,一定のルールを定めている.それは,必ずmasterブランチから新しい説明的で分かりやすい名前のブランチを作成することである.例えばuser-content-cache-keymenu-behavior-act-i等のような追加する機能や編集する機能の名前,モジュール名などが分かりやすくつけられていることが望ましい.

上図の例の場合,masterブランチから作成したadd_cpu_logicブランチは問題ないが,add_cpu_logicブランチから分岐して作成したtempブランチはmasterブランチから作成されたものではない.ブランチは自由に作成できるが,そのようにして作成されたブランチは最終的にmasterブランチに取り込む(mergeと呼ばれる)必要がある.そのとき,masterブランチ以外から作成されたブランチが存在すると,そのmerge作業が非常に困難になる.

また,この例の場合,tempブランチという名前も望ましくない.Github Flowにおいてブランチを新たに作成する場合は,そのブランチが何を目指したものなのかが第3者にも分かりやすいような命名を心がけるべきである.


ルール3:作成したブランチにローカル(開発者のマシン)でcommitし,サーバー上にも定期的に作業内容(commitしたもの)をpushする

ルール2で作成するブランチはそのままではローカル(すなわち開発者のマシン)のリポジトリ内にしか存在しないため,チームの他の開発者には誰がどのようなブランチを作成したかは分からない.そのため,Github Flowでは,ブランチ作成時あるいは開発作業中(すなわちブランチに対するcommitが行われている際に)に開発者が作成したブランチをサーバーへpushすることを指示している.ここでcommitとは既存のソースコードに対して行った編集内容をリポジトリに登録することを指し,pushとはローカルリポジトリの内容をサーバ側リポジトリにアップロードし,同期させることを示す.

開発作業中のものも含めて,すべてのローカルリポジトリで作成されたブランチをpushすることにより,現在誰が何をしているのかをサーバ側のリポジトリにあるブランチリストを見るだけで把握することが可能となる.

例:Githubで開発されているDeveloperツールのブランチリスト

上図の例では,開発者A,Bがそれぞれ異なる機能を実装している.ブランチ作成時及びCommit後にPushを行うことで,ローカルリポジトリで作成したブランチがリモートリポジトリに登録される.結果として,赤枠で囲まれたようにどのブランチが現在開発されているかをチームの全開発者が容易に理解できるようになる.


ルール4:フィードバックや助言が欲しいとき,あるいは作成したブランチでの作業内容をmasterブランチにmergeしても良いと思ったときは,Pull Requestを作成する

ルール1において,masterブランチに直接Commitすることは望ましくないと述べた.そのためGithub Flowでは,ルール2及び3でmasterブランチから作成したブランチの内容をmasterに取り込むために,Pull RequestとMergeと呼ばれる機能を利用する.

Pull Requestは以下のような機能であると述べられている.

プルリクエストとは簡単に言うと、開発者のローカルリポジトリでの変更を他の開発者に通知する機能です。プルリクエストは次のような機能を提供します。

機能追加や改修など、作業内容をレビュー・マージ担当者やその他関係者に通知します。 ソースコードの変更箇所をわかりやすく表示します。 ソースコードに関するコミュニケーションの場を提供します。

上図の例では,開発者Aがrecord_resultブランチにCommit後,Pushを行い,リモートリポジトリにもrecord_resultブランチの開発内容をアップロードしている.その後,点線で描かれているように,record_resultの内容をmasterブランチに取り込んでも良いか(Merge)を他の開発者に確認してもらうために,Pull Requestを作成している.

Pull RequestはGithubの機能として実現されており,Github Desktopと呼ばれるGitクライアントやGithubのページから作成できる.他の開発者は作成されたPull Requestを見ることで,record_resultブランチで何が行われたのかを把握することができる.また,必要であればrecord_resultブランチを別の開発者が自身のローカルブランチに取り込み,動作確認を行うことも可能である. なお,Pull Requestrecord_resultブランチの開発が完了していなくても作成して構わない.その場合は,取り込み(Merge)が目的ではなく,実装内容を他の開発者に診てもらうことそのものが目的となる.


ルール5:Pull Request自分以外の誰かがレビュー(作業内容の確認)をしてOKを出してくれたときのみmasterブランチにmergeしてよい

ルール4で作成したPull Requestは自分以外の誰かに必ずレビュー(作業内容を確認してもらうこと)してもらった後に,masterブランチにマージできる.すなわち,自分以外の誰か他の開発者が,Pull Requestをチェックし,その作業内容をmasterブランチに統合(merge)しても問題ないと判断してはじめて,mergeを行うべきである. このルールはルール1にあるmasterブランチは常にデプロイ可能であることを保証するために存在する.複数の開発者が好き勝手にmasterブランチの内容を修正するのではなく,少なくとも2人以上の開発者が確認した後mergeを行うことで,masterブランチにバグが混入しにくくなる.

この図にあるように,Pull Requestが作成され,他の開発者によるレビューが完了してはじめて,Mergeを行い,record_resultブランチの内容をmasterブランチに取り込むことができる.Githubでは問題がなければPull Requestの画面からMergeを行うことができる.


ルール6:mergeをしてmasterへpushしたら,直ちにデプロイをする

ルール4,5で述べたPull Request機能によって,ある開発者が開発した機能はmasterブランチにmergeされる前にチェックされる.しかしながら,その場合でもバグが混入することがありうるため,masterブランチへのmergeが行われた時は,その直後に必ずmasterブランチの内容が正常にデプロイできるかどうかをチェックしなければならない.

本演習の場合は,下図が示すようにmasterブランチへのmerge後にmasterブランチを取得(Pull)し,正常にコンパイル・実行がProcessing環境上で可能であることを確認することを指すものとする.

以降では,本演習で利用するProcessing環境について説明した後に,上記の6つのルールにもとづいた開発をどのように行うかについて,簡単なゲーム開発を題材に演習を実施する.

問題

Github Flowはチームでバージョン管理システムを用いて開発をする上で発生する様々な問題を改善するためのルールを提供している.具体的にどのような問題が改善されるか,2つ以上の問題について述べよ.まず問題について説明し,その問題をGithub Flowのルールがどのように改善してくれるのかを記述すること.

1 https://about.gitlab.com/

2 https://github.com/

results matching ""

    No results matching ""