コンテンツにスキップ
BeeuniBeeuni
日本語
Esc
↑↓移動↵開く⌘Jプレビュー
このページの内容

変更リクエスト

セッションでの作業がレビューを経てデフォルトブランチに反映される仕組み。

変更リクエスト(CR)は、ある git ブランチを別のブランチにマージします。Beeuni は、セッションのブランチ(head_ref)からプロジェクトのデフォルトブランチ(base_ref、通常は main)への CR を作成します。CR の行はメタデータであり、マージ、差分、競合チェックはプロジェクトのリポジトリに対する実際の git 操作として実行されます。セッションの作業をデフォルトブランチに到達させる唯一の方法が CR です。

作業を CR 経由にする理由

セッションは、セッション ID にちなんで命名された独自のブランチ上のサンドボックスで実行されます。サンドボックスは永続しませんが、ブランチは永続します。セッションの作業を永続的に記録する唯一の場所が git だからです。新しいセッションはすべてデフォルトブランチから開始されます。CR がマージされるまでは、作業は独自のブランチに残り、レビューされず、他のエージェント、トリガー、コラボレーターから見えません。これは、コード、エージェント、スキル、マニフェスト(beeuni.yaml)を含むすべての変更に適用されます。例外はありません。

エージェントの義務

エージェントは、プロジェクトのデフォルトブランチに変更を取り込むために CR を開く必要があります。エージェント自身が CR をマージしてはいけません。マージはユーザーの判断です。次の契約に従ってください。

  1. セッションブランチ($BEEUNI_BRANCH_NAME)でコミットする。小さく、動作するコミットを作成する。履歴を書き換えたり、強制プッシュしたりしない。
  2. ブランチをプッシュする: git push origin HEAD。
  3. CR を開く: beeuni cr open --title "..." --description "..."。セッションサンドボックス内では、--head と --session のデフォルトは $BEEUNI_BRANCH_NAME と $BEEUNI_SESSION_ID です。--base のデフォルトはプロジェクトのデフォルトブランチです。
  4. ユーザーがレビューできるよう、CR 番号を伝える。
  5. 停止する。自分で CR をマージしない。

アンチパターン

  • デフォルトブランチへの強制プッシュ。 バックエンドが許可している場合でも、レビューの契約に違反します。
  • 「自分のブランチにあるので、自分で取得してください。」 CR が先にマージされていない限り、サンドボックスが停止するとセッションブランチは失われます。
  • 変更をファイル、貼り付け、アーカイブとして送る。 CR システムがすでにこの問題を解決しています。

データモデル

CR は change_requests テーブルに保存されます。

列 型 注記
cr_id uuid 主キー。REST API の識別子。
project_id uuid CR が属するプロジェクト。
number integer プロジェクトごとの表示番号(#1、#2…)。プロジェクトごとに一意。再利用されない。
title text 必須。
description text 空文字列がデフォルト。
base_ref text マージ先のブランチ。通常は main。
head_ref text マージ元のブランチ。セッションではセッション ID(UUID)。
status enum open、merged、または closed。
head_commit_sha text オープン中の CR では、読み取りのたびにライブの head_ref の先端に対して更新される。マージ済み CR ではマージ時に取得される。
base_commit_sha text base_ref に対しても同じルール。
origin_session_id text CR を開いたセッション。セッションが削除されると null に設定される。
created_by uuid CR を作成したユーザー。
merged_at / merged_by timestamp / uuid CR をマージした日時とユーザー。
merge_commit_sha text マージコミット。fast-forward の場合は head_commit_sha と等しい。
closed_at / closed_by timestamp / uuid マージせずに CR をクローズした日時とユーザー。
metadata jsonb requested_changes を保持する。これは POST /:crId/request-changes が追加した {text, by, at} エントリのリスト。CR に独立したコメントテーブルはない。
created_at / updated_at timestamp 作成時に設定される。ステータス変更または SHA 更新のたびに更新される。

(project_id, number) に一意なインデックスがあるため、UUID の代わりに短い番号で CR を参照できます。

ライフサイクル

open ──(merge)──▶ merged      (terminal)
open ──(close)──▶ closed ──(reopen)──▶ open
  • open は開始時のステータスです。
  • closed は元に戻せます。POST /:crId/reopen により open に戻ります。
  • merged は終端状態です。マージ済みの CR を再度開いたりクローズしたりすることはできません。マージ後の状態に対して新しい CR を開いてください。

Beeuni は、デフォルトブランチより先行するコミットがブランチにない CR の作成を拒否します。通常、これはエージェントがローカルでコミットしたものの、プッシュしていないことを意味します。コミットをプッシュしてから、もう一度 CR を作成してください。

SHA の更新

オープン中の CR では、Beeuni はすべての GET で、ライブブランチに対して head_commit_sha と base_commit_sha を更新します。リポジトリに到達できない場合、またはブランチが存在しない場合、Beeuni は更新をスキップし、CR の最後に確認されたメタデータを提供します。マージ済みの CR では、マージ時に取得された SHA が保持され、Beeuni が再度更新することはありません。

マージの仕組み

POST /v1/projects/:projectId/change-requests/:crId/merge は次の手順を実行します。

  1. Beeuni は head_ref からマニフェスト(beeuni.yaml)を読み取り、マニフェストスキーマに対して検証します。マニフェストがないブランチは合格します。無効なマニフェストの場合、code: "MANIFEST_INVALID" を伴う 422 を返してマージを停止します。
  2. head_ref が base_ref より厳密に先行している場合、Beeuni は そのブランチ を fast-forward します。
  3. それ以外の場合、Beeuni はマージコミットを作成します。デフォルトメッセージは Merge CR #<n>: <title> で、リクエスト本文の message で上書きできます。コミット作成者は Beeuni <noreply@beeuni.com> です。
  4. 競合がある場合、競合リストを伴う 409 を返します。マージ前に GET /:crId/merge-preview で同じリストを確認できます。
  5. 成功すると、Beeuni は status を merged に設定し、merged_at、merged_by、merge_commit_sha を記録して、プロジェクトの git キャッシュを無効化します。

open ではない CR をマージすると、409 が返されます。

マージプレビュー

GET /:crId/merge-preview は次を返します。

フィールド 型 意味
base_sha string base_ref の現在の先端。
head_sha string head_ref の現在の先端。
merge_base string | null 共通の祖先。履歴が無関係の場合は null。
is_up_to_date boolean head_ref が base_ref に完全にマージされているかどうか。
can_merge boolean 競合がない。
can_fast_forward boolean head_ref が base_ref より厳密に先行しているかどうか。
conflicts string[] 競合するファイルパス。

REST API

すべてのルートは /v1/projects/:projectId/change-requests 配下にあります。

メソッド パス 注記
GET / ?status=open|merged|closed|all。フィルターを指定しない場合はすべてのステータスを返す。
POST / 本文: {title, description?, head_ref, base_ref?, session_id?}。201 を返す。
GET /:crId CR を返す。副作用として SHA を更新する。
PATCH /:crId title または description を編集する。open でない場合は 409。
GET /:crId/diff 統合パッチ: ファイル一覧、追加、削除。
GET /:crId/merge-preview 上記のマージプレビューを参照。
POST /:crId/merge 本文: {message?}。無効なマニフェストの場合は 422。競合時または open でない場合は 409。
POST /:crId/close すでに merged の場合は 409。
POST /:crId/reopen closed でない場合は 409。
POST /:crId/request-changes 本文: {feedback}。metadata.requested_changes に追加し、元のセッションのエージェントを起動する。open でない場合は 409。

POST / は、base_ref より先行するコミットがない head_ref を拒否します: 422 code: "CR_HEAD_NOT_AHEAD"。これは、ブランチをプッシュする前に CR を開いた場合にエージェントが受け取るエラーです。

認証

読み取りルートにはプロジェクトへの読み取りアクセスが必要です。書き込みルートには書き込みアクセスが必要です。各書き込み操作にはさらに権限が必要で、完全なトークンの場合とセッションのスコープ付きトークンの場合を以下に示します。

操作 権限
CR を開く project.gitops.push
変更を要求 project.review.act
マージ project.gitops.merge

各アクションに1つの機能を割り当てます。これはフルトークンでも、セッションにスコープされたトークンでも同じです。オープンとマージは別々のリーフであるため、トークンには変更リクエストをオープンする権限だけを与え、マージする権限は与えないこともできます。これが、上記のエージェントへの権限付与の仕組みです。

project.cr.openとproject.cr.mergeは、カットオーバー前のproject.gitops.pushとproject.gitops.mergeの名称で、同じ機能の別名でした。これらのいずれかがまだ記載されているbeeuni.yamlも引き続き機能します(権限付与は、解決時に現在の名称へ書き換えられます)。ただし、新しく作成するものにはgitopsの名称を使用してください。

セッションには、どのような権限が付与されていても、自分でオープンした変更リクエストをマージすることはできません。このルールは構造上のものであり、機能ではありません。

このページは役に立ちましたか?