Skip to content

Commit dc0dbfc

Browse files
committed
add gitlab_repo_merge_request
Signed-off-by: Feng Huang <fehuang@redhat.com>
1 parent b8eb92e commit dc0dbfc

File tree

3 files changed

+110
-3
lines changed

3 files changed

+110
-3
lines changed

reconcile/queries.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1748,7 +1748,7 @@ def get_repos_gitlab_housekeeping(server: str = "") -> list[dict[str, Any]]:
17481748
"""
17491749
code_components = get_code_components()
17501750
return [
1751-
{"url": c["url"], "housekeeping": c["gitlabHousekeeping"]}
1751+
{"name": c["name"], "url": c["url"], "housekeeping": c["gitlabHousekeeping"]}
17521752
for c in code_components
17531753
if c["url"].startswith(server)
17541754
and c["gitlabHousekeeping"]

reconcile/utils/gitlab_api.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,12 @@ def get_issues(self, state: str) -> list[ProjectIssue]:
401401
def get_merge_request(self, mr_id: str | int) -> ProjectMergeRequest:
402402
return self.project.mergerequests.get(mr_id)
403403

404-
def get_merge_requests(self, state: str) -> list[ProjectMergeRequest]:
405-
return self.project.mergerequests.list(state=state, get_all=True)
404+
def get_merge_requests(
405+
self, state: str, order_by: str = "created_at"
406+
) -> list[ProjectMergeRequest]:
407+
return self.project.mergerequests.list(
408+
state=state, order_by=order_by, get_all=True
409+
)
406410

407411
@staticmethod
408412
def get_merge_request_label_events(

tools/qontract_cli.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2249,6 +2249,109 @@ def sre_checkpoints(ctx: click.Context) -> None:
22492249
print_output(ctx.obj["options"], checkpoints_data, columns)
22502250

22512251

2252+
@get.command()
2253+
@click.pass_context
2254+
@click.option(
2255+
"--repo-name",
2256+
help="Specifies the gitlab repo name",
2257+
type=str,
2258+
)
2259+
@click.option(
2260+
"--ignore-awaiting-approval",
2261+
help="Ignore MR awaiting approval",
2262+
default=False,
2263+
type=bool,
2264+
)
2265+
def gitlab_repo_merge_request(
2266+
ctx: click.Context,
2267+
repo_name: str,
2268+
ignore_awaiting_approval: bool,
2269+
) -> None:
2270+
import reconcile.gitlab_housekeeping as glhk
2271+
2272+
instance = queries.get_gitlab_instance()
2273+
settings = queries.get_app_interface_settings()
2274+
repos = [
2275+
r
2276+
for r in queries.get_repos_gitlab_housekeeping(server=instance["url"])
2277+
if r["name"] == repo_name
2278+
]
2279+
if len(repos) != 1:
2280+
print(f"{repo_name} name error")
2281+
sys.exit(1)
2282+
2283+
repo = repos[0]
2284+
hk = repo["housekeeping"]
2285+
must_pass = hk.get("must_pass")
2286+
rebase = hk.get("rebase")
2287+
gl = GitLabApi(instance, project_url=repo["url"], settings=settings)
2288+
state = init_state(integration=glhk.QONTRACT_INTEGRATION)
2289+
merge_requests = gl.get_merge_requests(state=MRState.OPENED, order_by="updated_at")
2290+
2291+
columns = [
2292+
"id",
2293+
"title",
2294+
"author",
2295+
"labels",
2296+
"merge_status",
2297+
]
2298+
if must_pass:
2299+
columns.append("remaining_tests")
2300+
merge_queue_data = []
2301+
for mr in merge_requests:
2302+
pipelines = gl.get_merge_request_pipelines(mr)
2303+
running_pipelines = [p for p in pipelines if p.status == PipelineStatus.RUNNING]
2304+
last_pipeline_result = None
2305+
if pipelines:
2306+
last_pipeline_result = pipelines[0].status
2307+
if must_pass:
2308+
commit = next(mr.commits())
2309+
state_key = f"{gl.project.path_with_namespace}/{mr.iid}/{commit.id}"
2310+
remaining_tests = state.get(state_key, must_pass)
2311+
2312+
merge_status = ""
2313+
if mr.merge_status in {
2314+
MRStatus.CANNOT_BE_MERGED,
2315+
MRStatus.CANNOT_BE_MERGED_RECHECK,
2316+
}:
2317+
# https://docs.gitlab.com/api/merge_requests/#merge-status
2318+
merge_status = mr.detailed_merge_status
2319+
elif mr.draft:
2320+
merge_status = "draft_status"
2321+
elif len(mr.commits()) == 0:
2322+
merge_status = "contains_no_changes"
2323+
elif must_pass and remaining_tests:
2324+
merge_status = "has_remain_tests"
2325+
elif any(label in glhk.HOLD_LABELS for label in mr.labels):
2326+
merge_status = "hold"
2327+
elif not any(label in glhk.MERGE_LABELS_PRIORITY for label in mr.labels):
2328+
if ignore_awaiting_approval:
2329+
continue
2330+
merge_status = "awaiting_approval"
2331+
elif rebase and not glhk.is_rebased(mr, gl):
2332+
merge_status = "needs_rebase"
2333+
elif not pipelines:
2334+
merge_status = "no_pipelines"
2335+
elif running_pipelines:
2336+
merge_status = "pipeline_running"
2337+
elif last_pipeline_result != PipelineStatus.SUCCESS:
2338+
merge_status = "last_pipeline_failed"
2339+
2340+
item = {
2341+
"id": f"[{mr.iid}]({mr.web_url})",
2342+
"title": mr.title,
2343+
"author": mr.author["username"],
2344+
"labels": ", ".join(mr.labels),
2345+
"merge_status": merge_status,
2346+
}
2347+
if must_pass:
2348+
item["remaining_tests"] = ", ".join(remaining_tests)
2349+
merge_queue_data.append(item)
2350+
2351+
ctx.obj["options"]["sort"] = False # do not sort
2352+
print_output(ctx.obj["options"], merge_queue_data, columns)
2353+
2354+
22522355
@get.command()
22532356
@click.pass_context
22542357
def app_interface_merge_queue(ctx: click.Context) -> None:

0 commit comments

Comments
 (0)