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

Commit d97d446

Browse files
authored
Merge branch 'main' into attempt-2
2 parents 68fd0d0 + 18eb985 commit d97d446

File tree

15 files changed

+643
-85
lines changed

15 files changed

+643
-85
lines changed

codecov/settings_base.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from sentry_sdk.integrations.redis import RedisIntegration
99
from sentry_sdk.scrubber import DEFAULT_DENYLIST, EventScrubber
1010
from shared.django_apps.db_settings import *
11+
from shared.helpers.redis import get_redis_url
1112
from shared.license import startup_license_logging
1213

1314
from utils.config import SettingsModule, get_config, get_settings_module
@@ -265,10 +266,26 @@
265266
COOKIE_SAME_SITE = "Lax"
266267
COOKIE_SECRET = get_config("setup", "http", "cookie_secret")
267268
COOKIES_DOMAIN = get_config("setup", "http", "cookies_domain", default=".codecov.io")
269+
270+
271+
# Cache configuration
272+
CACHES = {
273+
"default": {
274+
"BACKEND": "django.core.cache.backends.redis.RedisCache",
275+
"LOCATION": get_redis_url(),
276+
}
277+
}
278+
279+
280+
# Session configuration
268281
SESSION_COOKIE_DOMAIN = get_config(
269282
"setup", "http", "cookies_domain", default=".codecov.io"
270283
)
271284
SESSION_COOKIE_SECURE = get_config("setup", "secure_cookie", default=True)
285+
286+
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
287+
288+
272289
# Defaulting to 'not found' as opposed to 'None' to avoid None somehow getting through as a bearer token. Token strings can't have spaces, hence 'not found' can never be forced as a header input value
273290
SUPER_API_TOKEN = os.getenv("SUPER_API_TOKEN", "not found")
274291
CODECOV_INTERNAL_TOKEN = os.getenv("CODECOV_INTERNAL_TOKEN", "not found")

codecov_auth/admin.py

Lines changed: 93 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -568,15 +568,13 @@ class OwnerAdmin(AdminMixin, admin.ModelAdmin):
568568
"username",
569569
"service",
570570
"email",
571-
"business_email",
572571
"name",
573572
"service_id",
574573
"createstamp",
575574
"parent_service_id",
576575
"root_parent_service_id",
577576
"private_access",
578577
"cache",
579-
"free",
580578
"invoice_details",
581579
"yaml",
582580
"updatestamp",
@@ -586,28 +584,87 @@ class OwnerAdmin(AdminMixin, admin.ModelAdmin):
586584
"student_updated_at",
587585
"user",
588586
"trial_fired_by",
587+
"sentry_user_id",
589588
)
590589

591-
fields = readonly_fields + (
592-
"admins",
593-
"plan_auto_activate",
594-
"onboarding_completed",
595-
"staff",
596-
"plan",
597-
"plan_provider",
598-
"plan_user_count",
599-
"plan_activated_users",
600-
"uses_invoice",
601-
"delinquent",
602-
"integration_id",
603-
"bot",
604-
"stripe_customer_id",
605-
"stripe_subscription_id",
606-
"organizations",
607-
"max_upload_limit",
608-
"account",
609-
"upload_token_required_for_public_repos",
610-
)
590+
fieldsets = [
591+
(
592+
None,
593+
{
594+
"fields": [
595+
"ownerid",
596+
"username",
597+
"service",
598+
"name",
599+
"service_id",
600+
"student",
601+
"user",
602+
"sentry_user_id",
603+
]
604+
},
605+
),
606+
(
607+
"Trial fields",
608+
{
609+
"fields": [
610+
"trial_status",
611+
"trial_fired_by",
612+
"trial_start_date",
613+
"trial_end_date",
614+
]
615+
},
616+
),
617+
(
618+
"Plan fields",
619+
{
620+
"fields": [
621+
"plan_auto_activate",
622+
"plan",
623+
"plan_user_count",
624+
"free",
625+
"plan_activated_users",
626+
]
627+
},
628+
),
629+
(
630+
"Billing fields",
631+
{
632+
"fields": [
633+
"uses_invoice",
634+
"delinquent",
635+
"stripe_customer_id",
636+
"stripe_subscription_id",
637+
]
638+
},
639+
),
640+
(
641+
"Reference fields",
642+
{
643+
"fields": [
644+
"admins",
645+
"staff",
646+
"upload_token_required_for_public_repos",
647+
"email",
648+
"parent_service_id",
649+
"root_parent_service_id",
650+
"private_access",
651+
"cache",
652+
"yaml",
653+
"bot",
654+
"max_upload_limit",
655+
"organizations",
656+
"account",
657+
"permission",
658+
"student_created_at",
659+
"student_updated_at",
660+
"onboarding_completed",
661+
"did_trial",
662+
"createstamp",
663+
"updatestamp",
664+
]
665+
},
666+
),
667+
]
611668

612669
def get_form(self, request, obj=None, change=False, **kwargs):
613670
form = super().get_form(request, obj, change, **kwargs)
@@ -629,6 +686,16 @@ def get_form(self, request, obj=None, change=False, **kwargs):
629686
field.widget.can_change_related = False
630687
field.widget.can_delete_related = False
631688

689+
# workaround for when a model field has null=True without blank=True
690+
for field_name in [
691+
"trial_start_date",
692+
"trial_end_date",
693+
"trial_status",
694+
"free",
695+
]:
696+
if form.base_fields.get(field_name):
697+
form.base_fields[field_name].required = False
698+
632699
return form
633700

634701
def has_add_permission(self, _, obj=None):
@@ -649,11 +716,11 @@ def get_deleted_objects(self, objs, request):
649716

650717
def save_related(self, request: HttpRequest, form, formsets, change: bool) -> None:
651718
if formsets:
652-
token_formset = formsets[0]
653-
token_id = token_formset.data.get("organization_tokens-0-id")
654-
token_refresh = token_formset.data.get("organization_tokens-0-REFRESH")
719+
formset = formsets[0]
720+
token_id = formset.data.get("organization_tokens-0-id")
721+
token_refresh = formset.data.get("organization_tokens-0-REFRESH")
655722
# token_id only exists if the token already exists (edit operation)
656-
if token_formset.is_valid() and token_id and token_refresh:
723+
if formset.is_valid() and token_id and token_refresh:
657724
OrgLevelTokenService.refresh_token(token_id)
658725
return super().save_related(request, form, formsets, change)
659726

codecov_auth/tests/test_admin.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,10 @@ def test_org_token_refresh_request_calls_service_to_refresh_token(
242242
"organization_tokens-0-REFRESH": "on",
243243
"_continue": ["Save and continue editing"],
244244
}
245-
self.client.post(request_url, data=fake_data)
245+
res = self.client.post(request_url, data=fake_data)
246+
247+
# redirected to list page if form change is successful
248+
self.assertEqual(res.status_code, 302)
246249
mock_refresh.assert_called_with(str(org_token.id))
247250

248251
@patch(
@@ -278,7 +281,10 @@ def test_org_token_request_doesnt_call_service_to_refresh_token(self, mock_refre
278281
"organization_tokens-0-token_type": ["upload"],
279282
"_continue": ["Save and continue editing"],
280283
}
281-
self.client.post(request_url, data=fake_data)
284+
res = self.client.post(request_url, data=fake_data)
285+
286+
# redirected to list page if form change is successful
287+
self.assertEqual(res.status_code, 302)
282288
mock_refresh.assert_not_called()
283289

284290
def test_start_trial_ui_display(self):

docker-compose.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ services:
1616
- RUN_ENV=DEV
1717
# Improves pytest-cov performance in python 3.12
1818
# https://github.com/nedbat/coveragepy/issues/1665#issuecomment-1937075835
19-
- COVERAGE_CORE=sysmon
19+
- COVERAGE_CORE=sysmon
2020
env_file:
2121
- .testenv
2222

@@ -42,3 +42,14 @@ services:
4242
redis:
4343
image: redis:6-alpine
4444

45+
minio:
46+
image: minio/minio:latest
47+
command: server /export
48+
environment:
49+
- MINIO_ACCESS_KEY=codecov-default-key
50+
- MINIO_SECRET_KEY=codecov-default-secret
51+
volumes:
52+
- type: tmpfs
53+
target: /export
54+
tmpfs:
55+
size: 256M

docker/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ services:
2323
access_key_id: codecov-default-key
2424
secret_access_key: codecov-default-secret
2525
verify_ssl: false
26+
bucket: archive
27+
port: 9000
28+
host: minio
2629

2730
github:
2831
bot:
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
[
2+
{
3+
"cursor": "MC44fHRlc3Q0",
4+
"node": {
5+
"name": "test4",
6+
"failureRate": 0.8,
7+
"flakeRate": 0.0,
8+
"avgDuration": 100.0,
9+
"totalFailCount": 20,
10+
"totalFlakyFailCount": 0,
11+
"totalPassCount": 5,
12+
"totalSkipCount": 5,
13+
"commitsFailed": 5,
14+
"lastDuration": 100.0
15+
}
16+
},
17+
{
18+
"cursor": "MC43NXx0ZXN0Mw==",
19+
"node": {
20+
"name": "test3",
21+
"failureRate": 0.75,
22+
"flakeRate": 0.0,
23+
"avgDuration": 100.0,
24+
"totalFailCount": 15,
25+
"totalFlakyFailCount": 0,
26+
"totalPassCount": 5,
27+
"totalSkipCount": 5,
28+
"commitsFailed": 5,
29+
"lastDuration": 100.0
30+
}
31+
},
32+
{
33+
"cursor": "MC42NjY2NjY2NjY2NjY2NjY2fHRlc3Qy",
34+
"node": {
35+
"name": "test2",
36+
"failureRate": 0.6666666666666666,
37+
"flakeRate": 0.0,
38+
"avgDuration": 100.0,
39+
"totalFailCount": 10,
40+
"totalFlakyFailCount": 0,
41+
"totalPassCount": 5,
42+
"totalSkipCount": 5,
43+
"commitsFailed": 5,
44+
"lastDuration": 100.0
45+
}
46+
},
47+
{
48+
"cursor": "MC41fHRlc3Qx",
49+
"node": {
50+
"name": "test1",
51+
"failureRate": 0.5,
52+
"flakeRate": 0.5,
53+
"avgDuration": 100.0,
54+
"totalFailCount": 5,
55+
"totalFlakyFailCount": 5,
56+
"totalPassCount": 5,
57+
"totalSkipCount": 5,
58+
"commitsFailed": 5,
59+
"lastDuration": 100.0
60+
}
61+
},
62+
{
63+
"cursor": "MC4wfHRlc3Qw",
64+
"node": {
65+
"name": "test0",
66+
"failureRate": 0.0,
67+
"flakeRate": 0.0,
68+
"avgDuration": 100.0,
69+
"totalFailCount": 0,
70+
"totalFlakyFailCount": 0,
71+
"totalPassCount": 5,
72+
"totalSkipCount": 5,
73+
"commitsFailed": 5,
74+
"lastDuration": 100.0
75+
}
76+
}
77+
]

0 commit comments

Comments
 (0)