Skip to content
Snippets Groups Projects
Unverified Commit 011b12b9 authored by Pablo Correa Gomez's avatar Pablo Correa Gomez :beach: Committed by Pablo Correa Gómez
Browse files

frontend: add a merge action to avoid using the UI for merging (MR 24)

parent 0ae0c77b
No related branches found
No related tags found
1 merge request!24frontend: instruct how to set MR to automerge on push
......@@ -4,7 +4,7 @@
if [ "$(id -u)" = 0 ]; then
set -x
apk -q add py3-argcomplete py3-mypy
apk -q add py3-argcomplete py3-gitlab py3-mypy
exec su "${TESTUSER:-build}" -c "sh -e $0"
fi
......
......@@ -170,19 +170,8 @@ def print_status(mr_id: Optional[int], no_cache: bool = False) -> None:
if commits_follow_format is None:
print("* Manually check if the commit subjects are correct")
origin = gitlab.parse_git_origin()
remote_local = status.source.split("/", 1)[0]
if remote_local == origin.project:
remote_local = "origin"
print("* Pretty 'git log -" + str(len(commits)) + " --pretty'?" + " (consider copying MR desc)")
print(
f"* Push your changes ('git push --force {remote_local} HEAD:" f"{status.source_branch}')"
)
print("* Web UI: comment about your reviewing and testing")
print("* Web UI: approve MR")
print("* Web UI: do (automatic) merge")
print("* Finish the MR: push, approve, merge, comment ('mrhlpr finish')")
def parse_args() -> argparse.Namespace:
......@@ -241,6 +230,16 @@ def parse_args() -> argparse.Namespace:
help=f"add message to last commit: {ci_labels['skip_vercheck']}",
)
# finish
finish = sub.add_parser("finish", help="help finishing the MR (push, approve, merge...)")
finish.add_argument(
"-c",
"--comment",
type=str,
nargs="?",
help="comment to post before merging to thank author",
)
if "argcomplete" in sys.modules:
argcomplete.autocomplete(parser, always_complete_options="long")
return parser.parse_args()
......@@ -260,3 +259,11 @@ def main():
mr_id = mr.checked_out()
mr.fixmsg(mr_id, args.skip_build, args.ignore_count, args.skip_vercheck)
print_status(mr_id)
elif args.action == "finish":
mr_id = mr.checked_out()
# TODO: Check that everything passed
comment = args.comment
if not comment:
comment = input("Provide a thank you comment (discouraged, but can be empty): ")
mr.finish(mr_id, comment, args.no_cache)
print_status(mr_id)
......@@ -115,3 +115,21 @@ def topdir() -> str:
msg = "Something went wrong when getting current branch name"
raise RuntimeError(msg)
return ret
def sha() -> str:
""":returns: current SHA"""
ret = run(["rev-parse"])
if ret is None:
msg = "Something went wrong when getting current commit SHA"
raise RuntimeError(msg)
return ret
def push_head(remote: str, branch: str) -> None:
"""Push HEAD to branch in remote"""
ret = run(["push", "--force-with-lease", remote, "HEAD:" + branch])
if ret is None:
msg = f"Something went wrong when pushing HEAD to branch '{branch}' in remote '{remote}'"
raise RuntimeError(msg)
print(ret)
......@@ -8,9 +8,15 @@ import os
import re
import subprocess
import sys
import time
from dataclasses import dataclass
from typing import Any, Optional
try:
import gitlab as gitlab_api
except ImportError:
pass
from . import ci_labels # type: ignore[attr-defined]
from . import git
from . import gitlab
......@@ -436,3 +442,41 @@ def fixmsg(
if skip_vercheck:
print("Appending [ci:skip-vercheck] to last commit...")
run_git_filter_branch("msg_filter_add_label.py", "HEAD~1", label="skip_vercheck")
def finish(mr_id: int, comment: str | None, no_cache: bool = False):
if "gitlab" not in sys.modules:
logging.error("python-gitlab is needed to run 'finish'")
exit(1)
print("Pushing changes...")
status = get_status(mr_id, no_cache)
origin = gitlab.parse_git_origin()
remote_local = status.source.split("/", 1)[0]
if remote_local == origin.project:
remote_local = "origin"
git.push_head(remote_local, status.source_branch)
gl = gitlab_api.Gitlab(url="https://gitlab.com", private_token=os.environ["GITLAB_TOKEN"])
project = gl.projects.get(origin.project_id)
mr = project.mergerequests.get(mr_id)
print("Approving MR...")
try:
mr.approve(git.sha())
# For some reason, approve fails with auth error if already approved...
except gitlab_api.GitlabAuthenticationError as e:
approved_by_ids = [ap["id"] for ap in mr.approval_state.get().rules[0]["approved_by"]]
gl.auth()
if gl.user is None:
raise e
if gl.user.id not in approved_by_ids:
raise RuntimeError("Approving failed, and MR not yet approved") from e
if comment:
print("Adding the comment...")
mr.notes.create({"body": comment})
# Give gitlab some time to process the push, it sometimes struggles
time.sleep(5)
print("Setting to auto-merge...")
mr.merge(merge_when_pipeline_succeeds=True)
......@@ -30,6 +30,7 @@ mrtest = "mrtest.frontend:main"
[project.optional-dependencies]
completion = ["argcomplete"]
api = ["python-gitlab>=4.0.0"]
[project.urls]
Homepage = "https://www.postmarketos.org"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment