Skip to content

Commit 6467b13

Browse files
authored
Merge branch 'master' into fix/readonlyadmin-cascade-delete
2 parents de1376f + fe1cc60 commit 6467b13

17 files changed

Lines changed: 1734 additions & 106 deletions

.github/actions/bot-autoassign/issue_assignment_bot.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ def handle_issue_comment(self):
273273
try:
274274
if self.event_payload.get("issue", {}).get("pull_request"):
275275
print("Comment is on a PR, not an issue - skipping")
276-
return False
276+
return True
277277
comment = self.event_payload.get("comment", {})
278278
issue = self.event_payload.get("issue", {})
279279
comment_body = comment.get("body", "")
@@ -285,7 +285,7 @@ def handle_issue_comment(self):
285285
if self.is_assignment_request(comment_body):
286286
return self.respond_to_assignment_request(issue_number, commenter)
287287
print("Comment does not contain assignment request")
288-
return False
288+
return True
289289
except Exception as e:
290290
print(f"Error handling issue comment: {e}")
291291
return False
@@ -308,10 +308,13 @@ def handle_pull_request(self):
308308
# We consider the event handled even if no issues were linked
309309
return True
310310
elif action == "closed":
311-
self.unassign_issues_from_pr(pr_body, pr_author)
311+
if pr.get("merged", False):
312+
print(f"PR #{pr_number} was merged, keeping issue assignments")
313+
else:
314+
self.unassign_issues_from_pr(pr_body, pr_author)
312315
return True
313316
print(f"PR action '{action}' not handled")
314-
return False
317+
return True
315318
except Exception as e:
316319
print(f"Error handling pull request: {e}")
317320
return False
@@ -328,7 +331,7 @@ def run(self):
328331
return self.handle_pull_request()
329332
else:
330333
print(f"Event type '{self.event_name}'" " not supported")
331-
return False
334+
return True
332335
except Exception as e:
333336
print(f"Error in main execution: {e}")
334337
return False

.github/actions/bot-autoassign/pr_reopen_bot.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def handle_pr_reopen(self):
7676
print(f"Reassigned {len(reassigned)}" f" issues to {pr_author}")
7777
return True
7878
except Exception as e:
79-
print(f"Error handling PR reopen: {e}")
79+
print(f"Error handling reopened PR: {e}")
8080
return False
8181

8282
def run(self):
@@ -89,7 +89,7 @@ def run(self):
8989
return self.handle_pr_reopen()
9090
else:
9191
print(f"Event type '{self.event_name}'" " not supported")
92-
return False
92+
return True
9393
except Exception as e:
9494
print(f"Error in main execution: {e}")
9595
return False
@@ -113,15 +113,15 @@ def handle_contributor_activity(self):
113113
return False
114114
if not issue_data.get("pull_request"):
115115
print("Comment is on an issue," " not a PR, skipping")
116-
return False
116+
return True
117117
pr = self.repo.get_pull(pr_number)
118118
if not pr.user or commenter != pr.user.login:
119119
print("Comment not from PR author, skipping")
120-
return False
120+
return True
121121
labels = [label.name for label in pr.get_labels()]
122122
if "stale" not in labels:
123123
print("PR is not stale, skipping")
124-
return False
124+
return True
125125
try:
126126
pr.remove_from_labels("stale")
127127
print("Removed stale label")
@@ -169,7 +169,7 @@ def run(self):
169169
return self.handle_contributor_activity()
170170
else:
171171
print(f"Event type '{self.event_name}'" " not supported")
172-
return False
172+
return True
173173
except Exception as e:
174174
print(f"Error in main execution: {e}")
175175
return False

.github/actions/bot-autoassign/stale_pr_bot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def unassign_linked_issues(self, pr):
144144
def close_stale_pr(self, pr, days_inactive):
145145
if pr.state == "closed":
146146
print(f"PR #{pr.number} is already closed, skipping")
147-
return False
147+
return True
148148
try:
149149
pr_author = pr.user.login if pr.user else None
150150
if not pr_author:

.github/actions/bot-autoassign/tests/test_issue_assignment_bot.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ def test_skip_pr_comment(self, bot_env):
291291
},
292292
}
293293
)
294-
assert not bot.handle_issue_comment()
294+
assert bot.handle_issue_comment()
295295

296296
def test_non_assignment_comment(self, bot_env):
297297
bot = IssueAssignmentBot()
@@ -304,7 +304,7 @@ def test_non_assignment_comment(self, bot_env):
304304
},
305305
}
306306
)
307-
assert not bot.handle_issue_comment()
307+
assert bot.handle_issue_comment()
308308

309309
def test_no_payload(self, bot_env):
310310
bot = IssueAssignmentBot()
@@ -373,6 +373,22 @@ def test_closed(self, bot_env):
373373
assert bot.handle_pull_request()
374374
mock_issue.remove_from_assignees.assert_called_once_with("testuser")
375375

376+
def test_merged_does_not_unassign(self, bot_env):
377+
bot = IssueAssignmentBot()
378+
bot.load_event_payload(
379+
{
380+
"action": "closed",
381+
"pull_request": {
382+
"number": 100,
383+
"user": {"login": "testuser"},
384+
"body": "Fixes #123",
385+
"merged": True,
386+
},
387+
}
388+
)
389+
assert bot.handle_pull_request()
390+
bot_env["repo"].get_issue.assert_not_called()
391+
376392
def test_unsupported_action(self, bot_env):
377393
bot = IssueAssignmentBot()
378394
bot.load_event_payload(
@@ -385,7 +401,7 @@ def test_unsupported_action(self, bot_env):
385401
},
386402
}
387403
)
388-
assert not bot.handle_pull_request()
404+
assert bot.handle_pull_request()
389405

390406

391407
class TestRun:
@@ -431,7 +447,7 @@ def test_pull_request_event(self, bot_env):
431447
def test_unsupported_event(self, bot_env):
432448
bot = IssueAssignmentBot()
433449
bot.event_name = "push"
434-
assert not bot.run()
450+
assert bot.run()
435451

436452
def test_no_github_client(self, bot_env):
437453
bot = IssueAssignmentBot()

.github/actions/bot-autoassign/tests/test_pr_reopen_bot.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def test_handle_pr_reopen_no_payload(self, bot_env):
108108
def test_run_unsupported_event(self, bot_env):
109109
bot = PRReopenBot()
110110
bot.event_name = "push"
111-
assert not bot.run()
111+
assert bot.run()
112112

113113

114114
class TestPRActivityBot:
@@ -160,7 +160,7 @@ def test_handle_contributor_activity_not_author(self, bot_env):
160160
mock_pr = Mock()
161161
mock_pr.user.login = "testuser"
162162
bot_env["repo"].get_pull.return_value = mock_pr
163-
assert not bot.handle_contributor_activity()
163+
assert bot.handle_contributor_activity()
164164

165165
def test_handle_contributor_activity_pr_not_stale(self, bot_env):
166166
bot = PRActivityBot()
@@ -177,7 +177,7 @@ def test_handle_contributor_activity_pr_not_stale(self, bot_env):
177177
mock_pr.user.login = "testuser"
178178
mock_pr.get_labels.return_value = []
179179
bot_env["repo"].get_pull.return_value = mock_pr
180-
assert not bot.handle_contributor_activity()
180+
assert bot.handle_contributor_activity()
181181

182182
def test_handle_contributor_activity_not_pr(self, bot_env):
183183
bot = PRActivityBot()
@@ -190,7 +190,7 @@ def test_handle_contributor_activity_not_pr(self, bot_env):
190190
"comment": {"user": {"login": "testuser"}},
191191
}
192192
)
193-
assert not bot.handle_contributor_activity()
193+
assert bot.handle_contributor_activity()
194194

195195
def test_handle_contributor_activity_no_payload(self, bot_env):
196196
bot = PRActivityBot()
@@ -199,4 +199,4 @@ def test_handle_contributor_activity_no_payload(self, bot_env):
199199
def test_run_unsupported_event(self, bot_env):
200200
bot = PRActivityBot()
201201
bot.event_name = "push"
202-
assert not bot.run()
202+
assert bot.run()

.github/actions/bot-autoassign/tests/test_stale_pr_bot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def test_already_closed(self, bot_env):
231231
bot = StalePRBot()
232232
mock_pr = Mock()
233233
mock_pr.state = "closed"
234-
assert not bot.close_stale_pr(mock_pr, 60)
234+
assert bot.close_stale_pr(mock_pr, 60)
235235
mock_pr.create_issue_comment.assert_not_called()
236236
mock_pr.edit.assert_not_called()
237237

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: "OpenWISP Changelog Generator"
2+
description: "Analyzes a PR and generates a RestructuredText changelog entry suggestion"
3+
author: "OpenWISP"
4+
5+
inputs:
6+
github-token:
7+
description: "GitHub token for API access"
8+
required: true
9+
gemini-api-key:
10+
description: "Google Gemini API key"
11+
required: true
12+
pr-number:
13+
description: "Pull request number to analyze"
14+
required: true
15+
repo-name:
16+
description: "Repository name in format owner/repo"
17+
required: true
18+
19+
runs:
20+
using: "composite"
21+
steps:
22+
- name: Set up Python
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: "3.13"
26+
27+
- name: Install dependencies
28+
shell: bash
29+
run: pip install "openwisp-utils[github_actions] @ https://github.com/openwisp/openwisp-utils/archive/refs/heads/master.tar.gz"
30+
31+
- name: Generate changelog entry
32+
id: generate
33+
shell: bash
34+
env:
35+
PR_NUMBER: ${{ inputs.pr-number }}
36+
REPO_NAME: ${{ inputs.repo-name }}
37+
GITHUB_TOKEN: ${{ inputs.github-token }}
38+
GEMINI_API_KEY: ${{ inputs.gemini-api-key }}
39+
run: |
40+
python ${{ github.action_path }}/generate_changelog.py
41+
42+
branding:
43+
icon: "file-text"
44+
color: "orange"

0 commit comments

Comments
 (0)