Skip to content

Commit e7846fb

Browse files
committed
landing_job: add method to show pr landing status (bug 2032164)
1 parent 81de22c commit e7846fb

2 files changed

Lines changed: 41 additions & 23 deletions

File tree

src/lando/api/views.py

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import json
2-
from collections import defaultdict
32
from datetime import datetime
43
from functools import wraps
54
from typing import Callable
@@ -21,7 +20,7 @@
2120
Revision,
2221
add_revisions_to_job,
2322
)
24-
from lando.main.models.landing_job import get_jobs_for_pull
23+
from lando.main.models.landing_job import get_pull_request_last_landing_job_status
2524
from lando.main.models.revision import DiffWarning, DiffWarningStatus
2625
from lando.main.scm import SCMType
2726
from lando.utils.github import GitHubAPIClient, PullRequest, PullRequestPatchHelper
@@ -200,26 +199,9 @@ def get(
200199
self, request: WSGIRequest, repo_name: int, pull_number: int
201200
) -> JsonResponse:
202201
"""Return the status of a pull request based on landing job counts."""
203-
204-
target_repo = Repo.objects.get(name=repo_name)
205-
landing_jobs = get_jobs_for_pull(target_repo, pull_number)
206-
landing_jobs_by_status = defaultdict(list)
207-
for landing_job in landing_jobs:
208-
landing_jobs_by_status[landing_job.status].append(landing_job.id)
209-
210-
status = None
211-
# Return the first encountered status in this list.
212-
for _status in [
213-
JobStatus.LANDED,
214-
JobStatus.CREATED,
215-
JobStatus.SUBMITTED,
216-
JobStatus.IN_PROGRESS,
217-
JobStatus.FAILED,
218-
]:
219-
if landing_jobs_by_status[_status]:
220-
status = str(_status).lower()
221-
break
222-
202+
status = str(
203+
get_pull_request_last_landing_job_status(repo_name, pull_number)
204+
).lower()
223205
return JsonResponse({"status": status}, status=200)
224206

225207
@method_decorator(require_authenticated_user)

src/lando/main/models/landing_job.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import datetime
22
import logging
3+
from collections import defaultdict
34
from collections.abc import Iterable
45
from pathlib import Path
56
from typing import Any
@@ -10,7 +11,7 @@
1011
from mots.config import FileConfig
1112
from mots.directory import Directory
1213

13-
from lando.main.models.jobs import BaseJob
14+
from lando.main.models.jobs import BaseJob, JobStatus
1415
from lando.main.models.repo import Repo
1516
from lando.main.models.revision import Revision, RevisionLandingJob
1617

@@ -304,6 +305,41 @@ def add_revisions_to_job(revisions: list[Revision], job: LandingJob):
304305
job.sort_revisions(revisions)
305306

306307

308+
def get_pull_request_last_landing_job_status(
309+
repo_name: str, pull_number: int
310+
) -> JobStatus:
311+
"""Return a heuristically determined status based on related jobs."""
312+
target_repo = Repo.objects.get(name=repo_name)
313+
landing_jobs = get_jobs_for_pull(target_repo, pull_number)
314+
landing_jobs_by_status = defaultdict(list)
315+
for landing_job in landing_jobs:
316+
landing_jobs_by_status[landing_job.status].append(landing_job.id)
317+
318+
# A LANDED status implies that the pull request has landed. A
319+
# DEFERRED status implies that the last job has been deferred.
320+
# For all other cases, there may be other permanently failed landing
321+
# jobs that are no longer relevant to the status of the pull request as
322+
# a whole.
323+
324+
# A CREATED status implies that the latest landing job is created.
325+
# A SUBMITTED status implies that the latest landing job is submitted.
326+
# An IN_PROGRESS status implies that the latest landing job is in progress.
327+
# A FAILED status implies that the latest landing job has failed.
328+
329+
# Return the first encountered status in this list.
330+
for _status in [
331+
JobStatus.LANDED,
332+
JobStatus.CREATED,
333+
JobStatus.SUBMITTED,
334+
JobStatus.IN_PROGRESS,
335+
JobStatus.DEFERRED,
336+
JobStatus.FAILED,
337+
JobStatus.CANCELLED,
338+
]:
339+
if landing_jobs_by_status[_status]:
340+
return _status
341+
342+
307343
def get_jobs_for_pull(target_repo: Repo, pull_number: int) -> QuerySet[LandingJob]:
308344
"""Given a target repo and a pull number, return all landing jobs."""
309345
revisions = Revision.objects.filter(

0 commit comments

Comments
 (0)