承認者ルール 開発者ガイドライン

このドキュメントでは、マージリクエスト承認ルールに関するすべての関連機能のバックエンドデザインとフローについて説明します。

これは貢献者がコード設計を理解しやすくし、機能とその実装が進化するにつれて改善すべき部分があるかどうかを確認するのに役立つはずです。

実装の詳細は頻繁に変更される可能性があるため、意図的にあまり詳しく書いていません。そのようなことは、コードで説明すべきです。ここに挙げたコンポーネントは、承認ルール機能が動作するためのアプリケーションの主要な部分です。

note
これは生きているドキュメントであり、このドキュメントで触れられているコードベースの一部が変更または削除されたとき、あるいは新しいコンポーネントが追加されたときには、それに応じて更新されるべきです。

データモデル

erDiagram Project ||--o{ MergeRequest: " " Project ||--o{ ApprovalProjectRule: " " ApprovalProjectRule }o--o{ User: " " ApprovalProjectRule }o--o{ Group: " " ApprovalProjectRule }o--o{ ProtectedBranch: " " MergeRequest ||--|| ApprovalState: " " ApprovalState ||--o{ ApprovalWrappedRule: " " MergeRequest ||--o{ Approval: " " MergeRequest ||--o{ ApprovalMergeRequestRule: " " ApprovalMergeRequestRule }o--o{ User: " " ApprovalMergeRequestRule }o--o{ Group: " " ApprovalMergeRequestRule ||--o| ApprovalProjectRule: " "

ProjectMergeRequest

Project およびMergeRequest のモデルは、ee/app/models/ee/project.rb およびee/app/models/ee/merge_request.rb で定義されています。承認ルールはEEのみの機能であるため、非EEバージョンを拡張しています。マージリクエストの承認に関連するアソシエーションなどは、ここで定義されています。

ApprovalState

erDiagram MergeRequest ||--|| ApprovalState: " "

ApprovalState クラスはee/app/models/approval_state.rb で定義されています。 実際のActiveRecord モデルではありません。このクラスは特定のマージリクエストの承認状態に関連するすべてのロジックをカプセル化します:

  • ターゲットブランチに基づいてマージリクエストに適用される承認ルールを知ること。
  • 特定のターゲットブランチに適用される承認ルールを知ることができます。
  • すべてのルールが承認されたかどうかをチェックします。
  • 承認者が必要かどうかの確認。
  • 承認者が何人いるのか、まだ承認が必要なのかの把握。

プロジェクト (ApprovalProjectRule) またはマージリクエスト (ApprovalMergeRequestRule) から承認者データを取得し、ApprovalWrappedRule としてラップします。

ApprovalProjectRule

erDiagram Project ||--o{ ApprovalProjectRule: " " ApprovalProjectRule }o--o{ User: " " ApprovalProjectRule }o--o{ Group: " " ApprovalProjectRule }o--o{ ProtectedBranch: " "

ApprovalProjectRule モデルはee/app/models/approval_project_rule.rb で定義されています。

レコードは、プロジェクト設定またはプロジェクトレベルの承認者APIを介して承認ルールが追加/編集/削除されたときに作成/更新/削除されます。ApprovalState モデルでは、承認ルールが上書きされない場合に、これらのレコードを取得します。

protected_branches 属性は、ルールが保護ブランチにスコープされている場合に設定され、使用されます。この機能の詳細については、保護されたブランチの承認者を参照してください。

ApprovalMergeRequestRule

erDiagram MergeRequest ||--o{ ApprovalMergeRequestRule: " " ApprovalMergeRequestRule }o--o{ User: " " ApprovalMergeRequestRule }o--o{ Group: " " ApprovalMergeRequestRule ||--o| ApprovalProjectRule: " "

ApprovalMergeRequestRule モデルはee/app/models/approval_merge_request_rule.rb で定義されています。

マージリクエストの作成/編集フォームまたはマージリクエストレベルの承認者APIを介してルールが追加/編集/削除されると、レコードが作成/更新/削除されます。

approval_project_rule は、既存のApprovalProjectRule に基づく場合に設定されます。

ApprovalMergeRequestRule は、オーバーライドされなければapproval_project_rule を継承するので、protected_branches を持ちません。

ApprovalWrappedRule

erDiagram ApprovalState ||--o{ ApprovalWrappedRule: " "

ApprovalWrappedRuleee/app/modes/approval_wrapped_rule.rb で定義されており、ActiveRecord モデルではありません。ApprovalProjectRuleApprovalMergeRequestRule を共通インターフェイスとしてラップするために使用されます。また、以下のサブタイプを持ちます:

  • ApprovalWrappedAnyApprovalRule - any_approver ルールのラップに使用します。
  • ApprovalWrappedCodeOwnerRule - code_owner ルールのラップ用。

このクラスは、ほとんどの責任をラップする承認ルールに委譲しますが、以下の責任も負います:

  • 承認ルールが承認者であるかどうかのチェック。
  • 承認ルールが何件承認されたか、またはまだ承認が必要かを知ることができます。

この情報は、承認ルールとマージリクエストのApproval レコードから取得します。

Approval

erDiagram MergeRequest ||--o{ Approval: " "

Approval モデルはee/app/models/approval.rb で定義されています。このモデルはマージリクエストに対する承認者の情報を保存します。承認者が承認/取り消しを行うたびに、レコードが作成/削除されます。

コントローラーとサービス

承認ルール機能を動作させるために、以下のコントローラとサービスを使用しています。

API::ProjectApprovalSettings

この非公開 API はee/lib/api/project_approval_settings.rb で定義されています。

これは次のような場合に使用されます:

  • プロジェクト設定の承認者ルールを一覧表示します。
  • プロジェクト設定でのルールの作成/更新/削除
  • マージリクエストフォームの作成時に承認者ルールを一覧表示。

Projects::MergeRequests::CreationsController

このコントローラはapp/controllers/projects/merge_requests/creations_controller.rb で定義されています。

このコントローラのcreate アクションは、マージリクエストフォームが送信されたときに使用されます。ApprovalMergeRequestRule レコードを作成/更新/削除するためのパラメータapproval_rules_attributes を受け取ります。このパラメータは、MergeRequests::CreateService を実行する際に渡されます。

Projects::MergeRequestsController

このコントローラはapp/controllers/projects/merge_requests_controller.rb で定義されています。

このコントローラのupdate アクションは、マージリクエストフォームが送信されたときに使用されます。Projects::MergeRequests::CreationsController のようなものですが、代わりにMergeRequests::UpdateService が実行されます。

API::MergeRequestApprovals

このAPIはee/lib/api/merge_request_approvals.rb で定義されています。

Approvals API エンドポイントは、マージリクエストページのロード時に要求されます。

/projects/:id/merge_requests/:merge_request_iid/approval_settings は、以下の目的で使用される非公開 API エンドポイントです:

  • マージリクエストフォームの承認者をリストアップします。
  • マージリクエストページに承認者ルールを表示します。

UI および API 経由で MR を承認/承認解除する場合、Approve Merge RequestAPI エンドポイントとUnapprove Merge RequestAPI エンドポイントが要求されます。それに応じてMergeRequests::ApprovalServiceMergeRequests::RemoveApprovalService が実行されます。

API::ProjectApprovalRulesAPI::MergeRequestApprovalRules

これらのAPIはee/lib/api/project_approval_rules.rbee/lib/api/merge_request_approval_rules.rb で定義されています。

マージリクエスト承認者APIを使用して、プロジェクトおよびマージリクエストレベルのルールの一覧表示/作成/更新/削除を行います。

ApprovalRules::CreateService,ApprovalRules::UpdateService,ApprovalRules::ProjectRuleDestroyService,ApprovalRules::MergeRequestRuleDestroyService を適宜実行します。

ApprovalRules::ParamsFilteringService

このサービスはee/app/services/approval_rules/params_filtering_service.rb で定義されています。

MergeRequests::CreateServiceMergeRequests::UpdateService が実行されたときのみ呼び出されます。

これは、approval_rules_attributes パラメータの解析を担当します:

  • ユーザーが承認規則を更新できない場合は削除してください。
  • ユーザーがプロジェクトのメンバーかどうかをフィルタリングします。
  • グループIDがユーザーに表示されているかどうかをフィルタリングします。
  • any_approver ルールを特定します。
  • 指定された場合、隠しグループを追加します。
  • ユーザー定義の適用不可 (マージリクエストのターゲットブランチに適用されないルール) 承認ルールを追加します。

フロー

これらのフローチャートは、コントローラから各機能のモデルまでの流れを説明するのに役立つはずです。

いくつかのCRUD APIエンドポイントは意図的にスキップしています。

Web UI による承認ルール付きマージリクエストの作成

graph LR Projects::MergeRequests::CreationsController --> MergeRequests::CreateService MergeRequests::CreateService --> ApprovalRules::ParamsFilteringService ApprovalRules::ParamsFilteringService --> MergeRequests::CreateService MergeRequests::CreateService --> MergeRequest MergeRequest --> db[(Database)] MergeRequest --> User MergeRequest --> Group MergeRequest --> ApprovalProjectRule User --> db[(Database)] Group --> db[(Database)] ApprovalProjectRule --> db[(Database)]

更新時には同じフローに従いますが、Projects::MergeRequestsController から開始し、代わりにMergeRequests::UpdateService を実行します。

MR ページでのマージリクエスト承認ルールの表示

graph LR API::MergeRequestApprovals --> MergeRequest MergeRequest --> ApprovalState ApprovalState --> id1{approval rules are overridden} id1{approval rules are overridden} --> |No| ApprovalProjectRule & ApprovalMergeRequestRule id1{approval rules are overridden} --> |Yes| ApprovalMergeRequestRule ApprovalState --> ApprovalWrappedRule ApprovalWrappedRule --> Approval

このフローはフロントエンドコンポーネントによって開始されます。返されたデータは、MR ウィジェットに情報を表示するために使用されます。

マージリクエストの承認者

graph LR API::MergeRequestApprovals --> MergeRequests::ApprovalService MergeRequests::ApprovalService --> Approval Approval --> db[(Database)]

承認しない場合、同じフローに従いますが、代わりにMergeRequests::RemoveApprovalService が実行されます。

TODO

  1. code_ownerreport_approver など、他のルールタイプに関連する情報を追加。
  2. マージリクエストを承認/非承認した場合の副作用に関する情報を追加しました。