Skip to content

Commit

Permalink
Merge pull request #97 from Tecnativa/migration_maintainer
Browse files Browse the repository at this point in the history
[ADD] ocabot migration issue maintainer
  • Loading branch information
sbidoul authored Nov 13, 2021
2 parents 9e7221d + 872e3b8 commit 016b10c
Show file tree
Hide file tree
Showing 9 changed files with 3,351 additions and 1 deletion.
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@ can be used to ask the bot to do the following:

* rebase the PR on the target branch

``/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.

TODO (help wanted)
------------------

Expand Down Expand Up @@ -215,6 +224,8 @@ Contributors
* Jose Angel Fentanez <joseangel@vauxoo.com>
* Simone Rubino <simone.rubino@agilebg.com>
* Sylvain Le Gal (https://twitter.com/legalsylvain)
* Tecnativa - Pedro M. Baeza
* Tecnativa - Víctor Martínez

Maintainers
===========
Expand Down
19 changes: 18 additions & 1 deletion src/oca_github_bot/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import re

from .tasks import merge_bot, rebase_bot
from .tasks import merge_bot, migration_issue_bot, rebase_bot

BOT_COMMAND_RE = re.compile(
# Do not start with > (Github comment), not consuming it
Expand Down Expand Up @@ -61,6 +61,8 @@ def create(cls, name, options):
return BotCommandMerge(name, options)
elif name == "rebase":
return BotCommandRebase(name, options)
elif name == "migration":
return BotCommandMigrationIssue(name, options)
else:
raise InvalidCommandError(name)

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


class BotCommandMigrationIssue(BotCommand):
module = None # mandatory str: module name

def parse_options(self, options):
if len(options) == 1:
self.module = options[0]
else:
raise InvalidOptionsError(self.name, options)

def delay(self, org, repo, pr, username, dry_run=False):
migration_issue_bot.migration_issue_start.delay(
org, repo, pr, username, module=self.module, dry_run=dry_run
)


def parse_commands(text):
""" Parse a text and return an iterator of BotCommand objects. """
for mo in BOT_COMMAND_RE.finditer(text):
Expand Down
6 changes: 6 additions & 0 deletions src/oca_github_bot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ def func_wrapper(*args, **kwargs):

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

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

BOT_TASKS_DISABLED = os.environ.get("BOT_TASKS_DISABLED", "").split(",")
Expand Down
1 change: 1 addition & 0 deletions src/oca_github_bot/tasks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
heartbeat,
main_branch_bot,
mention_maintainer,
migration_issue_bot,
tag_approved,
tag_needs_review,
tag_ready_to_merge,
Expand Down
113 changes: 113 additions & 0 deletions src/oca_github_bot/tasks/migration_issue_bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Copyright 2019 Tecnativa - Pedro M. Baeza
# Copyright 2021 Tecnativa - Víctor Martínez
# Distributed under the MIT License (http://opensource.org/licenses/MIT).

import re

from .. import github
from ..config import switchable
from ..manifest import user_can_push
from ..process import check_call
from ..queue import getLogger, task

_logger = getLogger(__name__)


def _create_or_find_branch_milestone(repo, branch):
for milestone in repo.milestones():
if milestone.title == branch:
return milestone
return repo.create_milestone(branch)


def _find_issue(repo, milestone, target_branch):
issue_title = f"Migration to version {target_branch}"
issue = False
for i in repo.issues(milestone=milestone.number):
if i.title == issue_title:
issue = i
break
return issue


def _set_lines_issue(gh_pr, issue, module):
lines = []
added = False
module_list = False
new_line = f"- [ ] {module} - By @{gh_pr.user.login} - #{gh_pr.number}"
for line in issue.body.split("\n"):
if line.startswith(f"- [ ] {module}"):
lines.append(new_line)
continue
elif not added:
splits = re.split(r"- \[ \] ([0-9a-zA-Z_]*)", line)
if len(splits) >= 2:
# Flag for detecting if we have passed already module list
module_list = True
line_module = splits[1]
if line_module > module:
lines.append(new_line)
added = True
elif module_list:
lines.append(new_line)
added = True
lines.append(line)
return lines


@task()
@switchable("migration_issue_bot")
def migration_issue_start(org, repo, pr, username, module=None, dry_run=False):
with github.login() as gh:
gh_pr = gh.pull_request(org, repo, pr)
target_branch = gh_pr.base.ref
pr_branch = f"tmp-pr-{pr}"
try:
with github.temporary_clone(org, repo, target_branch) as clone_dir:
# Create merge bot branch from PR and rebase it on target branch
# This only serves for checking permissions
check_call(
["git", "fetch", "origin", f"pull/{pr}/head:{pr_branch}"],
cwd=clone_dir,
)
check_call(["git", "checkout", pr_branch], cwd=clone_dir)
if not user_can_push(gh, org, repo, username, clone_dir, target_branch):
github.gh_call(
gh_pr.create_comment,
f"Sorry @{username} you are not allowed to mark the addon to"
f"be migrated.\n\n"
f"To do so you must either have push permissions on "
f"the repository, or be a declared maintainer of all "
f"modified addons.\n\n"
f"If you wish to adopt an addon and become it's "
f"[maintainer]"
f"(https://odoo-community.org/page/maintainer-role), "
f"open a pull request to add "
f"your GitHub login to the `maintainers` key of its "
f"manifest.",
)
return
# Assign milestone to PR
milestone = _create_or_find_branch_milestone(repo, target_branch)
gh_pr.issue().edit(milestone=milestone.number)
# Find issue
issue = _find_issue(repo, milestone, target_branch)
if not issue:
issue_title = f"Migration to version {target_branch}"
github.gh_call(
gh_pr.create_comment,
f"There's no issue in this repo with the title '{issue_title}' "
f"and the milestone {target_branch}, so not possible to add "
f"the comment.",
)
return
# Change issue to add the PR in the module list
lines = _set_lines_issue(gh_pr, issue, module)
issue.edit(body="\n".join(lines))
except Exception as e:
github.gh_call(
gh_pr.create_comment,
f"@{username} The migration issue commenter process could not "
f"start, because of exception {e}.",
)
raise
Loading

0 comments on commit 016b10c

Please sign in to comment.