Repository navigation
feat(backend): merge 元 PR の枝の baseline を default branch へ引き継ぐ - #58
Merged
Merged
Conversation
baseline の解決は枝の名前でしか探さないため、PR の枝で承認した baseline が merge 後の default branch のビルドから見えず、同じ変更の承認をもう一度求めていた。renovate の squash merge で依存を上げるたびに同じ絵を二度承認する形になっていた。
default branch のビルドを作るときに GET /repos/{repo}/commits/{sha}/pulls で merge 元の PR を引き、PR の枝の最新 baseline を default branch の baseline として写す。写した行は default branch の baseline なので、比較・承認・plan 添付の解決(latest_for)は変えずに引き継いだものを掴む。
- merge commit・squash・rebase のいずれでも API は同じ形で merge 済みの PR を返す(実 API で確かめた。rebase は前の方の写しでも同じ PR が返り、merge 後に PR の枝が消えていても引ける)
- 写すのは PR の枝の baseline が default branch の最新より新しいときだけ。default branch がその後に承認されていれば巻き戻さない
- source_build_id は元の承認ビルドを指したまま写すので、ビルドの刈り込みが写しの実体も守る
- GitHub App が無い・紐付いていない・API が失敗した・merge 済みの PR が無いときは何もせず、いまの二段解決のまま。ビルドの作成は失敗させない
- 必要な権限は既存の Pull requests(read を含む)で足りる
この変更は VRT-23 に当たる。git の祖先から解決する本筋は VRT-24 で扱う。
Assisted-by: multi-agent-shogun-aki-tweak
引き継ぐ baseline を枝の名前だけで選んでいた。枝の名前は merge の後に別の PR が使い回せるので、merge 済みの PR の枝名を新しい未 merge の PR が使い、その baseline を承認したあとで古い merge commit のビルドを作る(再実行など)と、別の PR の baseline が default branch へ写っていた。 写す元を、承認したビルドの PR 番号が GitHub から得た merge 元 PR の番号と一致する baseline の最新に限る。ビルドの PR 番号はビルド作成の要求が申告する値で、vrt-actions は github.event.pull_request.number を送る。PR 番号を持たないビルドで承認した baseline は写さない。 あわせて doc に二つを書いた。 - 何を信頼しているか。branch と commit_sha は申告で、sha が default branch 上に在ることも merge_commit_sha の一致も確かめない(後者は rebase merge のための意図した緩さ)。写せるのは同じプロジェクトで承認され merge された組だけで、default branch の最新より新しいときだけなので、祖先を確かめる API は足さない - created_at の境界。比べるのは行の created_at で、写した行には写した時刻が入るので、default branch の baseline が更新された後に merge された PR は引き継がない。source.created_at を保つだけでは、写しが名前の集合を丸ごと置き換えるので先の承認が消える。名前ごとの合成は VRT-26 で扱う 試験を三本足した。枝名を使い回した形、同じ merge commit の二度目のビルドで baseline の行が増えないこと、PR A の写しの後に merge した PR B を引き継がないこと。 Assisted-by: multi-agent-shogun-aki-tweak
inherit_from_branch は写さなかったときにどの訳でも None を返し、呼び手は何も残していなかった。PR 番号を申告しないビルド(push で作ったビルドなど)だけで承認した枝では引き継ぎが発火しないが、その訳がどこにも出なかった。 戻り値を Inheritance(Inherited / SourceIsDefaultBranch / NoBaselineForPullRequest / AlreadyInherited / DefaultBranchIsNewer)にし、inherit_merged_pr_baseline は写さなかったときに訳を info で残す。inherit_from_branch の呼び手はここだけである。 already_inherited の doc を実態に合わせた。ふつうは created_at の比べでも止まるが、写しと元の時刻は別のプロセスの時計で入るので、写した側の時計が遅れていれば写しの方が古くなりうる。そのとき二度写しを止めるのはこの守りだけである。 試験を二本足した。push のビルドだけで承認した枝を引き継がず NoBaselineForPullRequest を返すこと。写しの行の created_at を元より古く書き換えた形で、already_inherited だけが二度写しを止めること。 Assisted-by: multi-agent-shogun-aki-tweak
yupix
approved these changes
Oct 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
PR の枝で承認した baseline を、merge 後の default branch のビルドへ引き継ぎます。
GitHub App が使えるプロジェクトが対象です。App が無い場合の動作は変わりません。
Closes VRT-23(親: VRT-22)
背景
baseline は枝の名前だけで解決しています(同じ枝の最新 → default branch の最新)。
そのため、PR の枝で承認した baseline は merge で枝の名前が変わると見えなくなります。
merge 後の default branch のビルドは古い baseline と比べられ、同じ変更の承認をもう一度求めていました。
renovate の squash merge で目立ちます。
依存を上げるたびに、PR と merge 後の main で同じ絵を二度承認することになっていました。
変更点
GET /repos/{repo}/commits/{sha}/pullsで merge 元の PR を引きますlatest_for)は変えていません写すのは、PR の枝の baseline が default branch の最新より新しいときだけです。
default branch がその後に承認されていれば巻き戻しません。
写した行の
source_build_idは元の承認ビルドを指すので、系譜の表示とビルドの刈り込みはそのまま正しく働きます。次の場合は何もせず、これまでの解決のままです。
ビルドの作成は失敗させません。
merge の手法について
API の返す形は、merge commit・squash・rebase のどれでも同じでした(公開リポジトリで確かめました)。
rebase では、default branch に並んだどの写しの commit からでも同じ PR が返ります。
merge 後に PR の枝が消えていても引けることを、task の renovate の PR(squash と通常の merge)で確かめました。
権限
使う API は「Pull requests」の read を求めます。
既存の「Pull requests: Read and write」(PR コメント用)に含まれるので、App の権限は変わりません。
DB
migration はありません。
試験
tests/github_integration.rsに次を足しました。GitHub API は wiremock で差し替えています。
引き継ぐ側の試験は、実装の前に落ちることを確かめてあります。
引き継がない側の試験は、実装の守りを外すと落ちることを確かめてあります。
cargo test --workspace・cargo clippy --workspace --all-targets -- -D warnings・cargo fmt --all -- --checkは通っています。引き継ぐ baseline の選び方
引き継ぐのは、merge 元の PR の枝で、その PR の番号で承認した baseline の最新です。
枝の名前は merge の後に別の PR が使い回せるので、名前だけで選ぶと、古い merge commit のビルド(再実行など)が、同じ名前の別の PR の baseline を写してしまいます。
ビルドの PR 番号はビルド作成時に申告された値(vrt-actions が送る
pull_request_number)です。PR 番号を持たないビルドで承認した baseline は引き継ぎません。
ビルドの
branchとcommit_shaも申告された値で、その commit が default branch 上にあるかは確かめません。写せるのは、同じプロジェクトで承認され merge された baseline だけで、default branch の最新より新しいときだけなので、未承認の絵は入りません。
引き継がなかったときの記録
引き継がなかったときは、その訳をログに残します(
did not inherit the merged pull request's baseline、reason=…)。たとえば、PR 番号を送らないビルド(push で作ったビルドなど)だけで承認した枝は引き継がれず、
reason="no_baseline_for_pull_request"が出ます。引き継がない境界
比べるのは baseline の作成時刻で、引き継いだ行には引き継いだ時刻が入ります。
そのため、default branch の baseline が更新された後に merge された PR は引き継ぎません。
例: PR A と PR B を承認し、A を merge(引き継ぐ)してから B を merge すると、B は引き継がれません。
残る課題
git の祖先から baseline を解決する本筋は VRT-24 で扱います。
App の無い場合や GitHub 以外の forge は、この PR では救えません。
VRT-26 では baseline を名前ごとに合成して引き継ぎます。
いまは名前の集合を丸ごと置き換えるため、上の例の B を A の後に写すと A の承認が消えます。
そのため B は引き継がない境界にしています。
Assisted-by: multi-agent-shogun-aki-tweak