wajaの開発フロー
エンジニアブログ
2017-12-29
andyです。
今回はwajaの開発フローを振り返りつつ、現在どのようなフローで、どのようにツールを使っているか、ということを紹介したいと思います。
今までに大きく開発フローおよび利用ツールを2度変更しています。
最初はエンジニアも2,3名のころで、利用していたツールはSubversion、開発フローも1ブランチ開発、常に最新のコミットをリリース、といったシンプルな開発フローを取っていました。
その後デザイナーもエンジニアも増え、開発業務としても運用業務、改善/不具合修正、大きなリリース業務、とタスクの粒度もアサインされるメンバーもバラバラになってくるようになります。
また、各メンバーのレベルや得意分野も少しずつ分かれてくるようになり、お互いのスキルアップや修正範囲の把握、品質担保といったことを目的としてコードレビュー等も導入するようになりました。
そうなるとSubversionで1ブランチ開発、ではたち行かなくなりますので、分散管理システムやステージング環境へのデプロイを自動化する、といったことをやりたくなってきます。
そのために導入したフロー、ツールというのが下記の図のようになりました。
■利用ツール
・Git:バージョン管理のため。ブランチを切り分けて管理しやすいようにする
ことを目的とします。
・Gerrit:レビューのため。差分を確認し、行単位でコメントできる、といった
特徴があります。
・Jenkins:各種自動化を目的とします。
■主な開発フロー
・開発者はコミットする際、「change-id」というランダム値をコミット
メッセージに埋め込んでGerritに対してrefs/for/developブランチにpush
※ランダム値はGerritがコミットフックを提供しています。
・GerritはpushをトリガにJenkinsに対してテストジョブを実行する(フックを
使って特定のURLにアクセスする)
・Jenkinsはテスト上部を実行し、結果をGerritおよび開発者にレポートする
・開発者はセルフレビューをGerrit上で行い、問題なければGerrit上にマーキ
ング(+1)する
・レビューアはGerrit上でレビューを行い、問題なければGerrit上にマーキング
(+2)してSubmit(マージ)する
・GerritはマージをトリガにJenkinsに対してテストジョブを実行する
・Jenkinsはテスト結果を開発者、レビューアに通知し、成功していればステージ
ング環境にデプロイする
やりたいことは概ね実現できていたのですが、このフローには以下のようなデメリットがありました。
・Gerritがchange-idを1つのレビューに紐付けるため、レビュー結果の修正等
が同じコミットを上書きすることになる。
そのため1つのコミットが大きくなりがちになり、ブランチを分けて開発する必
要性が薄くなります。
何より開発者が自由にコミットできない(できたとしてもGerritにpushする際に
スカッシュする必要が出る)点がストレスです。
・運用業務といった、「直近でリリースしたいブランチ」の管理が難しい
develop, masterブランチでステージング環境、本番環境のブランチを管理して
いるのですが、直近リリースブランチをmasterブランチ起点で開発し、Gerrit
でmasterと比較してレビューし、問題なければ開発者自身がdevelopブランチ
から再度ブランチを切り直し、開発したコミットを自分自身でcherry pickする
という煩雑な業務が発生していました。
これはGerritを使う以上は仕方のない制限になりました。
・Jenkinsのジョブ設定が煩雑
Jenkinsは様々なジョブを自動実行できる反面、プラグイン等を駆使したとして
も各種設定が煩雑になり、簡単なスクリプトを準備したりする必要もあり、1つ
1つの設定が非常に手間がかかり、メンテナンスコストが上昇する傾向にありま
した。
・チケットと開発状況の紐づけを開発者自身が行う必要がある
チケット管理にはredmineを使っていましたが、あるチケット(タスク)がどの
程度の進捗状況なのか、開発者自身が都度更新しなければならないため、更新が
滞ることも多く、チケットがほぼ管理されていない状況になってしまっていま
した。
これら課題を解決するために、開発フローの見直し、および利用ツールを一新することにしました。
今期からの取り組みになりますが、現状は以下のようになっています。
■利用ツール
・Crucible:レビュー用。Gerritよりは操作性が落ちます。
・Bitbucket:Gitサーバ及びレビュー用。
・Bamboo:デプロイ等自動化用。
■主な開発フロー
・開発者は自分のタイミングでコミット、pushする。
定期リリースに入れるものはdevelop起点のfeatureブランチとし、
臨時リリースに入れるものはmaster起点のhotfixブランチとする。
・ビルドやテストが通っていなくても、好きなタイミングでCrucibleを使って
レビューやチャックを依頼できる。
・ブランチが完成したらBitbucket上でプルリクエストを出す。
・レビューアは適宜CrucibleやBitbucketを使いレビューし、完成したら
マージする。
・BitbcketからBambooにマージ通知され、ステージング環境に自動デプロイ
する。
書き出すとさほど変更点がないように見えますが、これにより以下のメリットを得ることができました。
・開発者が自分のタイミングでコミット&pushできるため、リズムも
精神的にも楽。
・レビューを気軽に依頼できるため、実装方針の相談などがやりやすい
・Bambooのビルド、デプロイタスクの管理が比較的簡単、
かつデプロイするブランチの切替設定がやりやすい
・JIRAと連携することで、そのタスクの状況が一目で分かる
また、JIRAにフローを設定することでチケットステータスの変更を
自動で行うことができる
まだまだ非効率な部分はありますが、初期から比較すると大きく「人がやらなくても良いこと」を減らし、やるべきことに集中できる環境が整ってきたのではないか、と考えています。
(ベンダーロックインしているというリスクに関してはデメリットかもしれませんが。。)
今後も引き続き課題点が出てきたらすぐに変えていく、という姿勢で開発フロー改善に取り組んでいこうと思います。