Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 2x 12x 38x 18x 18x 4x 14x 2x 12x 11x 25x | /**
* GitHub Review State Management
*
* Tracks the bot's previous review state on a PR for dismissal logic.
*/
import type { ReviewState } from '../output/types.js';
const VALID_REVIEW_STATES: ReadonlySet<string> = new Set(['CHANGES_REQUESTED', 'APPROVED', 'COMMENTED']);
function isValidReviewState(state: string): state is ReviewState {
return VALID_REVIEW_STATES.has(state);
}
// -----------------------------------------------------------------------------
// Bot Review History
// -----------------------------------------------------------------------------
/**
* A GitHub review from the API (subset of fields we need).
*/
export interface GitHubReviewInfo {
id: number;
state: string;
user?: { login: string } | null;
}
/**
* The bot's most recent review info (state + review ID for dismissal).
*/
export interface BotReviewInfo {
state: ReviewState;
reviewId: number;
}
/**
* Find the bot's most recent review state on a PR.
*
* Used to determine if we should dismiss a previous REQUEST_CHANGES
* when all issues are now resolved.
*
* Returns null if:
* - Bot has no reviews on this PR
* - Bot's most recent review was DISMISSED (user explicitly cleared it)
*/
export function findBotReviewState(reviews: GitHubReviewInfo[], botLogin: string): BotReviewInfo | null {
// GitHub API returns reviews in chronological order, search from end
for (let i = reviews.length - 1; i >= 0; i--) {
const review = reviews[i];
if (!review?.user || review.user.login !== botLogin) {
continue;
}
// User dismissed our review - don't look at older reviews
if (review.state === 'DISMISSED') {
return null;
}
if (isValidReviewState(review.state)) {
return { state: review.state, reviewId: review.id };
}
}
return null;
}
|