diff --git a/codecov-cli/codecov_cli/helpers/ci_adapters/buildkite.py b/codecov-cli/codecov_cli/helpers/ci_adapters/buildkite.py index 7b0412cf..f70e84f9 100644 --- a/codecov-cli/codecov_cli/helpers/ci_adapters/buildkite.py +++ b/codecov-cli/codecov_cli/helpers/ci_adapters/buildkite.py @@ -22,12 +22,42 @@ def _get_commit_sha(self): return os.getenv("BUILDKITE_COMMIT") def _get_slug(self): + # https://buildkite.com/docs/pipelines/configure/environment-variables#BUILDKITE_REPO + repo_url = os.getenv("BUILDKITE_REPO") + if repo_url: + slug = self._parse_slug_from_repo(repo_url) + if slug: + return slug + + # Fallback to organization and pipeline slugs org = os.getenv("BUILDKITE_ORGANIZATION_SLUG") repo = os.getenv("BUILDKITE_PIPELINE_SLUG") if org and repo: return f"{org}/{repo}" return None + def _parse_slug_from_repo(self, repo_url: str): + """ + TODO: this is relevant: https://stackoverflow.com/questions/31801271/what-are-the-supported-git-url-formats + supports: + (protocol://)host.xz/path/to/repo(.git/) + (protocol://)host.xz:path/to/repo(.git/) + (protocol://)user@host.xz:path/to/repo(.git/) + (protocol://)user@host.xz/path/to/repo(.git/) + """ + if not repo_url: + return None + + value = repo_url.strip() + value = value.removesuffix("/") + value = value.removesuffix(".git") + + value = value.replace(":", "/") + parts = [p for p in value.split("/") if p] + if len(parts) >= 2: + return "/".join(parts[-2:]) + return None + def _get_service(self): return "buildkite" diff --git a/codecov-cli/tests/ci_adapters/test_buildkite.py b/codecov-cli/tests/ci_adapters/test_buildkite.py index 11475941..94055da8 100644 --- a/codecov-cli/tests/ci_adapters/test_buildkite.py +++ b/codecov-cli/tests/ci_adapters/test_buildkite.py @@ -12,6 +12,7 @@ class BuildkiteEnvEnum(str, Enum): BUILDKITE_BUILD_NUMBER = "BUILDKITE_BUILD_NUMBER" BUILDKITE_BUILD_URL = "BUILDKITE_BUILD_URL" BUILDKITE_COMMIT = "BUILDKITE_COMMIT" + BUILDKITE_REPO = "BUILDKITE_REPO" BUILDKITE_ORGANIZATION_SLUG = "BUILDKITE_ORGANIZATION_SLUG" BUILDKITE_PIPELINE_SLUG = "BUILDKITE_PIPELINE_SLUG" BUILDKITE_PULL_REQUEST = "BUILDKITE_PULL_REQUEST" @@ -105,6 +106,33 @@ def test_pull_request_number(self, env_dict, expected, mocker): "env_dict,expected", [ ({}, None), + ( + { + BuildkiteEnvEnum.BUILDKITE_REPO: "git@github.com:codecov/umbrella.git" + }, + "codecov/umbrella", + ), + ( + { + BuildkiteEnvEnum.BUILDKITE_REPO: "https://github.com/codecov/umbrella.git" + }, + "codecov/umbrella", + ), + ( + { + BuildkiteEnvEnum.BUILDKITE_REPO: "ssh://git@github.com/codecov/umbrella.git" + }, + "codecov/umbrella", + ), + ( + {BuildkiteEnvEnum.BUILDKITE_REPO: "git://github.com/codecov/umbrella"}, + "codecov/umbrella", + ), + ( + # already-slug-like fallback + {BuildkiteEnvEnum.BUILDKITE_REPO: "codecov/umbrella"}, + "codecov/umbrella", + ), ( { BuildkiteEnvEnum.BUILDKITE_ORGANIZATION_SLUG: "myorg", @@ -119,6 +147,15 @@ def test_pull_request_number(self, env_dict, expected, mocker): }, "myorg/subteam/myrepo", ), + ( + # precedence: BUILDKITE_REPO should win over ORG/PIPELINE + { + BuildkiteEnvEnum.BUILDKITE_REPO: "git@github.com:codecov/umbrella.git", + BuildkiteEnvEnum.BUILDKITE_ORGANIZATION_SLUG: "myorg", + BuildkiteEnvEnum.BUILDKITE_PIPELINE_SLUG: "myrepo", + }, + "codecov/umbrella", + ), ( { BuildkiteEnvEnum.BUILDKITE_ORGANIZATION_SLUG: "myorg",