Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions src/signals/local-branch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import { simulateOpenPrPressure } from "../services/open-pr-pressure-scenarios";
import { isCodeFile, isTestFile } from "./path-matchers";
import { isMaintainerAuthorAssociation } from "../github/author-association";

const SCORE_PREVIEW_BLOCKING_WARNING_PATTERN = /not registered|no active|exceeds|credibility|token gate|confirmed ineligible/i;

export type LocalBranchChangedFile = {
path: string;
previousPath?: string | undefined;
Expand Down Expand Up @@ -356,7 +358,7 @@ export function buildLocalBranchAnalysis(args: {
});
const scoreBlockers = [
...rewardRisk.scoreBlockers,
...scorePreview.warnings.filter((warning) => /not registered|no active|exceeds|credibility|token gate|confirmed ineligible/i.test(warning)),
...scorePreview.warnings.filter((warning) => SCORE_PREVIEW_BLOCKING_WARNING_PATTERN.test(warning)),
...preflight.findings.filter((finding) => finding.severity !== "info").map((finding) => finding.title),
];
const eligibilityPlan = deriveEligibilityPlan(scorePreview);
Expand Down Expand Up @@ -789,6 +791,15 @@ function isApprovedOrMergeableOpenPr(pr: PullRequestRecord): boolean {
return reviewDecision === "approved" || ["clean", "has_hooks", "mergeable", "mergeable_state_clean"].includes(mergeableState);
}

function scorePreviewWarningFinding(warning: string): LocalBranchAnalysis["localFindings"][number] {
return {
code: "score_preview_warning",
severity: SCORE_PREVIEW_BLOCKING_WARNING_PATTERN.test(warning) ? "warning" : "info",
title: "Private preview warning",
detail: warning,
};
}

function buildLocalFindings(
input: LocalBranchAnalysisInput,
changedFiles: LocalBranchChangedFile[],
Expand Down Expand Up @@ -894,12 +905,7 @@ function buildLocalFindings(
...branchEligibilityFindings(branchEligibility),
...scorePreview.warnings
.filter((warning) => !/branch eligibility/i.test(warning))
.map((warning) => ({
code: "score_preview_warning",
severity: /not registered|no active|exceeds|credibility/i.test(warning) ? ("warning" as const) : ("info" as const),
title: "Private preview warning",
detail: warning,
})),
.map(scorePreviewWarningFinding),
...preflight.findings.map((finding) => ({
code: `preflight_${finding.code}`,
severity: finding.severity,
Expand Down Expand Up @@ -1284,3 +1290,7 @@ function nonNegative(value: number | undefined): number {
function unique<T>(value: T, index: number, values: T[]): boolean {
return values.indexOf(value) === index;
}

export const __localBranchInternals = {
scorePreviewWarningFinding,
};
26 changes: 26 additions & 0 deletions test/unit/local-branch-score-preview-warning.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it } from "vitest";
import { __localBranchInternals } from "../../src/signals/local-branch";

describe("score preview warning severity", () => {
it.each([
"token gate is not satisfied",
"confirmed ineligible for this branch",
"contributor is not registered",
"no active registration",
"open PR count exceeds the threshold",
"credibility is below the required floor",
])("classifies blocking warning text as warning: %s", (warning) => {
expect(__localBranchInternals.scorePreviewWarningFinding(warning)).toMatchObject({
code: "score_preview_warning",
severity: "warning",
detail: warning,
});
});

it("keeps unrelated preview warnings informational", () => {
expect(__localBranchInternals.scorePreviewWarningFinding("Mirror data is still warming up")).toMatchObject({
code: "score_preview_warning",
severity: "info",
});
});
});
Loading