前回のDay 21では、複数人のC#エンジニアがスプリント並行開発を進める際の「トピックブランチ完全隔離」と「毎朝のリベース習慣」を学びました。
本日のDay 22は、第5部 ケーススタディの第2弾として、開発プロジェクトの中で最もプレッシャーがかかる【テスト・結合フェーズ(ステージング環境でのバグ出しと収束)】を徹底解説します!
Subversion (SVN) や Visual SourceSafe (VSS) で開発してきたベテランエンジニアの方なら、「リリース前テストが始まったので、今日から trunk へのコミットは全面禁止です!」というアナウンスに頭を抱えた経験があるのではないでしょうか。
テスト中のバグ修正と次期バージョンの新機能開発が同じ場所で行われていたため、開発チーム全体が「手待ち(足止め)」状態に陥っていたのです。
しかしGitなら、リリースブランチ(
release/v1.0.0)を活用することで、QA・結合テストでのバグ修正だけを綺麗に収束させつつ、次期機能開発チームは develop で1秒も止まることなく爆速開発を継続できます。本日は、リリースブランチの切り方、ステージング環境へのデプロイ、C#での厳格なバグ修正コミットルール、そしてリリース完了時に絶対に欠かせない「双方向マージバック(先祖返り防止)」の実践テクニックを完全伝授します!
① 導入・本日の達成目標
システム開発が終盤に差し掛かると、QA(品質保証)チームやテスターによる結合テスト・受託受け入れテストがステージング環境で行われます。
このフェーズで最も恐ろしいのは、「テスト中の安定版コードに、未完成の次期新機能が紛れ込んでしまうこと」です。
Gitのリリースブランチ運用(Git Flow / GitLab Flow等)を正しく理解していれば、「テスト対象のバージョン」と「次期開発の本流」を物理的にブランチで分離し、極めて安全かつ迅速に製品を本番公開へと導くことができます。
- SVNの「テスト中コミット禁止令(開発凍結)」とGitのリリースブランチ隔離の違いを理解する
- リリースブランチ(
release/v1.0.0)の作成タイミングと「フィーチャーフリーズ」の意義を把握する - ステージング環境への自動デプロイとC#(.NET)プロジェクトにおける結合テスト検証フローを身につける
- テスト期間中の厳格コミット方針(新機能追加の全面禁止とバグ修正コミットの書き方)を習得する
- リリース完了時の「双方向マージバック(mainとdevelopへのマージ)」により先祖返り(バグ復活)を100%防止する
② 【図解】テスト期間中の開発ブロック対比:SVNの開発凍結 vs Gitのリリースブランチ隔離
まずは、SVNなどの集中型バージョン管理とGitにおける「テスト期間中のチーム全体の動き」を比較してみましょう。
開発凍結(コミット禁止令)の悲劇 vs リリースブランチの隔離力
- SVNの悲劇(全員の手が止まる開発凍結): SVNではブランチの取り回しが難しいため、テスト期間に入ると「本番リリースまで trunk へのコミットは禁止!」というお触れが出ます。次期バージョンの機能を作りたくてもコミットできないため、ローカルにファイルを退避したり、開発自体が完全にストップして膨大な工数ロスが発生していました。
- Gitの理想(リリースブランチによる完全並行): Gitでは、テスト開始の瞬間に
developからrelease/v1.0.0を分岐させます。ステージング環境にはこのブランチだけをデプロイし、QAチームがバグ出しを行います。次期機能(v1.1.0向け)を開発するメンバーは、そのままdevelop上で何事もなかったかのように開発を続行できます。チームの生産性が1ミリも落ちません!
③ 【図解】リリースブランチのライフサイクル(分岐から収束まで)
リリースブランチが生まれてから役割を終えるまでのライフサイクルは、以下の4つの明確なステップで進行します。
リリースブランチ運用の4ステップ
-
① 分岐とフィーチャーフリーズ(機能追加の凍結):
リリースターゲットの全機能がdevelopに揃ったら、リリースブランチを切ります。
git switch -c release/v1.0.0 develop
この瞬間以降、このブランチには「新しい機能の追加(feature)」は一切禁止となります。 -
② ステージング環境へのデプロイと検証開始:
GitHub Actions などのCI/CDパイプラインにより、release/v1.0.0がプッシュされると自動的にステージング環境へビルド・デプロイされます。QA担当者やクライアントが受け入れテストを開始します。 -
③ バグ修正コミットの集中投下:
テストで不具合が発見された場合、開発者はrelease/v1.0.0に対して直接修正コミット(または修正用トピックブランチからのPR)を投入します。修正されるたびにステージングへ即時反映され、再テストが行われます。 -
④ 収束とリリースサインオフ:
すべての重要バグ(Blocker/Critical/Major)が解消され、全自動テスト(E2E、結合テスト)がグリーンになれば、リリースブランチの目的は達成です。本番リリース作業へと移行します。
④ 【現場実践】C#現場でのステージング検証とバグ修正コミットの鉄則
.NET / C# のエンタープライズ現場では、ステージング環境特有の設定やデータベースとの結合テストが行われます。
このフェーズで絶対に守るべき「3大鉄則」を押さえておきましょう。
- 鉄則1:環境設定の厳格分離(appsettings.Staging.json)
接続文字列や外部APIエンドポイントはappsettings.Staging.jsonに分離し、コード本体にハードコードしないこと。環境変数やAzure Key Vaultから注入する設計にしておくことで、デプロイ事故を防ぎます。 - 鉄則2:新機能の「ついでコミット」は即死級の重罪
「ちょっと時間が余ったから次の便利な機能も入れておこう」は絶対に厳禁! 1つの余計なコード変更が予期せぬサイドエフェクト(退行バグ)を引き起こし、テスト工数を倍増させます。 - 鉄則3:コミットメッセージは明確に "fix:" で打つ
fix(payment): タイムアウト時の再試行リクエストで2重決済になる不具合を修正 (#412)のように、Conventional Commitsに従い、修正の対象とチケット番号を明記します。
⑤ 【最重要】リリース完了時の双方向マージバック:先祖返りを100%防止する
テストが完了し、本番環境へのリリースが決定したとき、多くの現場が一度はやらかす「最大の落とし穴」があります。
それは、「リリースブランチで行ったバグ修正を、developブランチへ戻し忘れること」です!
先祖返り(リグレッション)の恐怖と解決手順
release/v1.0.0 でせっかく直したバグを main だけにマージして満足してしまうと、次期バージョン(v1.1.0)を develop からリリースした際、「前に直したはずのバグが再び大復活する(先祖返り)」という大惨事が発生します。
これを防ぐため、リリース完了時は必ず以下の「双方向マージバック」を行います。
git switch main
git merge --no-ff release/v1.0.0
git tag -a v1.0.0 -m "Release version 1.0.0"
# ② 【超重要】develop(次期開発の本流)へも必ずマージバック!
git switch develop
git merge --no-ff release/v1.0.0
# ③ 役目を終えたリリースブランチを安全に削除
git branch -d release/v1.0.0
git push origin --delete release/v1.0.0
⑥ 現場の実践まとめ&次回予告
📌 本日の最重要ポイントまとめ
- リリースブランチで隔離せよ: SVNの「テスト中コミット禁止(開発凍結)」を撤廃し、
release/*ブランチを切ることでQAテストと次期開発を完全並行化する。 - フィーチャーフリーズの徹底: リリースブランチには新機能を一切持ち込まず、QAで発見されたバグ修正(fix)のみを集中投入する。
- ステージング環境の自動連携: C# / .NET では
appsettings.Staging.jsonで安全に設定を切り替え、CI/CDで迅速に結合検証を進める。 - 双方向マージバックの鉄則: リリース完了時は
main(本番タグ)だけでなく、必ずdevelopへもマージバックして修正の先祖返り(バグ復活)を未然に防ぐ。
次回は、第5部 ケーススタディの第3弾!
【Day 23: 【Case 3】本番リリースとタグ打ち(安定バージョンの凍結)】をお届けします!
ステージングテストをクリアしたコードを本番環境へ安全に反映させ、不変のバージョン番号(セマンティックバージョニング)を付与する「タグ打ちと本番リリース」の完全手順を徹底解説します。お楽しみに!
コメント
コメントを投稿