fix: restore scrolling and validator enforcement
ForgeFlow quality gate / quality (push) Canceled after 0s
ForgeFlow quality gate / quality (push) Canceled after 0s
This commit is contained in:
@@ -20,6 +20,8 @@ function normalizePolicy(policy = {}) {
|
||||
enabledChecks: Array.isArray(custom.enabledChecks) ? [...new Set(custom.enabledChecks.map(String))] : null,
|
||||
severityOverrides: custom.severityOverrides && typeof custom.severityOverrides === "object" ? { ...custom.severityOverrides } : {},
|
||||
blockingChecks: [...new Set((custom.blockingChecks || policy.blockingChecks || []).map(String))],
|
||||
blockingSeverities: [...new Set((custom.blockingSeverities || policy.blockingSeverities || base.severities || ["error"]).map(String))]
|
||||
.filter((severity) => ["warning", "error"].includes(severity)),
|
||||
allowSuppressions: custom.allowSuppressions ?? base.allowSuppressions ?? true,
|
||||
maxSuppressionDays: Math.max(1, Number(custom.maxSuppressionDays ?? base.maxSuppressionDays ?? 30)),
|
||||
};
|
||||
@@ -57,7 +59,7 @@ function applyPolicy(checks, policyInput, suppressions = [], now = new Date()) {
|
||||
suppressed: Boolean(suppression),
|
||||
suppression: suppression || null,
|
||||
expiredSuppression: expiredSuppression || null,
|
||||
blocking: !suppression && status !== "pass" && (status === "error" || policy.blockingChecks.includes(check.id)),
|
||||
blocking: !suppression && status !== "pass" && (policy.blockingSeverities.includes(status) || policy.blockingChecks.includes(check.id)),
|
||||
};
|
||||
});
|
||||
return { policy, checks: relevant };
|
||||
|
||||
@@ -484,12 +484,23 @@ class GitValidatorService {
|
||||
throw new Error("Unsupported Git Validator repair action.");
|
||||
}
|
||||
|
||||
async resolveRepairCheck(repository, candidate) {
|
||||
const checkId = String(candidate?.id || candidate?.checkId || "").trim();
|
||||
if (!checkId) throw new Error("A current Git Validator check ID is required.");
|
||||
const report = await this.scan(repository);
|
||||
const current = report.checks.find((check) => check.id === checkId);
|
||||
if (!current?.fixAction)
|
||||
throw new Error("This finding is resolved, suppressed or no longer repairable. Scan again before repairing.");
|
||||
if (candidate?.fixAction && candidate.fixAction !== current.fixAction)
|
||||
throw new Error("The Git Validator repair request is stale. Scan again before repairing.");
|
||||
return current;
|
||||
}
|
||||
summarize(repository, checks) {
|
||||
const totalWeight = checks.reduce((sum, check) => sum + check.weight, 0);
|
||||
const earned = checks.reduce(
|
||||
(sum, check) =>
|
||||
sum +
|
||||
(check.status === "pass"
|
||||
(check.status === "pass" || check.suppressed
|
||||
? check.weight
|
||||
: check.status === "warning"
|
||||
? check.weight * 0.45
|
||||
@@ -512,8 +523,9 @@ class GitValidatorService {
|
||||
checks,
|
||||
summary: {
|
||||
passed: checks.filter((check) => check.status === "pass").length,
|
||||
warnings: checks.filter((check) => check.status === "warning").length,
|
||||
errors: checks.filter((check) => check.status === "error").length,
|
||||
warnings: checks.filter((check) => check.status === "warning" && !check.suppressed).length,
|
||||
errors: checks.filter((check) => check.status === "error" && !check.suppressed).length,
|
||||
suppressed: checks.filter((check) => check.suppressed).length,
|
||||
repairable: checks.filter((check) => check.fixAction).length,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -373,7 +373,8 @@ function registerRepositoryIpc({
|
||||
});
|
||||
register("git-validator:preview-repair", async ({ fullName, check }) => {
|
||||
const repository = await resolveRepository({ fullName });
|
||||
return gitValidator.previewRepair(repository, check);
|
||||
const currentCheck = await gitValidator.resolveRepairCheck(repository, check);
|
||||
return gitValidator.previewRepair(repository, currentCheck);
|
||||
});
|
||||
register("git-validator:export", async ({ fullName, format = "json" }) => {
|
||||
const repository = await resolveRepository({ fullName });
|
||||
@@ -390,18 +391,19 @@ function registerRepositoryIpc({
|
||||
"add-editorconfig",
|
||||
"protect-default-branch",
|
||||
]);
|
||||
if (!allowed.has(check?.fixAction))
|
||||
const currentCheck = await gitValidator.resolveRepairCheck(repository, check);
|
||||
if (!allowed.has(currentCheck.fixAction))
|
||||
throw new Error("Unsupported Git Validator repair request.");
|
||||
const result = await gitValidator.repair(repository, check);
|
||||
const result = await gitValidator.repair(repository, currentCheck);
|
||||
await audit.append("git-validator.repair", {
|
||||
repository: repository.fullName,
|
||||
checkId: check.id,
|
||||
action: check.fixAction,
|
||||
checkId: currentCheck.id,
|
||||
action: currentCheck.fixAction,
|
||||
});
|
||||
await diagnostics.info("git-validator.repair.completed", {
|
||||
repository: repository.fullName,
|
||||
checkId: check.id,
|
||||
action: check.fixAction,
|
||||
checkId: currentCheck.id,
|
||||
action: currentCheck.fixAction,
|
||||
});
|
||||
return result;
|
||||
});
|
||||
|
||||
@@ -461,13 +461,15 @@ function createMockDeploymentBridge(context) {
|
||||
},
|
||||
async gitValidatorScan(fullName) {
|
||||
await wait(260);
|
||||
const policy = state.gitValidatorPolicy || { id: "standard", label: "Standard", requiredScore: 70 };
|
||||
const activeWarnings = 3;
|
||||
return {
|
||||
repository: fullName,
|
||||
checkedAt: iso(),
|
||||
score: 78,
|
||||
grade: "Good",
|
||||
policy: state.gitValidatorPolicy || { id: "standard", label: "Standard", requiredScore: 70 },
|
||||
ready: true,
|
||||
policy,
|
||||
ready: 78 >= policy.requiredScore && (policy.id === "minimal" || activeWarnings === 0),
|
||||
commitSha: "8cbaf303aa3bb9b4023a7c89aa13fb70ce612847",
|
||||
trend: { newlyFound: ["working-tree"], resolved: ["editorconfig"], regressions: [], suppressions: [] },
|
||||
expiredSuppressions: [],
|
||||
@@ -572,7 +574,12 @@ function createMockDeploymentBridge(context) {
|
||||
};
|
||||
},
|
||||
async gitValidatorSetPolicy(_fullName, policy) {
|
||||
state.gitValidatorPolicy = { id: policy.id, label: policy.id[0].toUpperCase() + policy.id.slice(1) };
|
||||
const requiredScores = { minimal: 55, standard: 70, strict: 82, production: 90 };
|
||||
state.gitValidatorPolicy = {
|
||||
id: policy.id,
|
||||
label: policy.id[0].toUpperCase() + policy.id.slice(1),
|
||||
requiredScore: requiredScores[policy.id] || 70,
|
||||
};
|
||||
return clone(state.gitValidatorPolicy);
|
||||
},
|
||||
async gitValidatorSuppress(_fullName, suppression) {
|
||||
|
||||
+17
-3
@@ -937,6 +937,21 @@ select:focus-visible {
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.repo-content > .tab-page,
|
||||
.repo-content > .validator-page {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
.repo-content > .validator-empty,
|
||||
.repo-content > .empty-state {
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
.changes-layout {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
@@ -1286,7 +1301,7 @@ html[data-theme="light"] .diff-line.remove {
|
||||
padding: 18px;
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
overflow: auto;
|
||||
align-content: start;
|
||||
}
|
||||
.validator-empty {
|
||||
min-height: 360px;
|
||||
@@ -2572,9 +2587,8 @@ kbd {
|
||||
font: 11px var(--font-mono);
|
||||
}
|
||||
.tab-page {
|
||||
min-height: 100%;
|
||||
min-height: 0;
|
||||
padding: 18px 19px 42px;
|
||||
overflow: auto;
|
||||
}
|
||||
.git-tools-grid {
|
||||
display: grid;
|
||||
|
||||
Reference in New Issue
Block a user