Skip to content

Commit

Permalink
Merge branch 'main' into scott/first-pull
Browse files Browse the repository at this point in the history
  • Loading branch information
scott-codecov committed Sep 8, 2023
2 parents 31f8f0a + c828650 commit a8b4391
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 131 deletions.
4 changes: 4 additions & 0 deletions database/tests/factories/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class Meta:
service = factory.Iterator(["gitlab", "github", "bitbucket"])
free = 0
unencrypted_oauth_token = factory.LazyFunction(lambda: uuid4().hex)
trial_start_date = datetime.now()
trial_end_date = datetime.now()
trial_status = enums.TrialStatus.NOT_STARTED.value

oauth_token = factory.LazyAttribute(
lambda o: encrypt_oauth_token(o.unencrypted_oauth_token)
Expand Down Expand Up @@ -222,6 +225,7 @@ class Meta:
upload_extras = {}
upload_type = "uploaded"
storage_path = "storage/path.txt"
created_at = datetime.now()


class UploadLevelTotalsFactory(Factory):
Expand Down
49 changes: 32 additions & 17 deletions services/decoration.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

from sqlalchemy import func

from database.enums import Decoration
from conftest import dbsession
from database.enums import Decoration, TrialStatus
from database.models import Commit, Owner, Repository
from database.models.reports import CommitReport, Upload
from services.billing import BillingPlan, is_pr_billing_plan
Expand All @@ -22,6 +23,7 @@
"29139614+renovate[bot]@users.noreply.github.com",
]
BOT_USER_IDS = ["29139614"] # renovate[bot] github
USER_BASIC_LIMIT_UPLOAD = 250


@dataclass
Expand All @@ -37,6 +39,34 @@ def _is_bot_account(author: Owner) -> bool:
return author.email in BOT_USER_EMAILS or author.service_id in BOT_USER_IDS


def determine_uploads_used(db_session, org: Owner) -> int:
query = (
db_session.query(Upload)
.join(CommitReport)
.join(Commit)
.join(Repository)
.filter(
Upload.upload_type == "uploaded",
Repository.ownerid == org.ownerid,
Repository.private == True,
Upload.created_at >= (datetime.now() - timedelta(days=30)),
Commit.timestamp >= (datetime.now() - timedelta(days=60)),
)
)

if (
org.trial_status == TrialStatus.EXPIRED.value
and org.trial_start_date
and org.trial_end_date
):
query = query.filter(
(Upload.created_at >= org.trial_end_date)
| (Upload.created_at <= org.trial_start_date)
)

return query.limit(USER_BASIC_LIMIT_UPLOAD).count()


def determine_decoration_details(
enriched_pull: EnrichedPull, empty_upload=None
) -> dict:
Expand Down Expand Up @@ -118,22 +148,7 @@ def determine_decoration_details(
)

# TODO declare this to be shared between codecov-api and worker
USER_BASIC_LIMIT_UPLOAD = 250
uploads_used = (
db_session.query(Upload)
.join(CommitReport)
.join(Commit)
.join(Repository)
.filter(
Upload.upload_type == "uploaded",
Repository.ownerid == org.ownerid,
Repository.private == True,
Upload.created_at >= (datetime.now() - timedelta(days=30)),
Commit.timestamp >= (datetime.now() - timedelta(days=60)),
)
.limit(USER_BASIC_LIMIT_UPLOAD)
.count()
)
uploads_used = determine_uploads_used(db_session=db_session, org=org)

if (
org.plan == BillingPlan.users_basic.value
Expand Down
2 changes: 1 addition & 1 deletion services/notification/notifiers/checks/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ async def notify(self, comparison: Comparison):
payload["url"] = get_pull_url(comparison.pull)
else:
payload["url"] = get_commit_url(comparison.head.commit)
return await self.send_notification(comparison, payload)
return await self.maybe_send_notification(comparison, payload)
except TorngitClientError as e:
if e.code == 403:
raise e
Expand Down
22 changes: 22 additions & 0 deletions services/notification/notifiers/mixins/message/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ async def create_message(
section_writer,
)

await self._write_feedback_link(comparison, settings, write)

return [m for m in message if m is not None]

async def _possibly_write_gh_app_login_announcement(
Expand All @@ -172,6 +174,26 @@ async def _possibly_write_gh_app_login_announcement(
write(f":exclamation: {message_to_display}")
write("")

async def _write_feedback_link(
self, comparison: ComparisonProxy, settings: dict, write: Callable
):
hide_project_coverage = settings.get("hide_project_coverage", False)
if hide_project_coverage:
write(
":loudspeaker: Thoughts on this report? [Let us know!]({0}).".format(
"https://about.codecov.io/pull-request-comment-report/"
)
)
else:
repo_service = comparison.repository_service.service
write(
":loudspeaker: Have feedback on the report? [Share it here]({0}).".format(
"https://gitlab.com/codecov-open-source/codecov-user-feedback/-/issues/4"
if repo_service == "gitlab"
else "https://about.codecov.io/codecov-pr-comment-feedback/"
)
)

async def write_section_to_msg(
self, comparison, changes, diff, links, write, section_writer, behind_by=None
):
Expand Down
17 changes: 1 addition & 16 deletions services/notification/notifiers/mixins/message/sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,13 @@ async def write_section(*args, **kwargs):
class NewFooterSectionWriter(BaseSectionWriter):
async def do_write_section(self, comparison, diff, changes, links, behind_by=None):
hide_project_coverage = self.settings.get("hide_project_coverage", False)
if hide_project_coverage:
yield ("")
yield (
":loudspeaker: Thoughts on this report? [Let us know!]({0}).".format(
"https://about.codecov.io/pull-request-comment-report/"
)
)
else:
repo_service = comparison.repository_service.service
if not hide_project_coverage:
yield ("")
yield (
"[:umbrella: View full report in Codecov by Sentry]({0}?src=pr&el=continue). ".format(
links["pull"]
)
)
yield (
":loudspeaker: Have feedback on the report? [Share it here]({0}).".format(
"https://about.codecov.io/codecov-pr-comment-feedback/"
if repo_service == "github"
else "https://gitlab.com/codecov-open-source/codecov-user-feedback/-/issues/4"
)
)


class NewHeaderSectionWriter(BaseSectionWriter):
Expand Down
83 changes: 43 additions & 40 deletions services/notification/notifiers/status/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,46 +212,7 @@ async def notify(self, comparison: Comparison):
else:
payload["url"] = get_commit_url(comparison.head.commit)

base_commit = comparison.base.commit if comparison.base else None
head_commit = comparison.head.commit if comparison.head else None

cache_key = make_hash_sha256(
dict(
type="status_check_notification",
repoid=head_commit.repoid,
base_commitid=base_commit.commitid if base_commit else None,
head_commitid=head_commit.commitid if head_commit else None,
notifier_name=self.name,
notifier_title=self.title,
)
)

last_payload = cache.get_backend().get(cache_key)
if last_payload is NO_VALUE or last_payload != payload:
ttl = int(
get_config(
"setup", "cache", "send_status_notification", default=600
)
) # 10 min default
cache.get_backend().set(cache_key, ttl, payload)
return await self.send_notification(comparison, payload)
else:
log.info(
"Notification payload unchanged. Skipping notification.",
extra=dict(
repoid=head_commit.repoid,
base_commitid=base_commit.commitid if base_commit else None,
head_commitid=head_commit.commitid if head_commit else None,
notifier_name=self.name,
notifier_title=self.title,
),
)
return NotificationResult(
notification_attempted=False,
notification_successful=None,
explanation="payload_unchanged",
data_sent=None,
)
return await self.maybe_send_notification(comparison, payload)
except TorngitClientError:
log.warning(
"Unable to send status notification to user due to a client-side error",
Expand Down Expand Up @@ -302,6 +263,48 @@ def get_status_external_name(self) -> str:
status_piece = f"/{self.title}" if self.title != "default" else ""
return f"codecov/{self.context}{status_piece}"

async def maybe_send_notification(
self, comparison: Comparison, payload: dict
) -> NotificationResult:
base_commit = comparison.base.commit if comparison.base else None
head_commit = comparison.head.commit if comparison.head else None

cache_key = make_hash_sha256(
dict(
type="status_check_notification",
repoid=head_commit.repoid,
base_commitid=base_commit.commitid if base_commit else None,
head_commitid=head_commit.commitid if head_commit else None,
notifier_name=self.name,
notifier_title=self.title,
)
)

last_payload = cache.get_backend().get(cache_key)
if last_payload is NO_VALUE or last_payload != payload:
ttl = int(
get_config("setup", "cache", "send_status_notification", default=600)
) # 10 min default
cache.get_backend().set(cache_key, ttl, payload)
return await self.send_notification(comparison, payload)
else:
log.info(
"Notification payload unchanged. Skipping notification.",
extra=dict(
repoid=head_commit.repoid,
base_commitid=base_commit.commitid if base_commit else None,
head_commitid=head_commit.commitid if head_commit else None,
notifier_name=self.name,
notifier_title=self.title,
),
)
return NotificationResult(
notification_attempted=False,
notification_successful=None,
explanation="payload_unchanged",
data_sent=None,
)

async def send_notification(self, comparison: Comparison, payload):
title = self.get_status_external_name()
repository_service = self.repository_service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ async def test_notify(self, sample_comparison, codecov_vcr, mock_configuration):
"> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`",
"> Powered by [Codecov](https://app.codecov.io/gh/joseph-sentry/codecov-demo/pull/9?src=pr&el=footer). Last update [5b174c2...5601846](https://app.codecov.io/gh/joseph-sentry/codecov-demo/pull/9?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).",
"",
f":loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/).",
]
for exp, res in zip(result.data_sent["message"], message):
assert exp == res
Expand Down Expand Up @@ -532,6 +533,7 @@ async def test_notify_gitlab(
"> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`",
"> Powered by [Codecov](https://app.codecov.io/gl/joseph-sentry/example-python/pull/1?src=pr&el=footer). Last update [0fc784a...0b6a213](https://app.codecov.io/gl/joseph-sentry/example-python/pull/1?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).",
"",
f":loudspeaker: Have feedback on the report? [Share it here](https://gitlab.com/codecov-open-source/codecov-user-feedback/-/issues/4).",
]
for exp, res in zip(result.data_sent["message"], message):
assert exp == res
Expand Down Expand Up @@ -599,8 +601,8 @@ async def test_notify_new_layout(
"</details>",
"",
"[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/joseph-sentry/codecov-demo/pull/9?src=pr&el=continue). ",
":loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/).",
"",
":loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/).",
]
for exp, res in zip(result.data_sent["message"], message):
assert exp == res
Expand Down Expand Up @@ -679,8 +681,8 @@ async def test_notify_with_components(
"</details>",
"",
"[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/joseph-sentry/codecov-demo/pull/9?src=pr&el=continue). ",
":loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/).",
"",
":loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/).",
]
for exp, res in zip(result.data_sent["message"], message):
assert exp == res
Expand Down
3 changes: 3 additions & 0 deletions services/notification/notifiers/tests/unit/test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,7 @@ async def test_build_default_payload(
f"",
f"... and [1 file with indirect coverage changes](test.example.br/gh/test_build_default_payload/{repo.name}/pull/{sample_comparison.pull.pullid}/indirect-changes?src=pr&el=tree-more)",
f"",
":loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/).",
]
),
},
Expand Down Expand Up @@ -1558,6 +1559,7 @@ async def test_build_default_payload_with_flags(
f"",
f"... and [1 file with indirect coverage changes](test.example.br/gh/test_build_default_payload_with_flags/{repo.name}/pull/{sample_comparison.pull.pullid}/indirect-changes?src=pr&el=tree-more)",
f"",
":loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/).",
]
),
},
Expand Down Expand Up @@ -1608,6 +1610,7 @@ async def test_build_default_payload_with_flags_and_footer(
f"> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`",
f"> Powered by [Codecov](test.example.br/gh/{test_name}/{repo.name}/pull/{sample_comparison.pull.pullid}?src=pr&el=footer). Last update [{base_commit.commitid[:7]}...{head_commit.commitid[:7]}](test.example.br/gh/{test_name}/{repo.name}/pull/{sample_comparison.pull.pullid}?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).",
f"",
":loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/).",
]
),
},
Expand Down
Loading

0 comments on commit a8b4391

Please sign in to comment.