Skip to content

Commit f80aa07

Browse files
committed
Move logic of reading the event payload file to settings.py
1 parent 411a611 commit f80aa07

File tree

8 files changed

+145
-38
lines changed

8 files changed

+145
-38
lines changed

coverage_comment/activity.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,20 @@ class ActivityNotFound(Exception):
1616
def find_activity(
1717
event_name: str,
1818
is_default_branch: bool,
19-
event_action: str | None = None,
19+
event_type: str,
20+
is_pr_merged: bool,
2021
) -> str:
2122
"""Find the activity to perform based on the event type and payload."""
2223
if event_name == "workflow_run":
2324
return "post_comment"
2425

2526
if (
2627
(event_name == "push" and is_default_branch)
27-
or (
28-
event_name == "pull_request"
29-
and event_action == "merged"
30-
and is_default_branch
31-
)
3228
or event_name == "schedule"
29+
or (event_name == "pull_request" and event_type == "closed")
3330
):
31+
if event_name == "pull_request" and event_type == "closed" and not is_pr_merged:
32+
raise ActivityNotFound
3433
return "save_coverage_data_files"
3534

3635
if event_name not in {"pull_request", "push"}:

coverage_comment/main.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from __future__ import annotations
22

33
import functools
4-
import json
54
import logging
65
import os
76
import sys
@@ -70,24 +69,16 @@ def action(
7069
log.debug(f"Operating on {config.GITHUB_REF}")
7170
gh = github_client.GitHub(session=github_session)
7271
event_name = config.GITHUB_EVENT_NAME
73-
event_path = config.GITHUB_EVENT_PATH
74-
event_action = None
75-
76-
if event_path and os.path.exists(event_path):
77-
with open(event_path) as event_file:
78-
event_payload = json.load(event_file)
79-
is_merged_pr_action = event_payload.get("pull_request", {}).get("merged", False)
80-
if is_merged_pr_action:
81-
event_action = "merged"
8272

8373
repo_info = github.get_repository_info(
8474
github=gh, repository=config.GITHUB_REPOSITORY
8575
)
8676
try:
8777
activity = activity_module.find_activity(
8878
event_name=event_name,
89-
event_action=event_action,
9079
is_default_branch=repo_info.is_default_branch(ref=config.GITHUB_REF),
80+
event_type=config.GITHUB_EVENT_TYPE,
81+
is_pr_merged=config.IS_PR_MERGED,
9182
)
9283
except activity_module.ActivityNotFound:
9384
log.error(

coverage_comment/settings.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import dataclasses
44
import decimal
5+
import functools
56
import inspect
7+
import json
68
import pathlib
79
from collections.abc import MutableMapping
810
from typing import Any
@@ -139,6 +141,23 @@ def GITHUB_BRANCH_NAME(self) -> str | None:
139141
return self.GITHUB_REF.split("/", 2)[2]
140142
return None
141143

144+
@functools.cached_property
145+
def GITHUB_EVENT_PAYLOAD(self) -> dict:
146+
if not self.GITHUB_EVENT_PATH:
147+
return {}
148+
return json.loads(self.GITHUB_EVENT_PATH.read_text())
149+
150+
@property
151+
def GITHUB_EVENT_TYPE(self) -> str | None:
152+
return self.GITHUB_EVENT_PAYLOAD.get("action")
153+
154+
@property
155+
def IS_PR_MERGED(self) -> bool:
156+
try:
157+
return self.GITHUB_EVENT_PAYLOAD["pull_request"]["merged"]
158+
except KeyError:
159+
return False
160+
142161
@property
143162
def FINAL_COMMENT_FILENAME(self):
144163
filename = self.COMMENT_FILENAME

tests/conftest.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
import pathlib
99
import zipfile
10+
from collections.abc import Callable
1011

1112
import httpx
1213
import pytest
@@ -47,7 +48,7 @@ def _(**kwargs):
4748

4849

4950
@pytest.fixture
50-
def pull_request_config(base_config):
51+
def pull_request_config(base_config) -> Callable[..., settings.Config]:
5152
def _(**kwargs):
5253
defaults = {
5354
# GitHub stuff
@@ -250,6 +251,14 @@ def summary_file(tmp_path):
250251
return file
251252

252253

254+
@pytest.fixture
255+
def pull_request_event_payload(tmp_path):
256+
file = tmp_path / "event.json"
257+
file.touch()
258+
259+
return file
260+
261+
253262
_is_failed = []
254263

255264

tests/integration/test_main.py

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212

1313

1414
@pytest.fixture
15-
def in_integration_env(integration_env, integration_dir):
16-
curdir = os.getcwd()
17-
os.chdir(integration_dir)
15+
def in_integration_env(integration_env, integration_dir, monkeypatch):
16+
monkeypatch.chdir(integration_dir)
1817
yield integration_dir
19-
os.chdir(curdir)
2018

2119

2220
@pytest.fixture
@@ -673,6 +671,55 @@ def test_action__push__default_branch(
673671
assert "Missing" in summary_content
674672

675673

674+
def test_action__pull_request_closed_merged(
675+
pull_request_config,
676+
session,
677+
in_integration_env,
678+
get_logs,
679+
git,
680+
summary_file,
681+
pull_request_event_payload,
682+
):
683+
session.register("GET", "/repos/py-cov-action/foobar")(
684+
json={"default_branch": "main", "visibility": "public"}
685+
)
686+
session.register(
687+
"GET",
688+
"https://img.shields.io/static/v1?label=Coverage&message=77%25&color=orange",
689+
)(text="<this is a svg badge>")
690+
691+
git.register("git branch --show-current")(stdout="foo")
692+
git.register("git reset --hard")()
693+
git.register("git fetch origin python-coverage-comment-action-data")()
694+
git.register("git switch python-coverage-comment-action-data")()
695+
git.register("git add endpoint.json")()
696+
git.register("git add data.json")()
697+
git.register("git add badge.svg")()
698+
git.register("git add htmlcov")()
699+
git.register("git add README.md")()
700+
git.register("git diff --staged --exit-code")(exit_code=1)
701+
git.register("git commit --message Update coverage data")()
702+
git.register("git push origin python-coverage-comment-action-data")()
703+
git.register("git switch foo")()
704+
705+
pull_request_event_payload.write_text(
706+
"""{"action": "closed", "pull_request": {"merged": true}}"""
707+
)
708+
709+
result = main.action(
710+
config=pull_request_config(
711+
GITHUB_STEP_SUMMARY=summary_file,
712+
GITHUB_EVENT_PATH=pull_request_event_payload,
713+
),
714+
github_session=session,
715+
http_session=session,
716+
git=git,
717+
)
718+
assert result == 0
719+
720+
assert get_logs("INFO", "Saving coverage files")
721+
722+
676723
def test_action__push__default_branch__private(
677724
push_config, session, in_integration_env, get_logs, git
678725
):

tests/unit/test_activity.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,44 @@
66

77

88
@pytest.mark.parametrize(
9-
"event_name, event_action, is_default_branch, expected_activity",
9+
"event_name, is_default_branch, event_type, is_pr_merged, expected_activity",
1010
[
11-
("workflow_run", None, True, "post_comment"),
12-
("push", None, True, "save_coverage_data_files"),
13-
("push", None, False, "process_pr"),
14-
("pull_request", "merged", True, "save_coverage_data_files"),
15-
("pull_request", None, True, "process_pr"),
16-
("pull_request", None, False, "process_pr"),
17-
("schedule", None, False, "save_coverage_data_files"),
11+
("workflow_run", True, None, False, "post_comment"),
12+
("push", True, None, False, "save_coverage_data_files"),
13+
("push", False, None, False, "process_pr"),
14+
("pull_request", True, "closed", True, "save_coverage_data_files"),
15+
("pull_request", True, None, False, "process_pr"),
16+
("pull_request", False, None, False, "process_pr"),
17+
("schedule", False, None, False, "save_coverage_data_files"),
1818
],
1919
)
20-
def test_find_activity(event_name, event_action, is_default_branch, expected_activity):
20+
def test_find_activity(
21+
event_name, is_default_branch, event_type, is_pr_merged, expected_activity
22+
):
2123
result = activity.find_activity(
2224
event_name=event_name,
23-
event_action=event_action,
2425
is_default_branch=is_default_branch,
26+
event_type=event_type,
27+
is_pr_merged=is_pr_merged,
2528
)
2629
assert result == expected_activity
2730

2831

2932
def test_find_activity_not_found():
3033
with pytest.raises(activity.ActivityNotFound):
31-
activity.find_activity(event_name="not_found", is_default_branch=False)
34+
activity.find_activity(
35+
event_name="not_found",
36+
is_default_branch=False,
37+
event_type="not_found",
38+
is_pr_merged=False,
39+
)
40+
41+
42+
def test_find_activity_pr_closed_not_merged():
43+
with pytest.raises(activity.ActivityNotFound):
44+
activity.find_activity(
45+
event_name="pull_request",
46+
is_default_branch=False,
47+
event_type="closed",
48+
is_pr_merged=False,
49+
)

tests/unit/test_main.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44

55
import httpx
6+
import pytest
67

78
from coverage_comment import main, settings, subprocess
89

@@ -14,7 +15,6 @@ def test_main(mocker, get_logs):
1415
# We could also accept not to test this function but if we've come this
1516
# far and have 98% coverage, we can as well have 100%.
1617

17-
exit = mocker.patch("sys.exit")
1818
action = mocker.patch("coverage_comment.main.action")
1919

2020
os.environ.update(
@@ -26,11 +26,14 @@ def test_main(mocker, get_logs):
2626
"GITHUB_BASE_REF": "",
2727
"GITHUB_EVENT_NAME": "push",
2828
"GITHUB_STEP_SUMMARY": "step_summary",
29+
"GITHUB_EVENT_PATH": "foo/bar",
2930
}
3031
)
31-
main.main()
3232

33-
exit.assert_called_with(action.return_value)
33+
with pytest.raises(SystemExit) as exc_data:
34+
main.main()
35+
36+
assert exc_data.value.code == action.return_value
3437
kwargs = action.call_args_list[0].kwargs
3538
assert isinstance(kwargs["config"], settings.Config)
3639
assert isinstance(kwargs["git"], subprocess.Git)

tests/unit/test_settings.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from __future__ import annotations
22

33
import decimal
4+
import json
45
import pathlib
6+
from collections.abc import Callable
57

68
import pytest
79

@@ -104,7 +106,7 @@ def test_config__verbose_deprecated(get_logs):
104106

105107

106108
@pytest.fixture
107-
def config():
109+
def config() -> Callable[..., settings.Config]:
108110
defaults = {
109111
"GITHUB_BASE_REF": "master",
110112
"GITHUB_TOKEN": "foo",
@@ -122,7 +124,7 @@ def config():
122124
"MERGE_COVERAGE_FILES": True,
123125
}
124126

125-
def _(**kwargs):
127+
def _(**kwargs) -> settings.Config:
126128
return settings.Config(**(defaults | kwargs))
127129

128130
return _
@@ -196,3 +198,22 @@ def test_final_coverage_data_branch(config):
196198
SUBPROJECT_ID="bar",
197199
)
198200
assert config_obj.FINAL_COVERAGE_DATA_BRANCH == "foo-bar"
201+
202+
203+
@pytest.mark.parametrize("merged", [True, False])
204+
def test_is_pr_merged(tmp_path, config, merged):
205+
path = tmp_path / "event.json"
206+
path.write_text(
207+
json.dumps({"action": "closed", "pull_request": {"merged": merged}})
208+
)
209+
config_obj = config(GITHUB_EVENT_PATH=path)
210+
211+
assert config_obj.IS_PR_MERGED is merged
212+
213+
214+
def test_is_pr_merged__other_payload(tmp_path, config):
215+
path = tmp_path / "event.json"
216+
path.write_text(json.dumps({"action": "other"}))
217+
config_obj = config(GITHUB_EVENT_PATH=path)
218+
219+
assert config_obj.IS_PR_MERGED is False

0 commit comments

Comments
 (0)