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

Commit 0956577

Browse files
committed
Bundle Analysis: Add mutation for toggling bundle caching configuration
1 parent d501c77 commit 0956577

File tree

9 files changed

+155
-1
lines changed

9 files changed

+155
-1
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from typing import Dict, List
2+
3+
from shared.django_apps.bundle_analysis.models import CacheConfig
4+
5+
from codecov.commands.base import BaseInteractor
6+
from codecov.commands.exceptions import ValidationError
7+
from codecov.db import sync_to_async
8+
from codecov_auth.models import Owner
9+
from core.models import Repository
10+
11+
12+
class UploadBundleConfigInteractor(BaseInteractor):
13+
def validate(
14+
self, repo: Repository, cache_config: List[Dict[str, str | bool]]
15+
) -> None:
16+
if not repo:
17+
raise ValidationError("Repo not found")
18+
19+
# Find any missing bundle names
20+
bundle_names = [
21+
bundle["bundle_name"]
22+
for bundle in cache_config
23+
# the value of bundle_name is always a string, just do this check to appease mypy
24+
if isinstance(bundle["bundle_name"], str)
25+
]
26+
existing_bundle_names = set(
27+
CacheConfig.objects.filter(
28+
repo_id=repo.pk, bundle_name__in=bundle_names
29+
).values_list("bundle_name", flat=True)
30+
)
31+
missing_bundles = set(bundle_names) - existing_bundle_names
32+
if missing_bundles:
33+
raise ValidationError(
34+
f"The following bundle names do not exist: {', '.join(missing_bundles)}"
35+
)
36+
37+
@sync_to_async
38+
def execute(
39+
self,
40+
owner_username: str,
41+
repo_name: str,
42+
cache_config: List[Dict[str, str | bool]],
43+
) -> List[Dict[str, str | bool]]:
44+
author = Owner.objects.filter(
45+
username=owner_username, service=self.service
46+
).first()
47+
repo = (
48+
Repository.objects.viewable_repos(self.current_owner)
49+
.filter(author=author, name=repo_name)
50+
.first()
51+
)
52+
53+
self.validate(repo, cache_config)
54+
55+
results = []
56+
for bundle in cache_config:
57+
bundle_name = bundle["bundle_name"]
58+
is_caching = bundle["toggle_caching"]
59+
CacheConfig.objects.filter(repo_id=repo.pk, bundle_name=bundle_name).update(
60+
is_caching=is_caching
61+
)
62+
results.append(
63+
{
64+
"bundle_name": bundle_name,
65+
"is_cached": is_caching,
66+
}
67+
)
68+
return results

core/commands/repository/repository.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import uuid
2-
from typing import Awaitable, Optional
2+
from typing import Awaitable, Dict, List, Optional
33

44
from codecov.commands.base import BaseCommand
55
from codecov_auth.models import Owner, RepositoryToken
@@ -16,6 +16,7 @@
1616
from .interactors.regenerate_repository_upload_token import (
1717
RegenerateRepositoryUploadTokenInteractor,
1818
)
19+
from .interactors.update_bundle_config import UploadBundleConfigInteractor
1920
from .interactors.update_repository import UpdateRepositoryInteractor
2021

2122

@@ -85,3 +86,13 @@ def encode_secret_string(self, owner: Owner, repo_name: str, value: str) -> str:
8586
return self.get_interactor(EncodeSecretStringInteractor).execute(
8687
owner, repo_name, value
8788
)
89+
90+
def update_bundle_caching(
91+
self,
92+
owner_username: str,
93+
repo_name: str,
94+
cache_config: List[Dict[str, str | bool]],
95+
) -> Awaitable[List[Dict[str, str | bool]]]:
96+
return self.get_interactor(UploadBundleConfigInteractor).execute(
97+
owner_username, repo_name, cache_config
98+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
input BundleCachingInput {
2+
bundleName: String!
3+
toggleCaching: Boolean!
4+
}
5+
6+
input UpdateBundleCachingInput {
7+
owner: String!
8+
repoName: String!
9+
bundles: [BundleCachingInput!]!
10+
}

graphql_api/types/mutation/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from .start_trial import gql_start_trial
2424
from .store_event_metrics import gql_store_event_metrics
2525
from .sync_with_git_provider import gql_sync_with_git_provider
26+
from .update_bundle_caching import gql_update_bundle_caching
2627
from .update_default_organization import gql_update_default_organization
2728
from .update_profile import gql_update_profile
2829
from .update_repository import gql_update_repository
@@ -55,3 +56,4 @@
5556
mutation = mutation + gql_store_event_metrics
5657
mutation = mutation + gql_save_okta_config
5758
mutation = mutation + gql_set_upload_token_required
59+
mutation = mutation + gql_update_bundle_caching

graphql_api/types/mutation/mutation.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ type Mutation {
3939
storeEventMetric(input: StoreEventMetricsInput!): StoreEventMetricsPayload
4040
saveOktaConfig(input: SaveOktaConfigInput!): SaveOktaConfigPayload
4141
setUploadTokenRequired(input: SetUploadTokenRequiredInput!): SetUploadTokenRequiredPayload
42+
updateBundleCaching(input: UpdateBundleCachingInput!): UpdateBundleCachingPayload
4243
}

graphql_api/types/mutation/mutation.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@
4949
error_sync_with_git_provider,
5050
resolve_sync_with_git_provider,
5151
)
52+
from .update_bundle_caching import (
53+
error_update_bundle_caching,
54+
resolve_update_bundle_caching,
55+
)
5256
from .update_default_organization import (
5357
error_update_default_organization,
5458
resolve_update_default_organization,
@@ -99,6 +103,7 @@
99103

100104
mutation_bindable.field("saveOktaConfig")(resolve_save_okta_config)
101105
mutation_bindable.field("setUploadTokenRequired")(resolve_set_upload_token_required)
106+
mutation_bindable.field("updateBundleCaching")(resolve_update_bundle_caching)
102107

103108
mutation_resolvers = [
104109
mutation_bindable,
@@ -128,4 +133,5 @@
128133
error_store_event_metrics,
129134
error_save_okta_config,
130135
error_set_upload_token_required,
136+
error_update_bundle_caching,
131137
]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from graphql_api.helpers.ariadne import ariadne_load_local_graphql
2+
3+
from .update_bundle_caching import (
4+
error_update_bundle_caching,
5+
resolve_update_bundle_caching,
6+
)
7+
8+
gql_update_bundle_caching = ariadne_load_local_graphql(
9+
__file__, "update_bundle_caching.graphql"
10+
)
11+
12+
__all__ = [
13+
"error_update_bundle_caching",
14+
"resolve_update_bundle_caching",
15+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
union UpdateBundleCachingError = UnauthenticatedError | ValidationError
2+
3+
type UpdateBundleCachingResult {
4+
bundleName: String
5+
isCached: Boolean
6+
}
7+
8+
type UpdateBundleCachingPayload {
9+
results: [UpdateBundleCachingResult!]
10+
error: UpdateBundleCachingError
11+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from typing import Any, Dict, List
2+
3+
from ariadne import UnionType
4+
from graphql import GraphQLResolveInfo
5+
6+
from core.commands.repository.repository import RepositoryCommands
7+
from graphql_api.helpers.mutation import (
8+
require_authenticated,
9+
resolve_union_error_type,
10+
wrap_error_handling_mutation,
11+
)
12+
13+
14+
@wrap_error_handling_mutation
15+
@require_authenticated
16+
async def resolve_update_bundle_caching(
17+
_: Any, info: GraphQLResolveInfo, input: Dict[str, Any]
18+
) -> Dict[str, List[Dict[str, str | bool]]]:
19+
command: RepositoryCommands = info.context["executor"].get_command("repository")
20+
21+
results = await command.update_bundle_caching(
22+
repo_name=input.get("repo_name", ""),
23+
owner_username=input.get("owner", ""),
24+
cache_config=input.get("bundles", []),
25+
)
26+
return {"results": results}
27+
28+
29+
error_update_bundle_caching = UnionType("UpdateBundleCachingError")
30+
error_update_bundle_caching.type_resolver(resolve_union_error_type)

0 commit comments

Comments
 (0)