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

Commit d58c40e

Browse files
committed
Initial commit
1 parent e8a5caf commit d58c40e

File tree

4 files changed

+215
-73
lines changed

4 files changed

+215
-73
lines changed

upload/views/combined_upload.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import logging
2+
3+
from rest_framework import status
4+
from rest_framework.generics import ListCreateAPIView
5+
from rest_framework.response import Response
6+
7+
from codecov_auth.authentication.repo_auth import (
8+
GitHubOIDCTokenAuthentication,
9+
GlobalTokenAuthentication,
10+
OrgLevelTokenAuthentication,
11+
RepositoryLegacyTokenAuthentication,
12+
TokenlessAuthentication,
13+
UploadTokenRequiredAuthenticationCheck,
14+
repo_auth_custom_exception_handler,
15+
)
16+
from upload.serializers import (
17+
CommitReportSerializer,
18+
CommitSerializer,
19+
UploadSerializer,
20+
)
21+
from upload.throttles import UploadsPerCommitThrottle, UploadsPerWindowThrottle
22+
from upload.views.commits import CommitLogicMixin
23+
from upload.views.reports import ReportLogicMixin
24+
from upload.views.uploads import CanDoCoverageUploadsPermission, UploadLogicMixin
25+
26+
log = logging.getLogger(__name__)
27+
28+
29+
class CombinedUploadMixin(CommitLogicMixin, ReportLogicMixin, UploadLogicMixin):
30+
pass
31+
32+
33+
class CombinedUploadView(ListCreateAPIView, CombinedUploadMixin):
34+
permission_classes = [CanDoCoverageUploadsPermission]
35+
authentication_classes = [
36+
UploadTokenRequiredAuthenticationCheck,
37+
GlobalTokenAuthentication,
38+
OrgLevelTokenAuthentication,
39+
GitHubOIDCTokenAuthentication,
40+
RepositoryLegacyTokenAuthentication,
41+
TokenlessAuthentication,
42+
]
43+
throttle_classes = [UploadsPerCommitThrottle, UploadsPerWindowThrottle]
44+
45+
def get_exception_handler(self):
46+
return repo_auth_custom_exception_handler
47+
48+
def create(self, request, *args, **kwargs):
49+
# Create commit
50+
create_commit_data = dict(
51+
branch=request.data.get("branch"),
52+
commit_sha=request.data.get("commit_sha"),
53+
fail_on_error=True,
54+
git_service=request.data.get("git_service"),
55+
parent_sha=request.data.get("parent_sha"),
56+
pull_request_number=request.data.get("pull_request_number"),
57+
slug=request.data.get("slug"),
58+
token=request.data.get("token"),
59+
)
60+
commit_serializer = CommitSerializer(data=create_commit_data)
61+
commit_serializer.is_valid(raise_exception=True)
62+
63+
repository = self.get_repo()
64+
commit = self.create_commit(commit_serializer, repository)
65+
66+
# Create report
67+
commit_report_data = dict(
68+
code=request.data.get("code"),
69+
commit_sha=request.data.get("commit_sha"),
70+
fail_on_error=True,
71+
git_service=request.data.get("git_service"),
72+
slug=request.data.get("slug"),
73+
token=request.data.get("token"),
74+
)
75+
commit_report_serializer = CommitReportSerializer(data=commit_report_data)
76+
report = self.create_report(commit_report_serializer, repository, commit)
77+
78+
# Do upload
79+
upload_data = dict(
80+
branch=request.data.get("branch"),
81+
build_code=request.data.get("build_code"),
82+
build_url=request.data.get("build_url"),
83+
commit_sha=request.data.get("commit_sha"),
84+
disable_file_fixes=request.data.get("disable_file_fixes"),
85+
disable_search=request.data.get("disable_search"),
86+
dry_run=request.data.get("dry_run"),
87+
env_vars=request.data.get("env_vars"),
88+
fail_on_error=request.data.get("fail_on_error"),
89+
files_search_exclude_folders=request.data.get(
90+
"files_search_exclude_folders"
91+
),
92+
files_search_explicitly_listed_files=request.data.get(
93+
"files_search_explicitly_listed_files"
94+
),
95+
files_search_root_folder=request.data.get("files_search_root_folder"),
96+
flags=request.data.get("flags"),
97+
gcov_args=request.data.get("gcov_args"),
98+
gcov_executable=request.data.get("gcov_executable"),
99+
gcov_ignore=request.data.get("gcov_ignore"),
100+
gcov_include=request.data.get("gcov_include"),
101+
git_service=request.data.get("git_service"),
102+
handle_no_reports_found=request.data.get("handle_no_reports_found"),
103+
job_code=request.data.get("job_code"),
104+
name=request.data.get("name"),
105+
network_filter=request.data.get("network_filter"),
106+
network_prefix=request.data.get("network_prefix"),
107+
network_root_folder=request.data.get("network_root_folder"),
108+
plugin_names=request.data.get("plugin_names"),
109+
pull_request_number=request.data.get("pull_request_number"),
110+
report_code=report.code,
111+
report_type=request.data.get("report_type"),
112+
slug=request.data.get("slug"),
113+
swift_project=request.data.get("swift_project"),
114+
token=request.data.get("token"),
115+
use_legacy_uploader=request.data.get("use_legacy_uploader"),
116+
)
117+
upload_serializer = UploadSerializer(data=upload_data)
118+
upload_serializer.is_valid(raise_exception=True)
119+
120+
instance = self.create_upload(upload_serializer, repository, commit, report)
121+
if instance:
122+
return Response(data=instance.data, status=status.HTTP_201_CREATED)
123+
else:
124+
return Response(
125+
upload_serializer.errors, status=status.HTTP_400_BAD_REQUEST
126+
)

upload/views/commits.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,14 @@
2626
log = logging.getLogger(__name__)
2727

2828

29-
class CommitViews(ListCreateAPIView, GetterMixin):
29+
class CommitLogicMixin(GetterMixin):
30+
def create_commit(self, serializer, repository):
31+
validate_activated_repo(repository)
32+
commit = serializer.save(repository=repository)
33+
return commit
34+
35+
36+
class CommitViews(ListCreateAPIView, CommitLogicMixin):
3037
serializer_class = CommitSerializer
3138
permission_classes = [CanDoCoverageUploadsPermission]
3239
authentication_classes = [
@@ -68,9 +75,7 @@ def perform_create(self, serializer):
6875
),
6976
)
7077
repository = self.get_repo()
71-
validate_activated_repo(repository)
72-
73-
commit = serializer.save(repository=repository)
78+
commit = self.create_commit(serializer, repository)
7479

7580
log.info(
7681
"Request to create new commit",

upload/views/reports.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from services.task import TaskService
1919
from upload.helpers import (
2020
generate_upload_prometheus_metrics_labels,
21-
validate_activated_repo,
2221
)
2322
from upload.metrics import API_UPLOAD_COUNTER
2423
from upload.serializers import CommitReportSerializer, ReportResultsSerializer
@@ -28,7 +27,23 @@
2827
log = logging.getLogger(__name__)
2928

3029

31-
class ReportViews(ListCreateAPIView, GetterMixin):
30+
class ReportLogicMixin(GetterMixin):
31+
def create_report(self, serializer, repository, commit):
32+
code = serializer.validated_data.get("code")
33+
if code == "default":
34+
serializer.validated_data["code"] = None
35+
instance, was_created = serializer.save(
36+
commit_id=commit.id,
37+
report_type=CommitReport.ReportType.COVERAGE,
38+
)
39+
if was_created:
40+
TaskService().preprocess_upload(
41+
repository.repoid, commit.commitid, instance.code
42+
)
43+
return instance
44+
45+
46+
class ReportViews(ListCreateAPIView, ReportLogicMixin):
3247
serializer_class = CommitReportSerializer
3348
permission_classes = [CanDoCoverageUploadsPermission]
3449
authentication_classes = [
@@ -55,23 +70,12 @@ def perform_create(self, serializer):
5570
),
5671
)
5772
repository = self.get_repo()
58-
validate_activated_repo(repository)
5973
commit = self.get_commit(repository)
6074
log.info(
6175
"Request to create new report",
6276
extra=dict(repo=repository.name, commit=commit.commitid),
6377
)
64-
code = serializer.validated_data.get("code")
65-
if code == "default":
66-
serializer.validated_data["code"] = None
67-
instance, was_created = serializer.save(
68-
commit_id=commit.id,
69-
report_type=CommitReport.ReportType.COVERAGE,
70-
)
71-
if was_created:
72-
TaskService().preprocess_upload(
73-
repository.repoid, commit.commitid, instance.code
74-
)
78+
instance = self.create_report(serializer, repository, commit)
7579

7680
inc_counter(
7781
API_UPLOAD_COUNTER,

upload/views/uploads.py

Lines changed: 62 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -49,40 +49,8 @@ def has_permission(self, request, view):
4949
)
5050

5151

52-
class UploadViews(ListCreateAPIView, GetterMixin):
53-
serializer_class = UploadSerializer
54-
permission_classes = [
55-
CanDoCoverageUploadsPermission,
56-
]
57-
authentication_classes = [
58-
UploadTokenRequiredAuthenticationCheck,
59-
GlobalTokenAuthentication,
60-
OrgLevelTokenAuthentication,
61-
GitHubOIDCTokenAuthentication,
62-
RepositoryLegacyTokenAuthentication,
63-
TokenlessAuthentication,
64-
]
65-
throttle_classes = [UploadsPerCommitThrottle, UploadsPerWindowThrottle]
66-
67-
def get_exception_handler(self):
68-
return repo_auth_custom_exception_handler
69-
70-
def perform_create(self, serializer: UploadSerializer):
71-
inc_counter(
72-
API_UPLOAD_COUNTER,
73-
labels=generate_upload_prometheus_metrics_labels(
74-
action="coverage",
75-
endpoint="create_upload",
76-
request=self.request,
77-
is_shelter_request=self.is_shelter_request(),
78-
position="start",
79-
),
80-
)
81-
repository: Repository = self.get_repo()
82-
validate_activated_repo(repository)
83-
commit: Commit = self.get_commit(repository)
84-
report: CommitReport = self.get_report(commit)
85-
52+
class UploadLogicMixin(GetterMixin):
53+
def create_upload(self, serializer, repository, commit, report):
8654
version = (
8755
serializer.validated_data["version"]
8856
if "version" in serializer.validated_data
@@ -127,31 +95,10 @@ def perform_create(self, serializer: UploadSerializer):
12795
instance.storage_path = path
12896
instance.save()
12997
self.trigger_upload_task(repository, commit.commitid, instance, report)
130-
inc_counter(
131-
API_UPLOAD_COUNTER,
132-
labels=generate_upload_prometheus_metrics_labels(
133-
action="coverage",
134-
endpoint="create_upload",
135-
request=self.request,
136-
repository=repository,
137-
is_shelter_request=self.is_shelter_request(),
138-
position="end",
139-
),
140-
)
14198
self.activate_repo(repository)
14299
self.send_analytics_data(commit, instance, version)
143100
return instance
144101

145-
def list(
146-
self,
147-
request: HttpRequest,
148-
service: str,
149-
repo: str,
150-
commit_sha: str,
151-
report_code: str,
152-
):
153-
return HttpResponseNotAllowed(permitted_methods=["POST"])
154-
155102
def trigger_upload_task(self, repository, commit_sha, upload, report):
156103
log.info(
157104
"Triggering upload task",
@@ -234,6 +181,66 @@ def get_token_for_analytics(self, commit: Commit):
234181
token = repo.upload_token
235182
return token
236183

184+
185+
class UploadViews(ListCreateAPIView, UploadLogicMixin):
186+
serializer_class = UploadSerializer
187+
permission_classes = [
188+
CanDoCoverageUploadsPermission,
189+
]
190+
authentication_classes = [
191+
UploadTokenRequiredAuthenticationCheck,
192+
GlobalTokenAuthentication,
193+
OrgLevelTokenAuthentication,
194+
GitHubOIDCTokenAuthentication,
195+
RepositoryLegacyTokenAuthentication,
196+
TokenlessAuthentication,
197+
]
198+
throttle_classes = [UploadsPerCommitThrottle, UploadsPerWindowThrottle]
199+
200+
def get_exception_handler(self):
201+
return repo_auth_custom_exception_handler
202+
203+
def perform_create(self, serializer: UploadSerializer):
204+
inc_counter(
205+
API_UPLOAD_COUNTER,
206+
labels=generate_upload_prometheus_metrics_labels(
207+
action="coverage",
208+
endpoint="create_upload",
209+
request=self.request,
210+
is_shelter_request=self.is_shelter_request(),
211+
position="start",
212+
),
213+
)
214+
repository: Repository = self.get_repo()
215+
validate_activated_repo(repository)
216+
commit: Commit = self.get_commit(repository)
217+
report: CommitReport = self.get_report(commit)
218+
219+
instance = self.create_upload(serializer, repository, commit, report)
220+
inc_counter(
221+
API_UPLOAD_COUNTER,
222+
labels=generate_upload_prometheus_metrics_labels(
223+
action="coverage",
224+
endpoint="create_upload",
225+
request=self.request,
226+
repository=repository,
227+
is_shelter_request=self.is_shelter_request(),
228+
position="end",
229+
),
230+
)
231+
232+
return instance
233+
234+
def list(
235+
self,
236+
request: HttpRequest,
237+
service: str,
238+
repo: str,
239+
commit_sha: str,
240+
report_code: str,
241+
):
242+
return HttpResponseNotAllowed(permitted_methods=["POST"])
243+
237244
def get_repo(self) -> Repository:
238245
try:
239246
repo = super().get_repo()

0 commit comments

Comments
 (0)