ベリファイステージのコードベースに貢献します。

ベリファイで取り組んでいること

Verifyステージでは、GitLab製品に統合された包括的な継続的インテグレーションプラットフォームに取り組んでいます。私たちのゴールは、ユーザーが行う仮定を検証し、CI/CD設定で定義された基準と照らし合わせてチェックする、高速で信頼性が高くセキュリティの高いプラットフォームを提供することで、ユーザーが優れた技術的・ビジネス的な意思決定を行えるようにすることです。ユニットテスト、エンドツーエンドテスト、ベンチマーク、パフォーマンス検証、コードカバレッジの実施などです。

GitLab CI/CDによって提供されるフィードバックは、ユーザーが成功するために必要な技術的、ビジネス的な選択について、十分な情報に基づいた決定を下すことを可能にします。なぜ継続的インテグレーションがミッションクリティカルな製品なのですか?

GitLab CI/CDはユーザーや顧客にフィードバックを届けるためのプラットフォームです。

彼らは継続的インテグレーション設定ファイル.gitlab-ci.yml を貢献し、彼らが答えを得たい質問を記述します。誰かがコミットをプッシュしたりパイプラインをトリガーしたりするたびに、私たちは CI/CD 設定で尋ねられた非常に重要な質問に対する答えを見つける必要があります。

これらの質問に答えられなかったり、さらに悪いことに、間違った答えを提供したりすると、ユーザーは間違った判断を下すかもしれません。そのような間違った決定は非常に深刻な結果をもたらす可能性があります。

CI/CDプラットフォームの基本原則

プラットフォームが生成するデータは

  1. 正確であること。
  2. 耐久性があります。
  3. アクセスしやすい。

プラットフォームそのものが

  1. 信頼できること。
  2. セキュリティ。
  3. 決定論的。
  4. 信頼できる
  5. 速い。
  6. シンプル。

GitLab CI/CDの設立以来、私たちはこれらの原則を守り、私たちとユーザーに貢献してきました。これらの原則の例をいくつか挙げます:

  • GitLab CI/CDが提供するフィードバックやプラットフォームが生成するデータは正確であるべきです。もしジョブが失敗し、それが成功したとユーザーに通知した場合、深刻な悪影響を及ぼす可能性があります。
  • フィードバックはユーザーが必要なときに利用できる必要があり、データはエンジニアが必要なときに突然消えてはいけません。
  • プラットフォームがセキュリティで保護されておらず、クレデンシャルやシークレットが漏れてしまっては意味がありません。
  • ユーザーがCI/CD設定の形で前提条件のセットを提供する場合、パイプラインが実行されるたびに結果が確定的であるべきです。
  • そうでなければ、プラットフォームは信頼できないかもしれないからです。高速で、使い方がシンプルで、優れたUXを備えていれば、ユーザーに十分なサービスを提供できます。

ベリファイでの構築

最適化する前に測定し、データに基づいた意思決定を行います。

測定できないものを最適化するのは非常に困難です。成功したかどうか、あるいはその成功がどの程度重要なものであったかを、どうやって知ることができるでしょうか?パフォーマンスや信頼性の改善に取り組んでいるのであれば、最適化する前に必ず測定してください。

物事を測定する最善の方法は、Prometheusメトリクスを追加することです。カウンタ、ゲージ、ヒストグラムは、おおよその結果を素早く得るための素晴らしい方法です。残念ながら、これはテールレイテンシを測定する最良の方法ではありません。Prometheusメトリクス、特にヒストグラムは通常近似値です。

テールレイテンシを測定する必要がある場合、例えば、どれぐらい遅いか、どれぐらいリクエストペイロードが大きいかを測定する必要がある場合、カスタムアプリケーションログの追加を検討し、常に構造化されたロギングを使用してください。

コードの実行経路が実際にどのようなものかを理解するために、プロファイリングとフレームグラフを使うことは有用です!

単純な解決策に努め、巧妙な解決策は避けましょう

より速く何かを提供するために、巧妙な解決策を使いたくなることがあります。なぜなら、長期的に理解し、メンテナーするのが難しくなるからです。その代わりに、コードベースの進化を容易にし、貢献者の障壁を低く保つような、退屈なソリューションに集中したいのです。できるだけシンプルなソリューションを見つけたいのです。

退屈な解決策と簡単な解決策を混同しないでください。

退屈な解決策と簡単な解決策が混同されることがあります。その逆もよくあります。例えば、複雑な新しいライブラリを、そうでなければすぐに実装できるような非常に小さな機能を追加するために含めることができます。

一方で、シンプルで、よくテストされ、よくメンテナーされたライブラリが利用可能な場合、過剰にエンジニアリングすることも可能です。その場合、ライブラリを使うことは理にかなっているかもしれません。私たちは、シンプルなソリューションと簡単なソリューションのバランスを常に考えており、適切なバランスを見つけることが重要であると認識しています。

“シンプル “は “フレキシブル “と相反するものではありません。

シンプルなものを作ることは、より高度で柔軟なソリューションが利用できなくなることを意味しません。.gitlab-ci.yml の設定を書くのが複雑になってきているのが良い例です。例えば、環境名を定義する簡単な方法を使うことができます:

deploy:
  environment: production
  script: cap deploy

しかし、environment キーワードは、より柔軟性を提供できる別のレベルの設定に拡張することもできます。

deploy:
  environment:
    name: review/$CI_COMMIT_REF_SLUG
    url: https://prod.example.com
  script: cap deploy

このようなアプローチは、新規ユーザーをプラットフォームの複雑性から守りながらも、必要であればより深く掘り下げていくことを可能にします。このアプローチは、他の多くの技術的な実装にも適用できます。

物事を観察可能に

GitLabはDevOpsプラットフォームです。私たちがDevOpsを普及させているのは、DevOpsが企業の効率性を高め、より良い成果を達成するのに役立つからです。DevOpsカルチャーの重要な要素の一つは、構築している機能やコードに対してオーナーシップを持つことです。自分の機能が本番環境でどのように機能し、どのように動作するのかがわからないときに、それを実行するのは非常に困難です。

これが、私たちが機能やコードを観察可能にしたい理由です。作成者が、その機能やコードが本番環境でどのように動作するのか、あるいはどのように動作しないのかを理解できるように書かなければなりません。私たちは通常、Prometheusメトリクスとアプリケーションロガーを適切に組み合わせることでこれを実現します。

TODOドキュメント Prometheus メトリクスをいつ使い、ロガーをいつ使うか。ヒストグラムとカウンタについて数文書いてください。インクリメンタル・ロールアウトを行う際のメトリクスの重要性を強調する文章をいくつか書いてください。

顧客データの保護

CI/CDプラットフォームによって生成されたデータを耐久性のあるものにすることは重要です。ユーザーや顧客によってCI/CDで生成されたデータは重要なものであり、私たちはそれを保護しなければならないと認識しています。このデータは重要な情報を含んでいるため重要であるだけでなく、私たちにはコンプライアンスと監査責任があります。

したがって、データベースからデータを永久に削除するマイグレーションを作成するときや、新しい保持ポリシーを定義するときには、細心の注意を払う必要があります。

一般的なルールとして、データベース、ファイルシステム、またはオブジェクトストレージからデータを削除するようなコードを書いているときは、その変更について特別な目を持つべきです。新しいリテンションポリシーを定義するときは、PMやEMにダブルチェックすべきです。

設計のレビュー

パイプライン処理やCI/CDステータスの移行のためにサブシステムを設計しているときは、できるだけ早い段階でベリファイのメンテナー(@gitlab-org/maintainers/cicd-verify)に設計に関する追加意見を求め、他の人にも同じことをする責任を負わせてください。ベリファイのメンテナーに設計をレビューしてもらうことで、見落としている盲点を早期に発見でき、より良いソリューションにつながる可能性があります。

開発作業を開始する前に設計をレビューしてもらうことで、マージリクエストレビューをより効率的に行うこともできます。ベリファイのメンテナーがデザインをレビューしていれば、メンテナーのレビュー中に意見が大きく異なったり、変更要求が出たりする可能性は低くなります。その結果、マージリクエストをより早くマージすることができます。

変更のレビューを受ける

マージリクエストをレビューする準備ができたら、レビュアーとメンテナーを割り当てなければなりません。変更の複雑さによっては、あなたが変更しようとしているコードベース領域について最もよく知っている人たちに参加してもらうとよいでしょう。レビュアー・ルーレットによって割り当てられたレビュアーやメンテナーが、その変更について十分な情報を持っているかどうか確信が持てない場合、ベリファイには多くのドメインエキスパートやメンテナーがいますので、彼らにあなたのコードのレビューを依頼してもかまいません。

レビュアー・ルーレットは有用な提案をしてくれますが、適切なレビュアーを割り当てることは重要なので、毎回自動的に行われるべきではありません。なぜなら、彼らのフィードバックはコードのスタイルや構文に限定されるかもしれないからです。変更の複雑さや影響度によっては、適切な人をレビュアーに割り当てることは非常に重要かもしれません。

誰を割り当てればいいかわからない場合は、git blame に相談するか、#s_verify Slack チャンネルで尋ねてください(GitLab チームメンバーのみ)。

変更/マージリクエストには、レビューや追加のレビュアーによる追加的な注意を必要とする2つの種類があります:

  1. パイプライン/ステージ/ビルドステータスに関するコードを変更するマージリクエスト。
  2. 認証/セキュリティ機能に関するコードを変更するマージリクエスト。

どちらの場合も、エンジニアはメンテナーとドメインの専門家にレビューを依頼することが期待されます。メンテナーがドメインの専門家である場合は、別の人を参加させることを推奨します。

インクリメンタルロールアウト

あなたのマージリクエストがメンテナーによってマージされた後、ユーザーやより広いコミュニティにリリースする時が来ました。通常、機能フラグを使ってこれを行います。すべてのマージリクエストに機能フラグが必要なわけではありませんが、ベリファイではほとんどのマージリクエストに機能フラグをつけるべきです。

このページのアドバイスに従っている場合、すでにいくつかのメトリクスと、おそらくいくつかのロガーが追加されているはずです。これで、これらのメトリクスを使用して、変更をインクリメンタルにロールアウトできるようになります!

典型的なシナリオは、メトリクスまたはロガーを観察しながら、いくつかの内部プロジェクトでいくつかの機能を有効にすることです。ElasticやKibanaにログを取り込む際に、若干の遅延が発生する可能性があることに注意してください。その機能が内部プロジェクトでうまく機能することを確認したら、他のプロジェクトにインクリメンタル・ロールアウトを開始できます。

パーセント・オブ・タイム」のインクリメンタル・ロールアウトの使用は避けてください。特に、コードベースの数カ所で機能フラグをチェックしており、チェックの結果を1カ所にメモしていない場合、エラーが発生しやすくなります。

私たちの宇宙を崩壊させないでください。

最初の GitLab 貢献者イベントの一つで、CI/CD パイプライン、ステージ、ジョブのステータスを正確に保つことの重要性について議論しました。私たちは、初期の顧客によって構築されたソフトウェアに関する仮想シナリオを考えました。

大型ハドロン衝突型加速器(LHC)にデプロイされたソフトウェアが、パイプラインがパスしたことを示す GitLab CI/CD のバグが原因で壊れた場合、このデータは正確ではなく、デプロイされたソフトウェアは実際には無効だったとしたらどうなるでしょうか?このような問題はLHCの誤作動を引き起こし、新たな粒子を生成して宇宙を崩壊させる可能性があります。

GitLab CI/CDのステータス処理における小さなバグの結果としては、非常に望ましくないことでしょう。CI/CDステータスを処理する際には十分注意してください。私たちは宇宙を崩壊させたくありません!

これは極端でありそうもないシナリオですが、正確でないデータを提示することはバタフライ効果によって無数の問題を引き起こす可能性があります。悲惨な結果をもたらす可能性のあるシナリオはもっとたくさんあります。GitLab CI/CDは、医療、航空、自動車のソフトウェアを構築する企業で使用されています。継続的インテグレーションはソフトウェアエンジニアリングのミッションクリティカルな部分です。

To-Do の定義

ベリファイでは、開発チームの「完了の定義」に従っています。また、ユーザーの質問に答えたり、問題を解決したりする際には、効率的でDRY な状態を維持したいと考えています。

解決策が既存の.gitlab-ci.yml 構文でサポートされているために解決されたイシューについては、ci-sample-projects グループに解決策を示すプロジェクトを作成します。

そのプロジェクトには以下のものが必要です:

  • シンプルなタイトル
  • 明確な説明。
  • README.md と:
    • 解決したイシューへのリンク。また、疑問が生じた場合は、解決したイシューでコラボレーションするようユーザーを誘導してください。
    • 関連ドキュメントへのリンク。
    • 例題が行っていることの詳細な説明。