Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

Commit 2e74f27

Browse files
committed
feat: implement customizable URL paths for upload endpoints
This enables downstream projects like prevent-cli to customize upload endpoint URLs by setting url_paths in the Click context object. - Add DEFAULT_URL_PATHS constant in upload.py with configurable URL templates - Pass url_paths from command context through do_upload_logic to UploadSender - Support different URL paths for COVERAGE and TEST_RESULTS upload types - Update prevent-cli main.py to customize TEST_RESULTS path to test_analytics
1 parent 14be544 commit 2e74f27

6 files changed

Lines changed: 86 additions & 23 deletions

File tree

codecov-cli/codecov_cli/commands/upload.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,27 @@
22
import os
33
import pathlib
44
import typing
5+
56
import click
67
import sentry_sdk
78

89
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
910
from codecov_cli.helpers.args import get_cli_args
1011
from codecov_cli.helpers.options import global_options
12+
from codecov_cli.helpers.upload_type import ReportType, report_type_from_str
1113
from codecov_cli.services.upload import do_upload_logic
1214
from codecov_cli.types import CommandContext
13-
from codecov_cli.helpers.upload_type import report_type_from_str, ReportType
1415

1516
logger = logging.getLogger("codecovcli")
1617

18+
DEFAULT_URL_PATHS = {
19+
ReportType.COVERAGE: {
20+
"upload_coverage": "/upload/{git_service}/{encoded_slug}/upload-coverage",
21+
"uploads": "/upload/{git_service}/{encoded_slug}/commits/{commit_sha}/reports/{report_code}/uploads",
22+
},
23+
ReportType.TEST_RESULTS: "/upload/test_results/v1",
24+
}
25+
1726

1827
def _turn_env_vars_into_dict(ctx, params, value):
1928
return dict((v, os.getenv(v, None)) for v in value)
@@ -264,6 +273,8 @@ def do_upload(
264273
ci_adapter = ctx.obj.get("ci_adapter")
265274
enterprise_url = ctx.obj.get("enterprise_url")
266275
args = get_cli_args(ctx)
276+
277+
url_paths = ctx.obj.get("url_paths", DEFAULT_URL_PATHS)
267278
logger.debug(
268279
"Starting upload processing",
269280
extra=dict(
@@ -276,6 +287,7 @@ def do_upload(
276287
cli_config,
277288
versioning_system,
278289
ci_adapter,
290+
url_paths,
279291
branch=branch,
280292
build_code=build_code,
281293
build_url=build_url,

codecov-cli/codecov_cli/services/upload/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
from codecov_cli.fallbacks import FallbackFieldEnum
88
from codecov_cli.helpers.ci_adapters.base import CIAdapterBase
99
from codecov_cli.helpers.request import log_warnings_and_errors_if_any
10-
from codecov_cli.helpers.versioning_systems import VersioningSystemInterface
1110
from codecov_cli.helpers.upload_type import ReportType
11+
from codecov_cli.helpers.versioning_systems import VersioningSystemInterface
1212
from codecov_cli.plugins import select_preparation_plugins
1313
from codecov_cli.services.upload.file_finder import select_file_finder
1414
from codecov_cli.services.upload.legacy_upload_sender import LegacyUploadSender
@@ -25,6 +25,7 @@ def do_upload_logic(
2525
cli_config: typing.Dict,
2626
versioning_system: VersioningSystemInterface,
2727
ci_adapter: CIAdapterBase,
28+
url_paths: typing.Dict,
2829
upload_coverage: bool = False,
2930
*,
3031
args: dict = None,
@@ -141,6 +142,7 @@ def do_upload_logic(
141142
token=token,
142143
env_vars=env_vars,
143144
report_code=report_code,
145+
url_paths=url_paths,
144146
report_type=report_type,
145147
name=name,
146148
branch=branch,

codecov-cli/codecov_cli/services/upload/upload_sender.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
from codecov_cli import __version__ as codecov_cli_version
1111
from codecov_cli.helpers.config import CODECOV_INGEST_URL
1212
from codecov_cli.helpers.encoder import encode_slug
13-
from codecov_cli.helpers.upload_type import ReportType
1413
from codecov_cli.helpers.request import (
1514
get_token_header,
1615
send_post_request,
1716
send_put_request,
1817
)
18+
from codecov_cli.helpers.upload_type import ReportType
1919
from codecov_cli.types import (
2020
RequestResult,
2121
UploadCollectionResult,
@@ -33,6 +33,7 @@ def send_upload_data(
3333
token: typing.Optional[str],
3434
env_vars: typing.Dict[str, str],
3535
report_code: str,
36+
url_paths: typing.Dict,
3637
report_type: ReportType = ReportType.COVERAGE,
3738
name: typing.Optional[str] = None,
3839
branch: typing.Optional[str] = None,
@@ -90,6 +91,7 @@ def send_upload_data(
9091
encoded_slug,
9192
commit_sha,
9293
report_code,
94+
url_paths,
9395
upload_coverage,
9496
)
9597
# Data that goes to storage
@@ -212,21 +214,31 @@ def get_url_and_possibly_update_data(
212214
encoded_slug,
213215
commit_sha,
214216
report_code,
217+
url_paths: typing.Dict,
215218
upload_coverage=False,
216219
file_not_found=False,
217220
):
218221
if report_type == ReportType.COVERAGE:
219-
base_url = f"{upload_url}/upload/{git_service}/{encoded_slug}"
222+
coverage_paths = url_paths[report_type]
220223
if upload_coverage:
221-
url = f"{base_url}/upload-coverage"
224+
path_template = coverage_paths["upload_coverage"]
222225
else:
223-
url = f"{base_url}/commits/{commit_sha}/reports/{report_code}/uploads"
226+
path_template = coverage_paths["uploads"]
227+
228+
url = upload_url + path_template.format(
229+
git_service=git_service,
230+
encoded_slug=encoded_slug,
231+
commit_sha=commit_sha,
232+
report_code=report_code,
233+
)
224234
elif report_type == ReportType.TEST_RESULTS:
225235
data["slug"] = encoded_slug
226236
data["branch"] = branch
227237
data["commit"] = commit_sha
228238
data["service"] = git_service
229239
data["file_not_found"] = file_not_found
230-
url = f"{upload_url}/upload/test_results/v1"
240+
241+
path_template = url_paths[report_type]
242+
url = upload_url + path_template
231243

232244
return url, data

codecov-cli/tests/helpers/test_upload_sender.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
import json
22
import re
3+
from copy import deepcopy
34
from pathlib import Path
45

5-
from copy import deepcopy
66
import pytest
77
import responses
88
from responses import matchers
99

1010
from codecov_cli import __version__ as codecov_cli_version
11+
from codecov_cli.commands.upload import DEFAULT_URL_PATHS
1112
from codecov_cli.helpers.encoder import encode_slug
13+
from codecov_cli.helpers.upload_type import ReportType
1214
from codecov_cli.services.upload.upload_sender import UploadSender
1315
from codecov_cli.types import (
1416
UploadCollectionResult,
15-
UploadCollectionResultFileFixer,
1617
UploadCollectionResultFile,
18+
UploadCollectionResultFileFixer,
1719
)
1820
from tests.data import reports_examples
19-
from codecov_cli.helpers.upload_type import ReportType
2021

2122
upload_collection = UploadCollectionResult(["1", "apple.py", "3"], [], [])
2223
random_token = "f359afb9-8a2a-42ab-a448-c3d267ff495b"
@@ -26,6 +27,7 @@
2627
"report_type": ReportType.COVERAGE,
2728
"report_code": "report_code",
2829
"env_vars": {},
30+
"url_paths": DEFAULT_URL_PATHS,
2931
"name": "name",
3032
"branch": "branch",
3133
"slug": "org/repo",
@@ -41,6 +43,7 @@
4143
"report_type": ReportType.TEST_RESULTS,
4244
"report_code": "report_code",
4345
"env_vars": {},
46+
"url_paths": DEFAULT_URL_PATHS,
4447
"name": "name",
4548
"branch": "branch",
4649
"slug": "org/repo",
@@ -351,7 +354,10 @@ def test_upload_sender_post_called_with_right_parameters_tokenless(
351354
]
352355

353356
sending_result = UploadSender().send_upload_data(
354-
upload_collection, random_sha, None, **named_upload_data
357+
upload_collection,
358+
random_sha,
359+
None,
360+
**named_upload_data,
355361
)
356362
assert sending_result.error is None
357363
assert sending_result.warnings == []
@@ -374,7 +380,10 @@ def test_upload_sender_put_called_with_right_parameters(
374380
self, mocked_responses, mocked_legacy_upload_endpoint, mocked_storage_server
375381
):
376382
sending_result = UploadSender().send_upload_data(
377-
upload_collection, random_sha, random_token, **named_upload_data
383+
upload_collection,
384+
random_sha,
385+
random_token,
386+
**named_upload_data,
378387
)
379388
assert sending_result.error is None
380389
assert sending_result.warnings == []
@@ -388,7 +397,10 @@ def test_upload_sender_result_success(
388397
self, mocked_responses, mocked_legacy_upload_endpoint, mocked_storage_server
389398
):
390399
sender = UploadSender().send_upload_data(
391-
upload_collection, random_sha, random_token, **named_upload_data
400+
upload_collection,
401+
random_sha,
402+
random_token,
403+
**named_upload_data,
392404
)
393405

394406
# default status for both put and post is 200
@@ -402,7 +414,10 @@ def test_upload_sender_result_fail_post_400(
402414
mocked_legacy_upload_endpoint.status = 400
403415

404416
sender = UploadSender().send_upload_data(
405-
upload_collection, random_sha, random_token, **named_upload_data
417+
upload_collection,
418+
random_sha,
419+
random_token,
420+
**named_upload_data,
406421
)
407422

408423
assert len(mocked_responses.calls) == 1
@@ -439,7 +454,10 @@ def test_upload_sender_result_fail_put_400(
439454
mocked_storage_server.status = 400
440455

441456
sender = UploadSender().send_upload_data(
442-
upload_collection, random_sha, random_token, **named_upload_data
457+
upload_collection,
458+
random_sha,
459+
random_token,
460+
**named_upload_data,
443461
)
444462

445463
assert len(mocked_responses.calls) == 2
@@ -455,7 +473,10 @@ def test_upload_sender_http_error_with_invalid_sha(
455473
mocked_legacy_upload_endpoint.status = 400
456474

457475
sender = UploadSender().send_upload_data(
458-
upload_collection, random_sha, random_token, **named_upload_data
476+
upload_collection,
477+
random_sha,
478+
random_token,
479+
**named_upload_data,
459480
)
460481

461482
assert sender.error is not None

codecov-cli/tests/services/upload/test_upload_service.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import pytest
33
from click.testing import CliRunner
44

5+
from codecov_cli.commands.upload import DEFAULT_URL_PATHS
56
from codecov_cli.helpers.upload_type import ReportType
67
from codecov_cli.services.upload import (
78
LegacyUploadSender,
@@ -48,6 +49,7 @@ def test_do_upload_logic_happy_path_legacy_uploader(mocker):
4849
cli_config,
4950
versioning_system,
5051
ci_adapter,
52+
DEFAULT_URL_PATHS,
5153
report_type=ReportType.COVERAGE,
5254
commit_sha="commit_sha",
5355
report_code="report_code",
@@ -116,6 +118,7 @@ def test_do_upload_logic_happy_path_legacy_uploader(mocker):
116118
token="token",
117119
env_vars=None,
118120
report_code="report_code",
121+
url_paths=DEFAULT_URL_PATHS,
119122
report_type=ReportType.COVERAGE,
120123
name="name",
121124
branch="branch",
@@ -165,6 +168,7 @@ def test_do_upload_logic_happy_path(mocker):
165168
cli_config,
166169
versioning_system,
167170
ci_adapter,
171+
DEFAULT_URL_PATHS,
168172
report_type=ReportType.COVERAGE,
169173
commit_sha="commit_sha",
170174
report_code="report_code",
@@ -231,6 +235,7 @@ def test_do_upload_logic_happy_path(mocker):
231235
token="token",
232236
env_vars=None,
233237
report_code="report_code",
238+
url_paths=DEFAULT_URL_PATHS,
234239
report_type=ReportType.COVERAGE,
235240
name="name",
236241
branch="branch",
@@ -276,6 +281,7 @@ def test_do_upload_logic_dry_run(mocker):
276281
cli_config,
277282
versioning_system,
278283
ci_adapter,
284+
DEFAULT_URL_PATHS,
279285
report_type=ReportType.COVERAGE,
280286
commit_sha="commit_sha",
281287
report_code="report_code",
@@ -362,6 +368,7 @@ def test_do_upload_logic_verbose(mocker, use_verbose_option):
362368
cli_config,
363369
versioning_system,
364370
ci_adapter,
371+
DEFAULT_URL_PATHS,
365372
branch="branch",
366373
build_code="build_code",
367374
build_url="build_url",
@@ -444,6 +451,7 @@ def side_effect(*args, **kwargs):
444451
cli_config,
445452
versioning_system,
446453
ci_adapter,
454+
DEFAULT_URL_PATHS,
447455
report_type=ReportType.COVERAGE,
448456
commit_sha="commit_sha",
449457
report_code="report_code",
@@ -550,6 +558,7 @@ def side_effect(*args, **kwargs):
550558
cli_config,
551559
versioning_system,
552560
ci_adapter,
561+
DEFAULT_URL_PATHS,
553562
report_type=ReportType.COVERAGE,
554563
commit_sha="commit_sha",
555564
report_code="report_code",
@@ -640,6 +649,7 @@ def test_do_upload_logic_happy_path_test_results(mocker):
640649
cli_config,
641650
versioning_system,
642651
ci_adapter,
652+
url_paths={ReportType.TEST_RESULTS: "upload/test_results/v1"},
643653
args={"args": "fake_args"},
644654
branch="branch",
645655
build_code="build_code",
@@ -694,6 +704,7 @@ def test_do_upload_logic_happy_path_test_results(mocker):
694704
commit_sha="commit_sha",
695705
token="token",
696706
env_vars=None,
707+
url_paths={ReportType.TEST_RESULTS: "upload/test_results/v1"},
697708
report_code="report_code",
698709
report_type=ReportType.TEST_RESULTS,
699710
name="name",

prevent-cli/src/prevent_cli/main.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
from codecov_cli.commands.process_test_results import process_test_results
1515
from codecov_cli.commands.report import create_report
1616
from codecov_cli.commands.send_notifications import send_notifications
17-
from codecov_cli.commands.upload import do_upload
17+
from codecov_cli.commands.upload import DEFAULT_URL_PATHS, do_upload
1818
from codecov_cli.commands.upload_coverage import upload_coverage
1919
from codecov_cli.commands.upload_process import upload_process
2020
from codecov_cli.helpers.ci_adapters import get_ci_adapter, get_ci_providers_list
2121
from codecov_cli.helpers.config import load_cli_config
2222
from codecov_cli.helpers.logging_utils import configure_logger
23+
from codecov_cli.helpers.upload_type import ReportType
2324
from codecov_cli.helpers.versioning_systems import get_versioning_system
2425
from codecov_cli.opentelemetry import init_telem
2526

@@ -83,6 +84,10 @@ def cli(
8384
ctx.obj["disable_telem"] = disable_telem
8485
ctx.obj["branding"] = branding
8586

87+
custom_url_paths = deepcopy(DEFAULT_URL_PATHS)
88+
custom_url_paths[ReportType.TEST_RESULTS] = "/upload/test_analytics/v1"
89+
ctx.obj["url_paths"] = custom_url_paths
90+
8691
init_telem(ctx.obj)
8792

8893

@@ -100,18 +105,18 @@ def cli(
100105
break
101106

102107

103-
cli.add_command(do_upload)
104-
cli.add_command(create_commit)
105-
cli.add_command(create_report)
106108
cli.add_command(pr_base_picking)
107109
cli.add_command(empty_upload)
108-
cli.add_command(upload_coverage)
109110
cli.add_command(upload)
110-
cli.add_command(upload_process)
111111
cli.add_command(send_notifications)
112-
cli.add_command(process_test_results)
113112

114113
# deprecated commands:
114+
cli.add_command(do_upload)
115+
cli.add_command(create_commit)
116+
cli.add_command(create_report)
117+
cli.add_command(upload_coverage)
118+
cli.add_command(upload_process)
119+
cli.add_command(process_test_results)
115120
cli.add_command(create_report_results)
116121
cli.add_command(get_report_results)
117122

0 commit comments

Comments
 (0)