Showing the changes to apps/server/src/pullRequest/gitLabMergeRequestJson.ts (1 of 3 files). Show all
Unified · Split
| @@ -515,13 +515,6 @@ export function decodeProjectMergeCapabilitiesJson( · 514 unmodified lines | ||
| 515 | 515 | }); |
| 516 | 516 | } |
| 517 | 517 | |
| 518 | −/** | |
| 519 | − * Comments only. System notes are GitLab's own activity feed entries, and a `DiffNote` is the | |
| 520 | − * root of a line-level discussion, which is what the review-comment kind means. | |
| 521 | − * | |
| 522 | − * The raw note count comes back alongside, because dropping notes hides whether the page was | |
| 523 | − * full: a caller cannot tell "no more notes" from "a page of activity entries" without it. | |
| 524 | − */ | |
| 525 | 518 | /** The three revisions a positioned comment is written against. */ |
| 526 | 519 | export interface GitLabDiffRefs { |
| 527 | 520 | readonly baseSha: string; |
| @@ -594,6 +587,21 @@ export function decodeDiffRefsJson( · 66 unmodified lines | ||
| 594 | 587 | ); |
| 595 | 588 | } |
| 596 | 589 | |
| 590 | +function systemNoteReviewState(body: string): "APPROVED" | "DISMISSED" | null { | |
| 591 | + switch (body.trim()) { | |
| 592 | + case "approved this merge request": | |
| 593 | + return "APPROVED"; | |
| 594 | + case "unapproved this merge request": | |
| 595 | + return "DISMISSED"; | |
| 596 | + default: | |
| 597 | + return null; | |
| 598 | + } | |
| 599 | +} | |
| 600 | + | |
| 601 | +/** | |
| 602 | + * Comments and approval history. Other system activity stays excluded. The raw count includes | |
| 603 | + * every note so a page containing only skipped activity does not end pagination early. | |
| 604 | + */ | |
| 597 | 605 | export function decodeNotesJson( |
| 598 | 606 | raw: string, |
| 599 | 607 | ): Result.Result< |
| @@ -609,19 +617,23 @@ export function decodeNotesJson( · 9 unmodified lines | ||
| 609 | 617 | const note = decodeNoteEntry(entry); |
| 610 | 618 | if (Exit.isFailure(note)) continue; |
| 611 | 619 | const value = note.value; |
| 612 | − if (value.system === true) continue; | |
| 613 | 620 | const body = value.body ?? ""; |
| 621 | + const reviewState = value.system === true ? systemNoteReviewState(body) : null; | |
| 622 | + if (value.system === true && reviewState === null) continue; | |
| 614 | 623 | if (body.trim().length === 0) continue; |
| 615 | 624 | const isDiffNote = value.type?.trim() === "DiffNote"; |
| 616 | 625 | comments.push({ |
| 617 | 626 | id: String(value.id), |
| 618 | − kind: isDiffNote ? "review-comment" : "issue-comment", | |
| 627 | + kind: reviewState !== null ? "review" : isDiffNote ? "review-comment" : "issue-comment", | |
| 619 | 628 | author: toActor(value.author), |
| 620 | 629 | body, |
| 621 | 630 | createdAt: value.created_at, |
| 622 | 631 | url: null, |
| 623 | − path: trimmed(value.position?.new_path) ?? trimmed(value.position?.old_path), | |
| 624 | − reviewState: null, | |
| 632 | + path: | |
| 633 | + reviewState !== null | |
| 634 | + ? null | |
| 635 | + : (trimmed(value.position?.new_path) ?? trimmed(value.position?.old_path)), | |
| 636 | + reviewState, | |
| 625 | 637 | }); |
| 626 | 638 | } |
| 627 | 639 | return Result.succeed({ comments, rawCount: decoded.success.length }); |