Skip to content

Commit 4a1e96e

Browse files
implement support for forgejo commit statuses
Signed-off-by: Olamidepeterojo <[email protected]>
1 parent 271bba4 commit 4a1e96e

File tree

4 files changed

+152
-80
lines changed

4 files changed

+152
-80
lines changed

ogr/services/forgejo/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# Copyright Contributors to the Packit project.
22
# SPDX-License-Identifier: MIT
33

4+
from ogr.services.forgejo.commit_flag import ForgejoCommitFlag
45
from ogr.services.forgejo.issue import ForgejoIssue
56
from ogr.services.forgejo.project import ForgejoProject
67
from ogr.services.forgejo.pull_request import ForgejoPullRequest
78
from ogr.services.forgejo.service import ForgejoService
89

910
__all__ = [
11+
ForgejoCommitFlag.__name__,
1012
ForgejoPullRequest.__name__,
1113
ForgejoIssue.__name__,
1214
ForgejoProject.__name__,

ogr/services/forgejo/commit_flag.py

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from datetime import datetime
55
from typing import Any
66

7-
import requests
7+
from pyforgejo import PyforgejoApi
88

99
from ogr.abstract import CommitFlag, CommitStatus
1010

@@ -51,29 +51,24 @@ def _from_raw_commit_flag(self) -> None:
5151
self.comment = raw.get("comment")
5252
self.uid = raw.get("id")
5353
self.url = raw.get("url")
54-
# Parse timestamps in ISO8601 format (adjust format if needed)
55-
self._created = datetime.strptime(raw.get("created"), "%Y-%m-%dT%H:%M:%SZ")
56-
self._edited = datetime.strptime(raw.get("updated"), "%Y-%m-%dT%H:%M:%SZ")
54+
self._created = raw.get("created")
55+
self._edited = raw.get("updated")
5756

5857
@staticmethod
5958
def get(project: Any, commit: str) -> list["CommitFlag"]:
6059
"""
61-
Retrieve commit statuses for the given commit from Forgejo.
62-
This method should use Forgejo's API to fetch statuses.
60+
Retrieve commit statuses for the given commit from Forgejo using the pyforgejo SDK.
6361
"""
64-
# Construct the URL using the project's forge_api_url, owner, repo, and commit hash.
65-
url = (
66-
f"{project.forge_api_url}/repos/{project.owner}/{project.repo}/commits/"
67-
f"{commit}/statuses"
62+
client = PyforgejoApi(api_url=project.forge_api_url, token=project.token)
63+
raw_flags = client.get_commit_statuses(
64+
owner=project.owner,
65+
repo=project.repo,
66+
commit=commit,
6867
)
69-
headers = project.get_auth_header() # Get auth headers from project config
70-
response = requests.get(url, headers=headers)
71-
response.raise_for_status()
72-
flags: list[CommitFlag] = [
68+
return [
7369
ForgejoCommitFlag(raw_commit_flag=raw_flag, project=project, commit=commit)
74-
for raw_flag in response.json()
70+
for raw_flag in raw_flags
7571
]
76-
return flags
7772

7873
@staticmethod
7974
def set(
@@ -85,22 +80,20 @@ def set(
8580
context: str,
8681
) -> "CommitFlag":
8782
"""
88-
Set a new commit status on Forgejo via its API.
83+
Set a new commit status on Forgejo via the pyforgejo SDK.
8984
"""
90-
url = (
91-
f"{project.forge_api_url}/repos/{project.owner}/{project.repo}/commits/"
92-
f"{commit}/statuses"
85+
client = PyforgejoApi(api_url=project.forge_api_url, token=project.token)
86+
raw_response = client.set_commit_status(
87+
owner=project.owner,
88+
repo=project.repo,
89+
commit=commit,
90+
state=state.name.lower(),
91+
target_url=target_url,
92+
description=description,
93+
context=context,
9394
)
94-
payload = {
95-
"state": state.name.lower(),
96-
"target_url": target_url,
97-
"description": description,
98-
"context": context,
99-
}
100-
headers = project.get_auth_header()
101-
response = requests.post(url, json=payload, headers=headers)
10295
return ForgejoCommitFlag(
103-
raw_commit_flag=response.json(),
96+
raw_commit_flag=raw_response,
10497
project=project,
10598
commit=commit,
10699
)

tests/integration/forgejo/conftest.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,13 @@ def service():
1515
instance_url="https://v10.next.forgejo.org",
1616
api_key=api_key,
1717
)
18+
19+
20+
@pytest.fixture
21+
def project(service):
22+
repo = os.environ.get("FORGEJO_REPO", "existing_repo_name")
23+
namespace = os.environ.get("FORGEJO_NAMESPACE", "existing_namespace")
24+
project = service.get_project(repo=repo, namespace=namespace)
25+
if not project:
26+
pytest.skip(f"Project {namespace}/{repo} does not exist.")
27+
return project

tests/integration/forgejo/test_commit_flag.py

Lines changed: 118 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,95 +2,162 @@
22
# SPDX-License-Identifier: MIT
33

44
import datetime
5-
import responses
5+
66
import pytest
7-
from typing import Any, Dict, List, Optional
8-
import requests
97

10-
from ogr.abstract import CommitStatus, CommitFlag
8+
from ogr.abstract import CommitFlag, CommitStatus
119
from ogr.services.forgejo.commit_flag import ForgejoCommitFlag
1210

11+
12+
def fake_get_commit_statuses(self, owner, repo, commit):
13+
return [
14+
{
15+
"commit": commit,
16+
"state": "success",
17+
"context": "CI",
18+
"comment": "All tests passed",
19+
"id": "123",
20+
"url": f"http://dummy-forgejo/commit/{commit}/status",
21+
"created": datetime.datetime.strptime(
22+
"2023-01-01T12:00:00Z",
23+
"%Y-%m-%dT%H:%M:%SZ",
24+
),
25+
"updated": datetime.datetime.strptime(
26+
"2023-01-01T12:30:00Z",
27+
"%Y-%m-%dT%H:%M:%SZ",
28+
),
29+
},
30+
]
31+
32+
33+
def fake_set_commit_status(
34+
self,
35+
owner,
36+
repo,
37+
commit,
38+
state,
39+
target_url,
40+
description,
41+
context,
42+
):
43+
return {
44+
"commit": commit,
45+
"state": state,
46+
"context": context,
47+
"comment": description,
48+
"id": "456",
49+
"url": f"http://dummy-forgejo/commit/{commit}/status",
50+
"created": datetime.datetime.strptime(
51+
"2023-02-01T12:00:00Z",
52+
"%Y-%m-%dT%H:%M:%SZ",
53+
),
54+
"updated": datetime.datetime.strptime(
55+
"2023-02-01T12:30:00Z",
56+
"%Y-%m-%dT%H:%M:%SZ",
57+
),
58+
}
59+
60+
61+
class FakePyforgejoApi:
62+
def __init__(self, api_url, token):
63+
self.api_url = api_url
64+
self.token = token
65+
66+
def get_commit_statuses(self, owner, repo, commit):
67+
return fake_get_commit_statuses(self, owner, repo, commit)
68+
69+
def set_commit_status(
70+
self,
71+
owner,
72+
repo,
73+
commit,
74+
state,
75+
target_url,
76+
description,
77+
context,
78+
):
79+
return fake_set_commit_status(
80+
self,
81+
owner,
82+
repo,
83+
commit,
84+
state,
85+
target_url,
86+
description,
87+
context,
88+
)
89+
90+
1391
class MockProject:
1492
forge_api_url = "http://dummy-forgejo/api/v1"
1593
owner = "dummy_owner"
1694
repo = "dummy_repo"
95+
token = "dummy_token"
1796

18-
def get_auth_header(self) -> Dict[str, str]:
97+
def get_auth_header(self) -> dict[str, str]:
1998
return {"Authorization": "Bearer dummy_token"}
2099

21-
@responses.activate
100+
101+
@pytest.fixture(autouse=True)
102+
def patch_pyforgejo_api(monkeypatch):
103+
monkeypatch.setattr(
104+
"ogr.services.forgejo.commit_flag.PyforgejoApi",
105+
FakePyforgejoApi,
106+
)
107+
108+
22109
def test_get_commit_flag_integration():
23110
project = MockProject()
24111
commit = "abcdef123456"
25-
url = f"{project.forge_api_url}/repos/{project.owner}/{project.repo}/commits/{commit}/statuses"
26-
27-
# Dummy response data simulating Forgejo API output.
28-
dummy_response = [{
29-
"commit": commit,
30-
"state": "success",
31-
"context": "CI",
32-
"comment": "All tests passed",
33-
"id": "123",
34-
"url": "http://dummy-forgejo/commit/abcdef123456/status",
35-
"created": "2023-01-01T12:00:00Z",
36-
"updated": "2023-01-01T12:30:00Z"
37-
}]
38-
responses.add(responses.GET, url, json=dummy_response, status=200)
39-
40-
# Call the method under test.
41-
flags: List[CommitFlag] = ForgejoCommitFlag.get(project, commit)
42-
43-
# Assertions using CommitStatus from packit.ogr.abstract.
112+
113+
flags: list[CommitFlag] = ForgejoCommitFlag.get(project, commit)
114+
44115
assert len(flags) == 1
45116
flag = flags[0]
46117
assert flag.commit == commit
47118
assert flag.state == CommitStatus.success
48119
assert flag.context == "CI"
49120
assert flag.comment == "All tests passed"
50121
assert flag.uid == "123"
51-
52-
expected_created = datetime.datetime.strptime("2023-01-01T12:00:00Z", "%Y-%m-%dT%H:%M:%SZ")
53-
expected_updated = datetime.datetime.strptime("2023-01-01T12:30:00Z", "%Y-%m-%dT%H:%M:%SZ")
122+
123+
expected_created = datetime.datetime.strptime(
124+
"2023-01-01T12:00:00Z",
125+
"%Y-%m-%dT%H:%M:%SZ",
126+
)
127+
expected_updated = datetime.datetime.strptime(
128+
"2023-01-01T12:30:00Z",
129+
"%Y-%m-%dT%H:%M:%SZ",
130+
)
54131
assert flag.created == expected_created
55132
assert flag.edited == expected_updated
56133

57-
@responses.activate
134+
58135
def test_set_commit_flag_integration():
59136
project = MockProject()
60137
commit = "abcdef123456"
61-
url = f"{project.forge_api_url}/repos/{project.owner}/{project.repo}/commits/{commit}/statuses"
62-
63-
# Dummy response for setting a commit status.
64-
dummy_response = {
65-
"commit": commit,
66-
"state": "success",
67-
"context": "CI",
68-
"comment": "Build succeeded",
69-
"id": "456",
70-
"url": "http://dummy-forgejo/commit/abcdef123456/status",
71-
"created": "2023-02-01T12:00:00Z",
72-
"updated": "2023-02-01T12:30:00Z"
73-
}
74-
responses.add(responses.POST, url, json=dummy_response, status=200)
75-
76-
# Call the set method to create a new commit flag.
138+
77139
flag = ForgejoCommitFlag.set(
78140
project=project,
79141
commit=commit,
80142
state=CommitStatus.success,
81143
target_url="http://dummy-target",
82144
description="Build succeeded",
83-
context="CI"
145+
context="CI",
84146
)
85-
86-
# Assertions to verify correct mapping using CommitStatus.
147+
87148
assert flag.commit == commit
88149
assert flag.state == CommitStatus.success
89150
assert flag.context == "CI"
90151
assert flag.comment == "Build succeeded"
91152
assert flag.uid == "456"
92-
93-
expected_created = datetime.datetime.strptime("2023-02-01T12:00:00Z", "%Y-%m-%dT%H:%M:%SZ")
94-
expected_updated = datetime.datetime.strptime("2023-02-01T12:30:00Z", "%Y-%m-%dT%H:%M:%SZ")
153+
154+
expected_created = datetime.datetime.strptime(
155+
"2023-02-01T12:00:00Z",
156+
"%Y-%m-%dT%H:%M:%SZ",
157+
)
158+
expected_updated = datetime.datetime.strptime(
159+
"2023-02-01T12:30:00Z",
160+
"%Y-%m-%dT%H:%M:%SZ",
161+
)
95162
assert flag.created == expected_created
96163
assert flag.edited == expected_updated

0 commit comments

Comments
 (0)