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 | /** The three revisions a positioned comment is written against. */ | 518 | /** The three revisions a positioned comment is written against. */ |
| 526 | export interface GitLabDiffRefs { | 519 | export interface GitLabDiffRefs { |
| 527 | readonly baseSha: string; | 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 | export function decodeNotesJson( | 605 | export function decodeNotesJson( |
| 598 | raw: string, | 606 | raw: string, |
| 599 | ): Result.Result< | 607 | ): Result.Result< |
| @@ -609,19 +617,23 @@ export function decodeNotesJson( · 9 unmodified lines | |||
| 609 | const note = decodeNoteEntry(entry); | 617 | const note = decodeNoteEntry(entry); |
| 610 | if (Exit.isFailure(note)) continue; | 618 | if (Exit.isFailure(note)) continue; |
| 611 | const value = note.value; | 619 | const value = note.value; |
| 612 | if (value.system === true) continue; | ||
| 613 | const body = value.body ?? ""; | 620 | const body = value.body ?? ""; |
| 621 | const reviewState = value.system === true ? systemNoteReviewState(body) : null; | ||
| 622 | if (value.system === true && reviewState === null) continue; | ||
| 614 | if (body.trim().length === 0) continue; | 623 | if (body.trim().length === 0) continue; |
| 615 | const isDiffNote = value.type?.trim() === "DiffNote"; | 624 | const isDiffNote = value.type?.trim() === "DiffNote"; |
| 616 | comments.push({ | 625 | comments.push({ |
| 617 | id: String(value.id), | 626 | id: String(value.id), |
| 618 | kind: isDiffNote ? "review-comment" : "issue-comment", | 627 | kind: reviewState !== null ? "review" : isDiffNote ? "review-comment" : "issue-comment", |
| 619 | author: toActor(value.author), | 628 | author: toActor(value.author), |
| 620 | body, | 629 | body, |
| 621 | createdAt: value.created_at, | 630 | createdAt: value.created_at, |
| 622 | url: null, | 631 | url: null, |
| 623 | path: trimmed(value.position?.new_path) ?? trimmed(value.position?.old_path), | 632 | path: |
| 624 | reviewState: null, | 633 | reviewState !== null |
| 634 | ? null | ||
| 635 | : (trimmed(value.position?.new_path) ?? trimmed(value.position?.old_path)), | ||
| 636 | reviewState, | ||
| 625 | }); | 637 | }); |
| 626 | } | 638 | } |
| 627 | return Result.succeed({ comments, rawCount: decoded.success.length }); | 639 | return Result.succeed({ comments, rawCount: decoded.success.length }); |