Skip to content

Commit 3cb7eef

Browse files
🐛 Ensure that if a fetch fails it retries with authentication in the same way as clone (#143)
<!-- Copyright (C) 2020-2026 Arm Limited or its affiliates and Contributors. All rights reserved. SPDX-License-Identifier: Apache-2.0 --> ### Description <!-- Please add any detail or context that would be useful to a reviewer. --> Problem: - `cd-assert-news` creates a temporary clone of the repo - that clone later does a git fetch - the fetch used the normal remote URL without authentication - in a private repo, that failed with GitHub credential errors Fix: - it tries a normal fetch first - if that fails, it retries using the authenticated GitHub URL built from `GIT_TOKEN` This is the same way htat `clone()` works. ### Test Coverage <!-- Please put an `x` in the correct box e.g. `[x]` to indicate the testing coverage of this change. --> - [x] This change is covered by existing or additional automated tests. - [ ] Manual testing has been performed (and evidence provided) as automated testing was not feasible. - [ ] Additional tests are not required for this change (e.g. documentation update). --------- Co-authored-by: Adrien CABARBAYE <adrien.cabarbaye@arm.com>
1 parent a59daf6 commit 3cb7eef

3 files changed

Lines changed: 35 additions & 2 deletions

File tree

continuous_delivery_scripts/utils/git_helpers.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,13 @@ def is_release_branch(self, branch_name: Optional[str]) -> bool:
196196

197197
def fetch(self) -> None:
198198
"""Fetches latest changes."""
199-
self.repo.git.fetch(all=True, tags=True, force=True)
199+
try:
200+
self.repo.git.fetch(all=True, tags=True, force=True)
201+
except GitCommandError as e:
202+
logger.info("failed fetching repository: %s" % e)
203+
logger.info("Retrying a different way")
204+
self.set_remote_url(self._git_url_ssh_to_https(self.get_remote_url()))
205+
self.repo.git.fetch(all=True, tags=True, force=True)
200206

201207
def get_branch(self, branch_name: str) -> Any:
202208
"""Gets a specific local branch.

news/20260601135433.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:bug: Ensure that if a fetch fails it retries with authentication in the same way as clone

tests/git_helper/test_git_helpers.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
# Copyright (C) 2020-2026 Arm Limited or its affiliates and Contributors. All rights reserved.
33
# SPDX-License-Identifier: Apache-2.0
44
#
5-
from unittest import TestCase
5+
from unittest import TestCase, mock
6+
7+
from git import GitCommandError
68

79
from continuous_delivery_scripts.utils.configuration import (
810
configuration,
@@ -37,6 +39,30 @@ def test_list_tracked_files(self):
3739
self.assertTrue(len(tracked_files) > 0)
3840
self.assertIn("setup.py", tracked_files)
3941

42+
@mock.patch.object(GitWrapper, "set_remote_url")
43+
@mock.patch.object(
44+
GitWrapper,
45+
"_git_url_ssh_to_https",
46+
return_value="https://test-token:x-oauth-basic@github.com/example/repository.git",
47+
)
48+
@mock.patch.object(
49+
GitWrapper,
50+
"get_remote_url",
51+
return_value="https://github.com/example/repository.git",
52+
)
53+
def test_fetch_retries_with_authentication(self, _get_remote_url, _git_url_ssh_to_https, set_remote_url):
54+
"""Ensures fetch retries with authentication when needed."""
55+
repo = mock.Mock(spec_set=["git"])
56+
repo.git = mock.Mock(spec_set=["fetch"])
57+
repo.git.fetch.side_effect = [GitCommandError("fetch", 128, stderr="fatal"), None]
58+
59+
git = GitWrapper(path=Path("."), repo=repo)
60+
61+
git.fetch()
62+
63+
self.assertEqual(2, repo.git.fetch.call_count)
64+
set_remote_url.assert_called_once_with("https://test-token:x-oauth-basic@github.com/example/repository.git")
65+
4066

4167
class TestGitTempClone(TestCase):
4268
def test_git_clone(self):

0 commit comments

Comments
 (0)