diff --git a/codecov_cli/helpers/ci_adapters/github_actions.py b/codecov_cli/helpers/ci_adapters/github_actions.py index f12d2105..86e3ac98 100644 --- a/codecov_cli/helpers/ci_adapters/github_actions.py +++ b/codecov_cli/helpers/ci_adapters/github_actions.py @@ -1,9 +1,12 @@ +import logging import os import re import subprocess from codecov_cli.helpers.ci_adapters.base import CIAdapterBase +logger = logging.getLogger("codecovcli") + class GithubActionsCIAdapter(CIAdapterBase): # https://docs.github.com/en/actions/learn-github-actions/environment-variables @@ -17,14 +20,27 @@ def _get_commit_sha(self): if not pr: return commit - # actions/checkout should be run with fetch-depth > 1 or set to 0 for this to work - completed_subprocess = subprocess.run( - ["git", "rev-parse", "HEAD^@"], capture_output=True - ) - - parents_hash = completed_subprocess.stdout.decode().strip().splitlines() - if len(parents_hash) == 2: - return parents_hash[1] + merge_commit_regex = r"^[a-z0-9]{40} [a-z0-9]{40}$" + merge_commit_message = subprocess.run( + ["git", "show", "--no-patch", "--format=%P"], + capture_output=True, + ).stdout + + try: + merge_commit_message = merge_commit_message.decode("utf-8").strip() + + if re.match(merge_commit_regex, merge_commit_message) is not None: + merge_commit = merge_commit_message.split(" ")[1] + logger.info(f" Fixing merge commit SHA ${commit} -> ${merge_commit}") + commit = merge_commit + elif merge_commit_message == "": + logger.info( + "-> Issue detecting commit SHA. Please run actions/checkout with fetch-depth > 1 or set to 0" + ) + except (AttributeError, TypeError): # For the re.match and .decode + logger.info( + f" Commit with SHA {commit} of PR {pr} is not a merge commit" + ) return commit diff --git a/tests/ci_adapters/test_ghactions.py b/tests/ci_adapters/test_ghactions.py index 5d7efb44..4bb1fd08 100644 --- a/tests/ci_adapters/test_ghactions.py +++ b/tests/ci_adapters/test_ghactions.py @@ -56,7 +56,7 @@ def test_commit_sha_in_merge_commit_and_parents_hash_len_is_2(self, mocker): return_value=fake_subprocess, ) - fake_subprocess.stdout = b"aa74b3ff0411086ee37e7a78f1b62984d7759077\n20e1219371dff308fd910b206f47fdf250621abf" + fake_subprocess.stdout = b"aa74b3ff0411086ee37e7a78f1b62984d7759077 20e1219371dff308fd910b206f47fdf250621abf\n" assert ( GithubActionsCIAdapter().get_fallback_value(FallbackFieldEnum.commit_sha) == "20e1219371dff308fd910b206f47fdf250621abf" @@ -82,6 +82,32 @@ def test_commit_sha_in_merge_commit_and_parents_hash_len_is_not_2(self, mocker): == "1234" ) + def test_commit_sha_in_merge_commit_is_empty(self, mocker): + mocker.patch.dict( + os.environ, {GithubActionsEnvEnum.GITHUB_SHA: "1234"}, clear=True + ) + mocker.patch.object( + GithubActionsCIAdapter, "_get_pull_request_number" + ).return_value = "random_pr_number" + + fake_subprocess = mocker.MagicMock() + mocker.patch( + "codecov_cli.helpers.ci_adapters.github_actions.subprocess.run", + return_value=fake_subprocess, + ) + + fake_subprocess.stdout = b"" + assert ( + GithubActionsCIAdapter().get_fallback_value(FallbackFieldEnum.commit_sha) + == "1234" + ) + + fake_subprocess.stdout = None + assert ( + GithubActionsCIAdapter().get_fallback_value(FallbackFieldEnum.commit_sha) + == "1234" + ) + @pytest.mark.parametrize( "env_dict,slug,build_code,expected", [