Skip to content

Commit 3982879

Browse files
authored
chore(ci-visibility): fix git temp dir (#5992)
CI Visibility: If there is an exception while using the temporary dir to unpack git commits, use cwd instead. This is an issue that happens on certain CI environments, not just for Python. ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines) are followed. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). ## Reviewer Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment.
1 parent ac4639c commit 3982879

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

ddtrace/ext/git.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,28 @@ def extract_user_git_metadata(env=None):
227227
def build_git_packfiles(revisions, cwd=None):
228228
# type: (str, Optional[str]) -> Generator
229229
basename = str(random.randint(1, 1000000))
230-
with TemporaryDirectory() as tempdir:
231-
prefix = "{tempdir}/{basename}".format(tempdir=tempdir, basename=basename)
230+
try:
231+
with TemporaryDirectory() as tempdir:
232+
prefix = "{tempdir}/{basename}".format(tempdir=tempdir, basename=basename)
233+
_git_subprocess_cmd(
234+
"pack-objects --compression=9 --max-pack-size=3m %s" % prefix, cwd=cwd, std_in=revisions.encode("utf-8")
235+
)
236+
yield prefix
237+
except ValueError:
238+
# The generation of pack files in the temporary folder (`TemporaryDirectory()`)
239+
# sometimes fails in certain CI setups with the error message
240+
# `unable to rename temporary pack file: Invalid cross-device link`.
241+
# The reason why is unclear.
242+
#
243+
# A workaround is to attempt to generate the pack files in `cwd`.
244+
# While this works most of the times, it's not ideal since it affects the git status.
245+
# This workaround is intended to be temporary.
246+
#
247+
# TODO: fix issue and remove workaround.
248+
if not cwd:
249+
cwd = os.getcwd()
250+
251+
prefix = "{tempdir}/{basename}".format(tempdir=cwd, basename=basename)
232252
_git_subprocess_cmd(
233253
"pack-objects --compression=9 --max-pack-size=3m %s" % prefix, cwd=cwd, std_in=revisions.encode("utf-8")
234254
)

tests/ci_visibility/test_ci_visibility.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,31 @@ def test_git_client_build_packfiles(git_repo):
340340
assert not os.path.isdir(directory)
341341

342342

343+
@mock.patch("ddtrace.ext.git.TemporaryDirectory")
344+
def test_git_client_build_packfiles_temp_dir_value_error(_temp_dir_mock, git_repo):
345+
_temp_dir_mock.side_effect = ValueError("Invalid cross-device link")
346+
found_rand = found_idx = found_pack = False
347+
with CIVisibilityGitClient._build_packfiles("%s\n" % TEST_SHA, cwd=git_repo) as packfiles_path:
348+
assert packfiles_path
349+
parts = packfiles_path.split("/")
350+
directory = "/".join(parts[:-1])
351+
rand = parts[-1]
352+
assert os.path.isdir(directory)
353+
for filename in os.listdir(directory):
354+
if rand in filename:
355+
found_rand = True
356+
if filename.endswith(".idx"):
357+
found_idx = True
358+
elif filename.endswith(".pack"):
359+
found_pack = True
360+
if found_rand and found_idx and found_pack:
361+
break
362+
else:
363+
pytest.fail()
364+
# CWD is not a temporary dir, so no deleted after using it.
365+
assert os.path.isdir(directory)
366+
367+
343368
def test_git_client_upload_packfiles(git_repo):
344369
serializer = CIVisibilityGitClientSerializerV1("foo", "bar")
345370
remote_url = "[email protected]:test-repo-url.git"

0 commit comments

Comments
 (0)