mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-10-15 18:07:18 +00:00
sync: Support SYNC_BRANCH to override the smart sync branch
`repo sync -s` always sends the manifest branch to the manifest server as the `branch` argument of GetApprovedManifest. Some servers map one manifest branch to several server-side (CI) branches, and the only way to pick among them was indirectly through the target. Honor a SYNC_BRANCH environment variable, mirroring SYNC_TARGET: if set and non-empty, send it instead of the manifest branch. An empty value is treated as unset. -t/--smart-tag is unaffected. Bug: 568962967 Test: ./run_tests Change-Id: I26700e8997c21487f83011258100fd91a5c87508 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/639123 Commit-Queue: Rahul Yadav <yadavrah@google.com> Reviewed-by: Gavin Mak <gavinmak@google.com> Tested-by: Rahul Yadav <yadavrah@google.com>
This commit is contained in:
1 parent
0a4e68f9d2
commit
340b587e94
3 files changed
+87
-3
No files matched your search
+4
-1
@@ -174,7 +174,10 @@ Explicitly enables Smart Sync. Repo will call
|
||||
`GetApprovedManifest(branch[, target])`.
|
||||
|
||||
The `branch` is determined by the current manifest branch as specified by
|
||||
`--manifest-branch=BRANCH` when running `repo init`.
|
||||
`--manifest-branch=BRANCH` when running `repo init`. If `${SYNC_BRANCH}` is
|
||||
defined and non-empty, its value is sent instead. This allows selecting a
|
||||
branch other than the one the checkout tracks, e.g. a server-side (CI) branch
|
||||
name that builds from the same manifest branch.
|
||||
|
||||
The `target` is defined by environment variables in the order below. If none
|
||||
of them match, then `target` is omitted. These variables were decided as they
|
||||
|
||||
+12
-2
@@ -2059,7 +2059,12 @@ later is required to fix a server side protocol bug.
|
||||
|
||||
return server_url, transport
|
||||
|
||||
def _SmartSyncSetup(self, opt, smart_sync_manifest_path, manifest):
|
||||
def _SmartSyncSetup(
|
||||
self,
|
||||
opt: optparse.Values,
|
||||
smart_sync_manifest_path: str,
|
||||
manifest: XmlManifest,
|
||||
) -> str:
|
||||
if not manifest.manifest_server:
|
||||
raise SmartSyncError(
|
||||
"error: cannot smart sync: no manifest server defined in "
|
||||
@@ -2077,7 +2082,12 @@ later is required to fix a server side protocol bug.
|
||||
try:
|
||||
server = xmlrpc.client.Server(server_url, transport=transport)
|
||||
if opt.smart_sync:
|
||||
branch = self._GetBranch(manifest.manifestProject)
|
||||
# SYNC_BRANCH overrides the branch sent to the manifest server
|
||||
# (e.g. to select a specific CI branch that builds the same
|
||||
# manifest branch). An empty value is treated as unset.
|
||||
branch = os.environ.get("SYNC_BRANCH")
|
||||
if not branch:
|
||||
branch = self._GetBranch(manifest.manifestProject)
|
||||
target = None
|
||||
if "SYNC_TARGET" in os.environ:
|
||||
target = os.environ["SYNC_TARGET"]
|
||||
|
||||
@@ -2982,3 +2982,74 @@ class TestSmartSyncSetupRemoteHelper(unittest.TestCase):
|
||||
"Stderr was: debugging logs",
|
||||
str(context.exception),
|
||||
)
|
||||
|
||||
|
||||
class TestSmartSyncSetupBranch(unittest.TestCase):
|
||||
"""Tests for how _SmartSyncSetup picks the branch sent to the server."""
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.cmd = sync.Sync()
|
||||
self.opt = mock.MagicMock()
|
||||
self.opt.quiet = True
|
||||
self.opt.smart_sync = True
|
||||
self.opt.smart_tag = None
|
||||
self.manifest = mock.MagicMock()
|
||||
self.manifest.manifest_server = (
|
||||
"http://android-smartsync.corp.google.com/manifestserver"
|
||||
)
|
||||
self.manifest.manifest_server_helper = None
|
||||
self.smart_sync_manifest_path = "/fake/path/to/manifest.xml"
|
||||
self.mock_server = mock.MagicMock()
|
||||
self.mock_server.GetApprovedManifest.return_value = [
|
||||
True,
|
||||
"<manifest></manifest>",
|
||||
]
|
||||
self.cmd._GetBranch = mock.MagicMock(return_value="main")
|
||||
self.cmd._ReloadManifest = mock.MagicMock()
|
||||
self.cmd._ResolveManifestServerTransport = mock.MagicMock(
|
||||
return_value=(self.manifest.manifest_server, mock.MagicMock())
|
||||
)
|
||||
|
||||
def _RunSetup(self, env: Dict[str, str]) -> str:
|
||||
with mock.patch.dict(os.environ, env, clear=True), mock.patch(
|
||||
"xmlrpc.client.Server", return_value=self.mock_server
|
||||
), mock.patch("builtins.open", mock.mock_open()):
|
||||
return self.cmd._SmartSyncSetup(
|
||||
self.opt, self.smart_sync_manifest_path, self.manifest
|
||||
)
|
||||
|
||||
def test_default_branch(self) -> None:
|
||||
"""Without SYNC_BRANCH the manifest branch is used."""
|
||||
self._RunSetup({})
|
||||
self.cmd._GetBranch.assert_called_once_with(
|
||||
self.manifest.manifestProject
|
||||
)
|
||||
self.mock_server.GetApprovedManifest.assert_called_once_with("main")
|
||||
|
||||
def test_sync_branch(self) -> None:
|
||||
"""SYNC_BRANCH replaces the manifest branch."""
|
||||
self._RunSetup({"SYNC_BRANCH": "git_main-abfs"})
|
||||
self.cmd._GetBranch.assert_not_called()
|
||||
self.mock_server.GetApprovedManifest.assert_called_once_with(
|
||||
"git_main-abfs"
|
||||
)
|
||||
|
||||
def test_sync_branch_with_target(self) -> None:
|
||||
"""SYNC_BRANCH and SYNC_TARGET are both forwarded."""
|
||||
self._RunSetup(
|
||||
{
|
||||
"SYNC_BRANCH": "git_main-abfs",
|
||||
"SYNC_TARGET": "cf_x86_64_phone-trunk_staging-eng",
|
||||
}
|
||||
)
|
||||
self.mock_server.GetApprovedManifest.assert_called_once_with(
|
||||
"git_main-abfs", "cf_x86_64_phone-trunk_staging-eng"
|
||||
)
|
||||
|
||||
def test_empty_sync_branch(self) -> None:
|
||||
"""An empty SYNC_BRANCH falls back to the manifest branch."""
|
||||
self._RunSetup({"SYNC_BRANCH": ""})
|
||||
self.cmd._GetBranch.assert_called_once_with(
|
||||
self.manifest.manifestProject
|
||||
)
|
||||
self.mock_server.GetApprovedManifest.assert_called_once_with("main")
|
||||
Reference in new issue
Block a user