Skip to content

Commit 1ad1ecc

Browse files
[ADD] ocabot migration issue maintainer
New ocabot command for maintaining migration issues: ``/ocabot migration``, followed by the module name, performing the following: * Look for an issue in that repository with the name "Migration to version ``{version}``", where ``{version}`` is the name of the target branch. * Add or edit a line in that issue, linking the module to the pull request (PR) and the author of it. * TODO: When the PR is merged, the line gets ticked. * Put the milestone corresponding to the target branch in the PR. Co-authored-by: Pedro M. Baeza <[email protected]>
1 parent 9e7221d commit 1ad1ecc

9 files changed

+3323
-1
lines changed

Diff for: README.rst

+11
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ can be used to ask the bot to do the following:
8989

9090
* rebase the PR on the target branch
9191

92+
``/ocabot migration``, followed by the module name, performing the following:
93+
94+
* Look for an issue in that repository with the name "Migration to version
95+
``{version}``", where ``{version}`` is the name of the target branch.
96+
* Add or edit a line in that issue, linking the module to the pull request
97+
(PR) and the author of it.
98+
* TODO: When the PR is merged, the line gets ticked.
99+
* Put the milestone corresponding to the target branch in the PR.
100+
92101
TODO (help wanted)
93102
------------------
94103

@@ -215,6 +224,8 @@ Contributors
215224
* Jose Angel Fentanez <[email protected]>
216225
* Simone Rubino <[email protected]>
217226
* Sylvain Le Gal (https://twitter.com/legalsylvain)
227+
* Tecnativa - Pedro M. Baeza
228+
* Tecnativa - Víctor Martínez
218229

219230
Maintainers
220231
===========

Diff for: src/oca_github_bot/commands.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import re
55

6-
from .tasks import merge_bot, rebase_bot
6+
from .tasks import merge_bot, migration_issue_bot, rebase_bot
77

88
BOT_COMMAND_RE = re.compile(
99
# Do not start with > (Github comment), not consuming it
@@ -61,6 +61,8 @@ def create(cls, name, options):
6161
return BotCommandMerge(name, options)
6262
elif name == "rebase":
6363
return BotCommandRebase(name, options)
64+
elif name == "migration":
65+
return BotCommandMigrationIssue(name, options)
6466
else:
6567
raise InvalidCommandError(name)
6668

@@ -102,6 +104,21 @@ def delay(self, org, repo, pr, username, dry_run=False):
102104
rebase_bot.rebase_bot_start.delay(org, repo, pr, username, dry_run=False)
103105

104106

107+
class BotCommandMigrationIssue(BotCommand):
108+
module = None # mandatory str: module name
109+
110+
def parse_options(self, options):
111+
if len(options) == 1:
112+
self.module = options[0]
113+
else:
114+
raise InvalidOptionsError(self.name, options)
115+
116+
def delay(self, org, repo, pr, username, dry_run=False):
117+
migration_issue_bot.migration_issue_start.delay(
118+
org, repo, pr, username, module=self.module, dry_run=dry_run
119+
)
120+
121+
105122
def parse_commands(text):
106123
""" Parse a text and return an iterator of BotCommand objects. """
107124
for mo in BOT_COMMAND_RE.finditer(text):

Diff for: src/oca_github_bot/config.py

+6
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ def func_wrapper(*args, **kwargs):
5454

5555
DRY_RUN = os.environ.get("DRY_RUN", "").lower() in ("1", "true", "yes")
5656

57+
# Coma separated list of task to run
58+
# By default all configured tasks are run.
59+
# Available tasks:
60+
# delete_branch,tag_approved,tag_ready_to_merge,gen_addons_table,
61+
# gen_addons_readme,gen_addons_icon,setuptools_odoo,merge_bot,tag_needs_review,
62+
# migration_issue_bot
5763
BOT_TASKS = os.environ.get("BOT_TASKS", "all").split(",")
5864

5965
BOT_TASKS_DISABLED = os.environ.get("BOT_TASKS_DISABLED", "").split(",")

Diff for: src/oca_github_bot/tasks/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
heartbeat,
66
main_branch_bot,
77
mention_maintainer,
8+
migration_issue_bot,
89
tag_approved,
910
tag_needs_review,
1011
tag_ready_to_merge,

Diff for: src/oca_github_bot/tasks/migration_issue_bot.py

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Copyright 2019 Tecnativa - Pedro M. Baeza
2+
# Copyright 2021 Tecnativa - Víctor Martínez
3+
# Distributed under the MIT License (http://opensource.org/licenses/MIT).
4+
5+
import re
6+
7+
from .. import github
8+
from ..config import switchable
9+
from ..process import check_call
10+
from ..queue import getLogger, task
11+
from ..manifest import user_can_push
12+
13+
_logger = getLogger(__name__)
14+
15+
16+
def _create_or_find_branch_milestone(repo, branch):
17+
for milestone in repo.milestones():
18+
if milestone.title == branch:
19+
return milestone
20+
return repo.create_milestone(branch)
21+
22+
23+
def _find_issue(repo, milestone, target_branch):
24+
issue_title = f"Migration to version {target_branch}"
25+
issue = False
26+
for i in repo.issues(milestone=milestone.number):
27+
if i.title == issue_title:
28+
issue = i
29+
break
30+
return issue
31+
32+
33+
def _set_lines_issue(gh_pr, issue, module):
34+
lines = []
35+
added = False
36+
module_list = False
37+
new_line = f"- [ ] {module} - By @{gh_pr.user.login} - #{gh_pr.number}"
38+
for line in issue.body.split("\n"):
39+
if line.startswith(f"- [ ] {module}"):
40+
lines.append(new_line)
41+
continue
42+
elif not added:
43+
splits = re.split(r"- \[ \] ([0-9a-zA-Z_]*)", line)
44+
if len(splits) >= 2:
45+
# Flag for detecting if we have passed already module list
46+
module_list = True
47+
line_module = splits[1]
48+
if line_module > module:
49+
lines.append(new_line)
50+
added = True
51+
elif module_list:
52+
lines.append(new_line)
53+
added = True
54+
lines.append(line)
55+
return lines
56+
57+
58+
@task()
59+
@switchable("migration_issue_bot")
60+
def migration_issue_start(org, repo, pr, username, module=None, dry_run=False):
61+
with github.login() as gh:
62+
gh_pr = gh.pull_request(org, repo, pr)
63+
target_branch = gh_pr.base.ref
64+
pr_branch = f"tmp-pr-{pr}"
65+
try:
66+
with github.temporary_clone(org, repo, target_branch) as clone_dir:
67+
# Create merge bot branch from PR and rebase it on target branch
68+
# This only serves for checking permissions
69+
check_call(
70+
["git", "fetch", "origin", f"pull/{pr}/head:{pr_branch}"],
71+
cwd=clone_dir,
72+
)
73+
check_call(["git", "checkout", pr_branch], cwd=clone_dir)
74+
if not _user_can_push(
75+
gh, org, repo, username, clone_dir, target_branch
76+
):
77+
github.gh_call(
78+
gh_pr.create_comment,
79+
f"Sorry @{username} you are not allowed to mark the addon to"
80+
f"be migrated.\n\n"
81+
f"To do so you must either have push permissions on "
82+
f"the repository, or be a declared maintainer of all "
83+
f"modified addons.\n\n"
84+
f"If you wish to adopt an addon and become it's "
85+
f"[maintainer]"
86+
f"(https://odoo-community.org/page/maintainer-role), "
87+
f"open a pull request to add "
88+
f"your GitHub login to the `maintainers` key of its "
89+
f"manifest.",
90+
)
91+
return
92+
# Assign milestone to PR
93+
milestone = _create_or_find_branch_milestone(repo, target_branch)
94+
gh_pr.issue().edit(milestone=milestone.number)
95+
# Find issue
96+
issue = _find_issue(repo, milestone, target_branch)
97+
if not issue:
98+
issue_title = f"Migration to version {target_branch}"
99+
github.gh_call(
100+
gh_pr.create_comment,
101+
f"There's no issue in this repo with the title '{issue_title}' "
102+
f"and the milestone {target_branch}, so not possible to add "
103+
f"the comment.",
104+
)
105+
return
106+
# Change issue to add the PR in the module list
107+
lines = _set_lines_issue(gh_pr, issue, module)
108+
issue.edit(body="\n".join(lines))
109+
except Exception as e:
110+
github.gh_call(
111+
gh_pr.create_comment,
112+
f"@{username} The migration issue commenter process could not "
113+
f"start, because of exception {e}.",
114+
)
115+
raise

0 commit comments

Comments
 (0)