Skip to content

Commit

Permalink
Merge branch 'main' into jerrodcodecov-patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
trent-codecov authored Sep 14, 2023
2 parents 32ec4b2 + 53ecfc0 commit cd59e30
Show file tree
Hide file tree
Showing 21 changed files with 718 additions and 91 deletions.
12 changes: 11 additions & 1 deletion database/models/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import string
import uuid
from datetime import datetime
from functools import cached_property

from sqlalchemy import Column, ForeignKey, Index, UniqueConstraint, types
from sqlalchemy.dialects import postgresql
Expand Down Expand Up @@ -297,7 +298,9 @@ class Pull(CodecovBaseModel):
behind_by_commit = Column(types.Text)

author = relationship(Owner)
repository = relationship(Repository, backref=backref("pulls", cascade="delete"))
repository = relationship(
Repository, backref=backref("pulls", cascade="delete", lazy="dynamic")
)

__table_args__ = (Index("pulls_repoid_pullid", "repoid", "pullid", unique=True),)

Expand Down Expand Up @@ -355,6 +358,13 @@ def should_write_to_storage(self) -> bool:
repoid=self.repository.repoid,
)

@cached_property
def is_first_pull(self):
first_pull = (
self.repository.pulls.with_entities(Pull.id_).order_by(Pull.id_).first()
)
return first_pull.id_ == self.id_

_flare = Column("flare", postgresql.JSON)
_flare_storage_path = Column("flare_storage_path", types.Text, nullable=True)
flare = ArchiveField(
Expand Down
1 change: 1 addition & 0 deletions database/tests/factories/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class Meta:
"s": 1,
}
)
_report_json_storage_path = None
_report_json = factory.LazyFunction(
lambda: {
"files": {
Expand Down
8 changes: 3 additions & 5 deletions dockerscripts/Dockerfile.circle
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# syntax=docker/dockerfile:1.3
ARG REQUIREMENTS_IMAGE
FROM busybox:1.34.1 as berglas
WORKDIR /tmp
ADD https://storage.googleapis.com/berglas/0.5.0/linux_amd64/berglas berglas
RUN echo "99dc4b3146d19b7e36cc6d339eeefa6a959a6d86143b7317e722d09a3b57ca45 berglas" | sha256sum -c
ARG BERGLAS_VERSION=1.0.3
FROM us-docker.pkg.dev/berglas/berglas/berglas:$BERGLAS_VERSION as berglas


FROM $REQUIREMENTS_IMAGE
Expand All @@ -12,7 +10,7 @@ ARG RELEASE_VERSION

ENV RELEASE_VERSION $RELEASE_VERSION

COPY --chmod=755 --from=berglas /tmp/berglas /usr/local/bin/berglas
COPY --chmod=755 --from=berglas /bin/berglas /usr/local/bin/berglas

USER codecov

Expand Down
2 changes: 1 addition & 1 deletion requirements.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
git+ssh://[email protected]/codecov/shared.git@f0174635ccaebc3463a5641b9ad640a46b5fd472#egg=shared
git+ssh://[email protected]/codecov/shared.git@bef9260a4b6218b5ce4b5b9152a71d7e6d63a954#egg=shared
git+ssh://[email protected]/codecov/[email protected]#egg=codecovopentelem
boto3
celery
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# pip-compile requirements.in
Expand Down Expand Up @@ -251,7 +251,7 @@ s3transfer==0.3.4
# via boto3
sentry-sdk==1.19.1
# via -r requirements.in
shared @ git+ssh://[email protected]/codecov/shared.git@f0174635ccaebc3463a5641b9ad640a46b5fd472
shared @ git+ssh://[email protected]/codecov/shared.git@bef9260a4b6218b5ce4b5b9152a71d7e6d63a954
# via -r requirements.in
six==1.15.0
# via
Expand Down
19 changes: 11 additions & 8 deletions services/notification/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,17 @@ def get_notifiers_instances(self) -> Iterator[AbstractBaseNotifier]:
decoration_type=self.decoration_type,
)

yield CodecovSlackAppNotifier(
repository=self.repository,
title="codecov-slack-app",
notifier_yaml_settings={},
notifier_site_settings={},
current_yaml=self.current_yaml,
decoration_type=self.decoration_type,
)
# yield notifier if slack_app field is True, nonexistent, or a non-empty dict
slack_app_yaml_field = read_yaml_field(self.current_yaml, ("slack_app",), True)
if slack_app_yaml_field:
yield CodecovSlackAppNotifier(
repository=self.repository,
title="codecov-slack-app",
notifier_yaml_settings=slack_app_yaml_field,
notifier_site_settings={},
current_yaml=self.current_yaml,
decoration_type=self.decoration_type,
)

comment_yaml_field = read_yaml_field(self.current_yaml, ("comment",))
if comment_yaml_field:
Expand Down
11 changes: 10 additions & 1 deletion services/notification/notifiers/codecov_slack_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@ def notification_type(self) -> Notification:
return Notification.codecov_slack_app

def is_enabled(self) -> bool:
return True
# if yaml settings are a dict, then check the enabled key and return that
# the enabled field should always exist if the yaml settings are a dict because otherwise it would fail the validation

# else if the yaml settings is a boolean then just return that

# in any case, self.notifier_yaml_settings should either be a bool or a dict always and should never be None
if isinstance(self.notifier_yaml_settings, dict):
return self.notifier_yaml_settings.get("enabled", False)
elif isinstance(self.notifier_yaml_settings, bool):
return self.notifier_yaml_settings

def store_results(self, comparison: Comparison, result: NotificationResult):
pass
Expand Down
12 changes: 12 additions & 0 deletions services/notification/notifiers/comment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
)

from database.enums import Notification
from database.models import Pull
from helpers.metrics import metrics
from services.comparison.types import Comparison
from services.license import requires_license
Expand Down Expand Up @@ -358,11 +359,22 @@ async def build_message(self, comparison: Comparison) -> List[str]:
return self._create_empty_upload_message()
if self.should_use_upload_limit_decoration():
return self._create_reached_upload_limit_message(comparison)
if comparison.pull.is_first_pull:
return self._create_welcome_message()
pull_dict = comparison.enriched_pull.provider_pull
return await self.create_message(
comparison, pull_dict, self.notifier_yaml_settings
)

def _create_welcome_message(self):
return [
"## Welcome to [Codecov](https://codecov.io) :tada:",
"",
"Once merged to your default branch, Codecov will compare your coverage reports and display the results in this comment.",
"",
"Thanks for integrating Codecov - We've got you covered :open_umbrella:",
]

def _create_empty_upload_message(self):
if self.is_passing_empty_upload():
return [
Expand Down
22 changes: 0 additions & 22 deletions services/notification/notifiers/mixins/message/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,6 @@ 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 @@ -174,26 +172,6 @@ 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: 16 additions & 1 deletion services/notification/notifiers/mixins/message/sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,28 @@ 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 not hide_project_coverage:
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
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
18 changes: 13 additions & 5 deletions services/notification/notifiers/tests/integration/test_comment.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from unittest.mock import patch
from unittest.mock import PropertyMock, patch

import pytest
from shared.reports.readonly import ReadOnlyReport
Expand All @@ -10,6 +10,15 @@
from services.notification.notifiers.comment import CommentNotifier


@pytest.fixture
def is_not_first_pull(mocker):
mocker.patch(
"database.models.core.Pull.is_first_pull",
return_value=False,
new_callable=PropertyMock,
)


@pytest.fixture
def codecove2e_comparison(dbsession, request, sample_report, small_report):
repository = RepositoryFactory.create(
Expand Down Expand Up @@ -319,6 +328,7 @@ def sample_comparison_for_limited_upload(
)


@pytest.mark.usefixtures("is_not_first_pull")
class TestCommentNotifierIntegration(object):
@pytest.mark.asyncio
async def test_notify(self, sample_comparison, codecov_vcr, mock_configuration):
Expand Down Expand Up @@ -380,7 +390,6 @@ 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 @@ -524,7 +533,6 @@ 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 @@ -592,8 +600,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/).",
"",
]
for exp, res in zip(result.data_sent["message"], message):
assert exp == res
Expand Down Expand Up @@ -672,8 +680,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/).",
"",
]
for exp, res in zip(result.data_sent["message"], message):
assert exp == res
Expand Down
3 changes: 0 additions & 3 deletions services/notification/notifiers/tests/unit/test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1516,7 +1516,6 @@ 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 @@ -1559,7 +1558,6 @@ 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 @@ -1610,7 +1608,6 @@ 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,30 @@ def test_is_enabled(self, dbsession, mock_configuration, sample_comparison):
notifier = CodecovSlackAppNotifier(
repository=sample_comparison.head.commit.repository,
title="title",
notifier_yaml_settings={},
notifier_yaml_settings={"enabled": True},
notifier_site_settings=True,
current_yaml={},
current_yaml={"slack_app": {"enabled": True}},
)
assert notifier.is_enabled() == True

def test_is_enable_false(self, dbsession, mock_configuration, sample_comparison):
notifier = CodecovSlackAppNotifier(
repository=sample_comparison.head.commit.repository,
title="title",
notifier_yaml_settings={"enabled": False},
notifier_site_settings=True,
current_yaml={"slack_app": {"enabled": False}},
)

assert notifier.is_enabled() is False

def test_notification_type(self, dbsession, mock_configuration, sample_comparison):
notifier = CodecovSlackAppNotifier(
repository=sample_comparison.head.commit.repository,
title="title",
notifier_yaml_settings={},
notifier_yaml_settings={"enabled": True},
notifier_site_settings=True,
current_yaml={},
current_yaml={"slack_app": {"enabled": True}},
)
assert notifier.notification_type == Notification.codecov_slack_app

Expand All @@ -36,9 +47,9 @@ async def test_notify(
notifier = CodecovSlackAppNotifier(
repository=sample_comparison.head.commit.repository,
title="title",
notifier_yaml_settings={},
notifier_yaml_settings={"enabled": True},
notifier_site_settings=True,
current_yaml={},
current_yaml={"slack_app": {"enabled": True}},
)
result = await notifier.notify(sample_comparison)
assert result.notification_successful == True
Expand All @@ -54,9 +65,9 @@ async def test_notify_failure(
notifier = CodecovSlackAppNotifier(
repository=sample_comparison.head.commit.repository,
title="title",
notifier_yaml_settings={},
notifier_yaml_settings={"enabled": True},
notifier_site_settings=True,
current_yaml={},
current_yaml={"slack_app": {"enabled": True}},
)
result = await notifier.notify(sample_comparison)
assert result.notification_successful == False
Expand All @@ -74,9 +85,9 @@ async def test_notify_request_being_called(
notifier = CodecovSlackAppNotifier(
repository=sample_comparison.head.commit.repository,
title="title",
notifier_yaml_settings={},
notifier_yaml_settings={"enabled": True},
notifier_site_settings=True,
current_yaml={},
current_yaml={"slack_app": {"enabled": True}},
)
result = await notifier.notify(sample_comparison)
assert result.notification_successful == True
Expand Down
Loading

0 comments on commit cd59e30

Please sign in to comment.