Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.

Commit e76d9b9

Browse files
authored
Merge pull request #146 from codecov/dana/empty-upload
create empty-upload command
2 parents ec1c3ef + f829528 commit e76d9b9

File tree

5 files changed

+181
-0
lines changed

5 files changed

+181
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import logging
2+
import typing
3+
import uuid
4+
5+
import click
6+
7+
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
8+
from codecov_cli.helpers.git import GitService
9+
from codecov_cli.services.empty_upload import empty_upload_logic
10+
11+
logger = logging.getLogger("codecovcli")
12+
13+
14+
@click.command()
15+
@click.option(
16+
"-C",
17+
"--sha",
18+
"--commit-sha",
19+
"commit_sha",
20+
help="Commit SHA (with 40 chars)",
21+
cls=CodecovOption,
22+
fallback_field=FallbackFieldEnum.commit_sha,
23+
required=True,
24+
)
25+
@click.option(
26+
"-r",
27+
"--slug",
28+
"slug",
29+
cls=CodecovOption,
30+
fallback_field=FallbackFieldEnum.slug,
31+
help="owner/repo slug used instead of the private repo token in Self-hosted",
32+
envvar="CODECOV_SLUG",
33+
)
34+
@click.option(
35+
"-t",
36+
"--token",
37+
help="Codecov upload token",
38+
type=click.UUID,
39+
envvar="CODECOV_TOKEN",
40+
)
41+
@click.option(
42+
"--git-service",
43+
cls=CodecovOption,
44+
fallback_field=FallbackFieldEnum.git_service,
45+
type=click.Choice(service.value for service in GitService),
46+
)
47+
@click.pass_context
48+
def empty_upload(
49+
ctx,
50+
commit_sha: str,
51+
slug: typing.Optional[str],
52+
token: typing.Optional[uuid.UUID],
53+
git_service: typing.Optional[str],
54+
):
55+
logger.debug(
56+
"Starting empty upload process",
57+
extra=dict(
58+
extra_log_attributes=dict(
59+
commit_sha=commit_sha,
60+
slug=slug,
61+
token=token,
62+
service=git_service,
63+
)
64+
),
65+
)
66+
return empty_upload_logic(commit_sha, slug, token, git_service)

codecov_cli/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from codecov_cli.commands.base_picking import pr_base_picking
88
from codecov_cli.commands.commit import create_commit
99
from codecov_cli.commands.create_report_result import create_report_results
10+
from codecov_cli.commands.empty_upload import empty_upload
1011
from codecov_cli.commands.get_report_results import get_report_results
1112
from codecov_cli.commands.labelanalysis import label_analysis
1213
from codecov_cli.commands.report import create_report
@@ -61,6 +62,7 @@ def cli(
6162
cli.add_command(pr_base_picking)
6263
cli.add_command(label_analysis)
6364
cli.add_command(static_analysis)
65+
cli.add_command(empty_upload)
6466

6567

6668
def run():
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import logging
2+
3+
from codecov_cli.helpers.encoder import encode_slug
4+
from codecov_cli.helpers.request import (
5+
get_token_header_or_fail,
6+
log_warnings_and_errors_if_any,
7+
send_post_request,
8+
)
9+
10+
logger = logging.getLogger("codecovcli")
11+
12+
13+
def empty_upload_logic(commit_sha, slug, token, git_service):
14+
encoded_slug = encode_slug(slug)
15+
headers = get_token_header_or_fail(token)
16+
url = f"https://api.codecov.io/upload/{git_service}/{encoded_slug}/commits/{commit_sha}/empty-upload"
17+
sending_result = send_post_request(url=url, headers=headers)
18+
if sending_result.status_code < 300 and sending_result.text:
19+
logger.info(sending_result.text)
20+
log_warnings_and_errors_if_any(sending_result, "Empty Upload")
21+
return sending_result
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import uuid
2+
3+
from click.testing import CliRunner
4+
5+
from codecov_cli.services.empty_upload import empty_upload_logic
6+
from codecov_cli.types import RequestError, RequestResult, RequestResultWarning
7+
from tests.test_helpers import parse_outstreams_into_log_lines
8+
9+
10+
def test_empty_upload_with_warnings(mocker):
11+
mock_send_commit_data = mocker.patch(
12+
"codecov_cli.services.empty_upload.send_post_request",
13+
return_value=RequestResult(
14+
error=None,
15+
warnings=[RequestResultWarning(message="somewarningmessage")],
16+
status_code=201,
17+
text="",
18+
),
19+
)
20+
runner = CliRunner()
21+
with runner.isolation() as outstreams:
22+
res = empty_upload_logic(
23+
"commit_sha",
24+
"owner/repo",
25+
uuid.uuid4(),
26+
"service",
27+
)
28+
out_bytes = parse_outstreams_into_log_lines(outstreams[0].getvalue())
29+
assert out_bytes == [
30+
("info", "Empty Upload process had 1 warning"),
31+
("warning", "Warning 1: somewarningmessage"),
32+
]
33+
assert res == mock_send_commit_data.return_value
34+
mock_send_commit_data.assert_called_once()
35+
36+
37+
def test_empty_upload_with_error(mocker):
38+
mock_send_commit_data = mocker.patch(
39+
"codecov_cli.services.empty_upload.send_post_request",
40+
return_value=RequestResult(
41+
error=RequestError(
42+
code="HTTP Error 403",
43+
description="Permission denied",
44+
params={},
45+
),
46+
warnings=[],
47+
status_code=403,
48+
text="Permission denied",
49+
),
50+
)
51+
runner = CliRunner()
52+
with runner.isolation() as outstreams:
53+
res = empty_upload_logic(
54+
"commit_sha",
55+
"owner/repo",
56+
uuid.uuid4(),
57+
"service",
58+
)
59+
60+
print(outstreams)
61+
out_bytes = parse_outstreams_into_log_lines(outstreams[0].getvalue())
62+
assert out_bytes == [("error", "Empty Upload failed: Permission denied")]
63+
assert res == mock_send_commit_data.return_value
64+
mock_send_commit_data.assert_called_once()
65+
66+
67+
def test_empty_upload_200(mocker):
68+
mocked_response = mocker.patch(
69+
"codecov_cli.helpers.request.requests.post",
70+
return_value=mocker.MagicMock(status_code=200),
71+
)
72+
token = uuid.uuid4()
73+
res = empty_upload_logic("commit_sha", "owner/repo", token, "service")
74+
assert res.error is None
75+
assert res.warnings == []
76+
mocked_response.assert_called_once()
77+
78+
79+
def test_empty_upload_403(mocker):
80+
mocked_response = mocker.patch(
81+
"codecov_cli.helpers.request.requests.post",
82+
return_value=mocker.MagicMock(status_code=403, text="Permission denied"),
83+
)
84+
token = uuid.uuid4()
85+
res = empty_upload_logic("commit_sha", "owner/repo", token, "service")
86+
assert res.error == RequestError(
87+
code="HTTP Error 403",
88+
description="Permission denied",
89+
params={},
90+
)
91+
mocked_response.assert_called_once()

tests/test_codecov_cli.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def test_existing_commands():
1111
"create-report",
1212
"create-report-results",
1313
"do-upload",
14+
"empty-upload",
1415
"get-report-results",
1516
"label-analysis",
1617
"pr-base-picking",

0 commit comments

Comments
 (0)