web-dev-qa-db-ja.com

ビルドに失敗したコミットを自動的に元に戻す

私の同僚は、ビルドに失敗したコミットを元に戻すようにCIサーバーを作成することを考えているため、HEADmasterは常に安定しています(少なくともビルドを渡す場合と同様)。 。

これはベストプラクティスですか、それとも開発者が修正するまでmasterをそのままにしておくよりも問題が多いのでしょうか?

私の考えでは、コミットを元に戻すと、コミットと修正を読み取るタスクがより複雑になります(開発者は元に戻して修正をコミットする必要があり、git log)そして、コミットをそのままにして、修正をコミットします。 masterを安定させることにはいくつかの利点がありますが、この失敗したコミットの復帰は私を納得させません。

編集:masterでも他の開発ブランチでもかまいませんが、問題は同じです。CIシステムがビルドに失敗したコミットを元に戻す必要がありますか?

別の(長い)編集:わかりました、gitを奇妙な方法で使用しています。ブランチにコミットすると、他の開発者やその変更から切り離され、ブランチを再統合して競合の可能性に対処しなければならない時間が増えるため、ブランチの概念は実際のCIに反すると考えています。全員がmasterにコミットすると、この競合は最小限に抑えられ、すべてのコミットがすべてのテストに合格します。

もちろん、これにより、安定版のみをプッシュ(またはビルドを中断)し、下位互換性を壊したり、新しい機能を導入するときに機能の切り替えを行わないように、より注意深くプログラムしたりする必要があります。

この方法またはその方法でCIを実行するとトレードオフがありますが、それは質問の範囲外です(これについては 関連する質問 を参照してください)。必要に応じて、私は質問を言い換えることができます。開発者の小さなチームが機能ブランチで協力します。ある開発者がそのブランチのビルドを壊す何かをコミットした場合、CIシステムはコミットを元に戻す必要があるかどうか。

44

次の理由でこれを行うことには反対です:

  • 自動ツールをユーザーに代わってコードを変更するに設定すると、間違いを犯したり、変更を中止する必要がある状況が発生したりするリスクがあります(例: 、Google Mockの最新バージョンにはバグがあったため、コードが失敗することはありません)、再構成に時間を費やす必要があります。さらに、コードのバグではなく、ビルドシステムのバグが原因でビルドが失敗するというわずかなリスクが常にあります。私にとって、CIはmy codeが正しいという確信を得ることです。これは単にそれを、私が心配する潜在的な問題の別の原因に変えるだけです。

  • 「ビルド」を壊すバグの種類すべき修正するのにほとんど時間がかからない愚かな間違いです(コメントで指摘したように、これはあなたにも当てはまります)。より微妙で複雑なバグが定期的にマスターに発生している場合、正しい解決策は「迅速に修正する」ことではなく、マージされる前に機能ブランチを確認する際により注意する必要があります。

  • バグが適切に修正されている間、マスターをビルドできない状態のまま数分間放置しても、誰にも害はありません。それは、CEOがマスターを個人的にチェックアウトし、ランダムなタイミングでクライアントに直接コードを公開するようなものではありません(少なくとも、おそらくあなたの関与なしではありません)。バグを修正する前に何かをリリースする必要がある非常にまれなイベントthenは、公開する前に手動で復帰することを簡単に決定できます。

56
Ixrec

最初に条件について合意しましょう。

私は個人的に、継続的ビルドと継続的統合という用語を使用して、2つの異なるシナリオを区別しています。

  • 継続的ビルド:前回のビルド以降にリポジトリが変更されたかどうかを定期的にチェックし、変更された場合はビルド/テストするツール。
  • 継続的インテグレーション:プルリクエストを取得し、最新のヘッドpriorに対して検証して、それらを可視化するツール。

後者の継続的統合は、保護するリポジトリが常に緑であることを意味します1:それは厳密に良いです。

あなたの質問は、Continuous Buildにとって本当に意味があるだけなので、これがあなたのセットアップであると仮定してお答えします。

1:環境の原因もビルドを台無しにする可能性があります。たとえば、ハードコードされた年(2015)のテストが2016年1月に失敗し始め、ディスクがいっぱいになる可能性があります...そしてもちろん、不安定なテストのペストがあります。私はここではそれらの問題を無視しています。そうでなければ、どこにも行きません。


継続的ビルドのセットアップをしている場合、ビルドを壊した可能性のあるコミットの逆転を実際に自動化できますが、いくつかの微妙な点があります。

  • 実際にコミットを取り除くことはできません。他の同僚がすでにコミットをチェックアウトしている可能性があり、次にコミットしようとしたときにプッシュバックします。代わりに、反転はreverse diffをコミットする必要があります。ああ、そして同僚は、それを正しくプッシュする方法を見つけなければならないので、それが正しかったときに自分の作業を元に戻すことを嫌います...
  • 実際には最後のコミット(それはマージです)だけを取り除くことはできませんが、すべてのコミットを取り除く必要があります...特定の時点まで。たとえば、最後の既知の適切なコミット(システムのブートストラップ時に注意してください)。
  • 外部の原因(環境の問題)について考え、すべてを0日目に戻す設定を回避する必要があります。ありがたいことに、最後の既知の良好なコミットに戻すことで、この問題を回避できます。
  • 最後の既知の適切なビルドがビルドされない可能性がある(環境の問題)と考える必要があります。その場合、それ以降のすべてのコミットが元に戻される可能性があります。理想的には、障害が発生した場合、および復帰する前に、最後に確認された適切なビルドをチェックアウトして、再テストします。合格した場合は元に戻し、そうでない場合はアラートを生成します。

このシステムでは、不安定なテストや同僚ががらくたをコミットする場合、多くの適切なコミットが取り消されることに注意してください。その後、同僚はあなたを嫌います。


うまくいけば、私のホラーストーリーで、壊れたリポジトリを許可する問題が明らかになったので、適切な継続的インテグレーションパイプラインを実装して、PRが直接リポジトリにプッシュされるのではなく、作業キューにマージするためにキューに入れられ、一度に1つ統合されるようにします(またはロールアップによる):

  • リポジトリのヘッドをローカルにフェッチする
  • プルリクエストを適用
  • ビルドしてテストする
  • 成功した場合はリポジトリにプッシュします。それ以外の場合は失敗としてマークします
  • 次のリクエストに移動

両方を試みたので、これは厳密に優れています。

26
Matthieu M.

これはベストプラクティスですか、それとも開発者が修正するまでマスターを壊れたままにするよりも問題が多いかもしれません。

問題があります。 「マスターHEADが壊れています。最初の変更を元に戻します」)を決定する人は、CIシステムが同じことをするのとはまったく異なります。

いくつかの欠点があります:

  • 自動リバーサルプロセスでエラーが発生すると、リポジトリが台無しになります。

  • これは、単一のチェンジセット(最上位)がビルドを台無しにしたことを想定しています(これは非現実的です)。

  • メンテナは、単に調査してコミットするだけでなく、問題を修正するためにより多くの作業を行う必要があります(逆の履歴も確認する必要があります)

ブランチにコミットすると、他の開発者やその変更から切り離され、ブランチを再統合して競合の可能性に対処しなければならない時間が増えるため、ブランチの概念は実際のCIに反すると考えています。

この信念(ブランチvs CI)は正しくありません。 one安定したブランチを維持することを検討してくださいユニットテスト済みチェンジセットのみをコミットします。残り(機能ブランチとローカルブランチ)は、各開発者の責任であり、CIポリシーの一部ではありません。

機能ブランチではwantが他の開発者から隔離されます。これにより、次のことが可能になります。

  • 探索的コーディングを実行する

  • コードベースを試す

  • 部分的なコミット(実際には機能しないコードをコミット)を実行して、バックアップポイントを設定(失敗した場合)、より意味のある変更履歴を(コミットメッセージを介して)作成し、作業をバックアップして他の何かに完全に切り替える( "git commit && git checkout")を書くのにかかる時間

  • 時間がかかる優先度の低いタスクを実行する(たとえば、データレイヤーの80クラスすべてを変更するリファクタリングを実行したい:すべてを変更してコードがコンパイルされるまで、1日に2つ変更する(ただし、これは可能)単一のコミットができるまで、誰にも影響を与えません)。

ある開発者がそのブランチのビルドを壊す何かをコミットした場合、CIシステムはコミットを元に戻す必要があるかどうか。

すべきではない。 CIブランチでの安定したコードのコミットは、自動化されたシステムではなく、コミッターの責任です。

5
utnapistim

Gerrit + Jenkins環境を使用して、マスターブランチを常に良好な状態に保つことをお勧めします。人々は新しいコードをGerritにプッシュします。これにより、Jenkinsジョブがトリガーされ、そのパッチ、ビルド、テストなどがプルされます。パッチのような他の開発者やJenkinsがその作業を正常に完了した場合、Gerritはそのコードをマスターブランチにマージします。

@ brian-vandenbergが説明している同様の環境

ブランチを良好な状態に保つことに加えて、ソフトウェアのコード品質と知識共有を改善するコードレビューステップを追加します。

[1]ジェンキンス https://jenkins-ci.org/

[2] Gerrit https://www.gerritcodereview.com/

2
Gustavo Coelho

CIがリポジトリのコミット履歴を変更することはありません。

ここでの正しい解決策は、テストおよび検証されていないコミットがマスターブランチに追加されないようにすることです。

機能ブランチで作業し、それらでCIを自動的に実行させますか?ビルドが失敗した場合、それらをマスターにマージしないでください。

機能ブランチで実行し、ビルド中にmaster/integration /何でもローカルブランチにマージしてからテストを実行することにより、問題がある場合はマージをテストする追加のビルドを作成できます。

1
Daenyth

ビルドサーバーにはJenkinsを使用し、コミットのプッシュにはゲートキーパーモデルを使用します-ここで、Jenkinsとコミットトリガーの組み合わせ(ピアレビューアーが作業を完了したことを確認)がゲートキーパーです。

コミットは curl を介して間接的にJenkinsにプッシュされます。マスターリポジトリを複製し、マージするコミットをプルして、必要なすべてのビルドを実行します(Linux/solarisの場合)。すべてのビルドが完了すると、コミットがプッシュされます。

これにより、これまでに説明した問題のすべてではなくても多くが回避されます。

  • 歴史改変
  • 破損を修正する必要がある開発者であれば、履歴を正しく取得する
  • (壊れたビルドの形の)不安定性は決して導入されません

また、単体テストが正常に完了するなど、他の要件を直接適用することもできます。

1

尋ねられた質問には欠陥があります。私はこの声明を尊重します

「ブランチにコミットすると、他の開発者やその変更から切り離されるため、ブランチのコンセプトは実際のCIに反すると信じています。」

あなたがすべきことはこれらのステップです

  • 必要に応じてマスターで作業します(それは問題なく、全員から変更をプルし続けます)しかし、ローカルでマスターにコミットしないでください
  • 変更をマスターにコミットする直前に、submit_XXXXXXでブランチを作成します
  • 自動ビルドですべてのsubmit_XXXブランチビルドを取得する
  • オプション1:ブレークをビルド、またはブレークをマージ...変更が拒否され、マスターに到達しない
  • オプション2:ビルドが機能し、ジェンキンスがマスターをプッシュして更新する

次に、git commitフックを配置して、実際に全員がマスターにコミットするのを防ぎます。それは素晴らしい働きをします...これまでに壊れたビルドはなく、マスターからのコミットを元に戻すこともありません。

後で、ディーン

0
Dean Hiller

最後のコミットでビルドが壊れたという自動メールを何回受け取りましたか?それは何回間違っていますか?しかし、今度は、それが本当にあなた自身なのか、それとも同じ時間に別のコミットをした誰かなのかを確認する必要があります。あるいは多分それは環境的なものでした。

システムが確実にわからない場合は、自動化したくありません。

0
Mohair