From 8340dcce795bd8535eb19210dfc856bba7541b40 Mon Sep 17 00:00:00 2001 From: Joseph Kostreva Date: Tue, 9 Apr 2024 08:46:57 -0500 Subject: [PATCH] Check gerrit dependencies using isMerged() When a gerrit change is merged, the dependencies are not always updated correctly until you change or rebase a patch. Calling isMerged() gets around this issue to make sure the dependency is merged. Consider the following scenario (merge-mode: cherry-pick): A user creates relation chain patch A and B. They update only A with a new patchset and gate. Then they apply the correct votes for B to gate. If isMerged() isn't called, change B will not start gating because it's dependencies are using a cached version of is_merged. Merge-mode cherry-pick supports merging a change that is an indirect ancestor (parent is any patchset of another change) as long as there are no conflicts with what is already merged in the repository. Change-Id: I6afc8b9897a0c04b416edd26b880386963932082 --- zuul/driver/gerrit/gerritconnection.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/zuul/driver/gerrit/gerritconnection.py b/zuul/driver/gerrit/gerritconnection.py index 5c120c9feb..1d100b945b 100644 --- a/zuul/driver/gerrit/gerritconnection.py +++ b/zuul/driver/gerrit/gerritconnection.py @@ -881,10 +881,22 @@ class GerritConnection(ZKChangeCacheMixin, ZKBranchCacheMixin, BaseConnection): 'GerritChange', str(dep_num), str(dep_ps)) dep = self._getChange(dep_key, history=history, event=event) + # Check if the change is depending on an older commit than what + # is the latest. If it is, then it might already be merged. In + # this case, call isMerged() to verify and don't use the cached + # version. This is necessary in the case of merge-mode cherry-pick. + # A change's parent may point to old patchset of a dependency but + # still be allowed to gate. + check_dep_key = ChangeKey(self.connection_name, None, + 'GerritChange', str(dep_num), + str(dep_ps + 1)) + check_dep = self._getChange(check_dep_key) + # This is a git commit dependency. So we only ignore it if it is # already merged. So even if it is "ABANDONED", we should not # ignore it. - if (not dep.is_merged) and dep not in needs_changes: + if dep not in needs_changes and not ( + dep.is_merged or not check_dep or self.isMerged(dep)): git_needs_changes.append(dep_key.reference) needs_changes.add(dep_key.reference)