読者です 読者をやめる 読者になる 読者になる

継続開発のススメ

other

概要

開発をすればリリースがあり、リリースが終われば開発があります。継続開発をする以上はリリースと開発の繰り返しです。

開発手法やリリース手段は沢山あるのですが、あまりしっくりくるものが無かったので自分でまとめてみました。

これで完璧というものは残念ながらこの世にないと思うので、これからも臨機応変に良い流れを作って行ければと思います。

この文章は以下のような構成になってます。書き殴りですみません。

  • バージョンの付け方
  • ソースコード管理とリリース
  • タスク駆動
  • 環境方針

定義

いくつか事前に定義しておかないと話しが訳わからなくなりそうなので。

  • バージョン管理には git を採用しています。
  • 開発というのはコードを書く事だけを指してはいません。
  • ここでいうフレームワークは「自身で開発している」として扱います。そうしないとちょっと難しいので。
  • ライブラリは自身の開発とそれ以外があると思いますので、そこは明確的に分けていきます。
  • プロダクトとはフレームワークやライブラリを使って作る何かです。

フレームワークのバージョンの付け方

バージョン番号の構成

"1.2.10" のような 3 つの区分けによる付け方を採用しました。

それぞれ "メジャー.マイナー.リビジョン" と呼ぶことにしました。

メジャー
下位互換を考えない変更
マイナー
下位互換がある大幅な変更
リビジョン
バグフィックスや下位互換のある小幅な変更

小幅か大幅かは明確にするのは難しいので、チームで判断するべきです。

繰り上がりは使いません。リビジョンがたとえ 5000 になってもマイナーに繰り上がることはありません。

バージョン番号による安定版/開発版

良くあると思うのですが、マイナーの偶数を安定版、奇数を開発版と定義します。

2.1.10 は開発版、2.2.0 は安定版です。

プロダクトのバージョンの付け方

バージョン番号の構成はフレームワークと同様です。

バージョン番号によるリリース版と追従版

フレームワークが更新されたとしても「セキュリティや機能追加」がされないのであればプロダクトをあえてアップデートをする必要はありませんが、最新版のフレームワークに追従しておく必要はあります。もちろんそれがフレームワークではなくサードパーティのライブラリの一つに追従するのも必要でしょう。

マイナーの偶数を「リリース版」、奇数を「追従版(イイ名前が思いつかない)」とします。外にリリースするのは偶数番のみです。

バージョンの付け方のサンプル
X プロダクト
バージョン 1.2.3
Y プロダクト
バージョン 2.6.2
B フレームワーク
安定版 バージョン 2.2.1
B フレームワーク
開発版 バージョン 2.3.108
C ライブラリ
バージョン 1.4.0

C ライブラリが 1.2.0 から 1.4.0 にバージョンアップしました。 C ライブラリは B フレームワークを構成するライブラリの一つです。まずここで B フレームワークを対応させます。Y プロダクトには次のリリースで使いたい機能が入っていることもあり、影響はありますが X プロダクトには影響はなかったとします。Y プロダクトはマイナーを上げてリリースしますが、X プロダクトは追従するだけです。

まず B フレームワークの開発版 2.3.109 にて C ライブラリバージョン 1.4.0 を対応させます。さらにフレームワークの安定版 2.4.0 をリリースまで持って行きます。

X プロダクト
リリース バージョン 1.2.3
X プロダクト
追従 バージョン 1.3.1
Y プロダクト
リリース バージョン 2.6.2
Y プロダクト
追従 バージョン 2.7.87
B フレームワーク
安定版 バージョン 2.4.0
B フレームワーク
開発版 バージョン 2.5.0
C ライブラリ
バージョン 1.4.0

ここから X と Y のプロダクトのフレームワークアップデートを行っていきます。

X プロダクトには影響しないので 1.3.2 として追従アップデートを行います。Y プロダクトでは影響があるため 2.8.0 としてリリースします。

X プロダクト
リリース バージョン 1.2.3
X プロダクト
追従 バージョン 1.3.2
Y プロダクト
リリース バージョン 2.8.0
B フレームワーク
安定版 バージョン 2.4.0
C ライブラリ
バージョン 1.4.0

結局の所はタイミングが重要です。追従バージョンからリリースバージョンへのリリースのサイクルは製品のタイプによって変わってくると思います。

バージョンについて

あまりバージョンの付け方をきっちり書いている資料とか無いので、色々なプロジェクトを参考にして考えてみました。なにか良い資料などがあれば教えて頂ければと思います。

バージョン管理とリリース

上記のバージョンをつかったリリースをうまくやるためにも、バージョン管理システムは必須です。ここでは git と git の開発手法の一つである git-flow を使って説明していきます。

git-flow

git-flow では develop というブランチが開発ブランチです。新機能は全て feature というブランチを使って開発します。

またリリースの際は release というブランチを切ります。バグフィックスなどは hotfix というブランチを切って開発します。

詳しいのは git-flow 使ってみた でどうぞ。

git-flow を使った開発/ビルド/テスト/リリース

新機能はとにかく feature ブランチを切って、単体テストまで書いたら develop ブランチにマージします。

git flow feature finish ブランチ名

jenkins や travis-ci や buildbot などで develop ブランチに対して自動ビルド/自動テストをしかけておきます。新機能がばしばし入る場所なので赤いことは多いと思いますが、できる限り青にするように心がけます。

feature ブランチに対しては「長生きしそう」な場合は CI にブランチを登録して自動ビルドしてもらうようにしましょう。

feature ブランチのマージがある程度貯まってきたら定期的に開発版のリリースをしておくと良いです。これは気分的なモノではありますが、なんとなく目安になります。

さて、安定版のリリースに向けて release ブランチを切りましょう。今の開発版が 1.1.x だとしたら 1.2.0 です。

この時、開発版と安定版の担当者を分ける事をオススメします。安定版リリース担当者は release ブランチをメインに触って develop の事は気にしないようにします。

開発版担当者は release ブランチから定期的に develop に対して merge や cherry-pick をするようにします。

git flow release finish ブランチ名

安定版リリース後、安定版を使ってプロダクトを開発していきますが、その際もし安定版のフレームワークにバグがあった場合は hotfix ブランチを使って安定版側を直すようにしましょう。develop ブランチでは既に直ったとしても、再度リリースするよりはコストが低いです。

git flow hotfix finish ブランチ名

基本的にはこのサイクルの繰り返しです

タスク駆動

人間はとにかく忘れていきます、全員でタスクを共有できるようにしておくべきです。

github の issues や trac や redmine などを使って、気になったこと等、何でもイイから書き込むようにしましょう。

ただし「定期タスクレビュー」を行う事は必須です。これが無いとだんだんタスクが埋もれていって破綻します。

持っている課題をいかにタスクとして外に出せるかが重要になってきます。

タスクベースで仕事を依頼すると、仕事の負荷がわかりやすくなります。大事なのはできる限りタスクをこなさないで良いモノをリリースし続けるか、ということだと思います。

まぁ、難しいですが。

方針

環境を作っていて経験上これはいいな、って思ったことを箇条書きで書いてみます

  • レビューはコミット後
    • github 等を使えばコミットに対して突っ込みが入れやすくて、情報共有がしやすいです
    • レビューして貰いたい相手に丸投げできます、レビューを待っている間、開発が止まるなんて時間の無駄です
  • 単体テストと外部テストはリポジトリを切り離す
    • 外部テストは「まったく別のシステム」として作るべきです
    • 外部テストとはソースコードレイヤーでのテストではなく、API を実際に curl からたたくなどの外からのテストです
  • フルテストは自前でやらないで、ビルドシステムに任せる
    • 時間の無駄です。変更部分だけテストしたらさっさと push してしまいましょう
  • コーディング規約は出来るだけ作っておく
    • ルールはルールです、ある程度はちゃんと決めておいた方が開発してるときに悩みません
  • 少人数で開発する
    • 多くても 3 人程度な気がします、もちろん規模にもよります。これ以上多い場合は見通しが悪くなる気がします。
  • テスターは専任で(むしろ一番偉いくらいの勢いで)
    • 独立したテスター(特に負荷試験やセキュリティ試験に対して)を用意すべきです
    • テストはとても難しいので「開発ついで」で出来る技術ではありません
  • 週 1 程度の定期的なミーティングを行う
    • 「仕様」の打ち合わせと課題を持ち合わせて出来るだけ短く終わらせるように心がける
    • 課題を全員で話し合う場は絶対必要です
  • 開発チームと製品チームは分ける
    • 開発チームは develop ブランチと feature ブランチに注力させるべきです、そうしないと「新しい機能」を実装するのがおっくうになります
  • 出来るだけメールを使わない
    • 基本「顔を合わせての話し合い」をするべきです。メールは大きな変更が入ったときのアナウンス程度にしましょう
    • タスクの共有等はタスクドリブンのところで出したツールで共有します
    • 話し合いをする際は資料(テキストベース)を事前に git で共有しておきましょう
    • 話し合いの結果はすぐに資料に起こしておくのがオススメです。とくに資料は1枚でそれを淡々と更新していくと良いです。日付毎とかに分けると管理がめんどくさくなります。
  • コーディング規約は定期的に出来るだけ見直す
  • ライブラリがアップデートしたら出来るだけ早めに対応して、検証する

色々書き出してみましたが、まだまだある気がします。皆さんが思うこれはやっとくべきというのがあれば是非教えて下さい