refactor: 리펙토링
This commit is contained in:
@@ -71,6 +71,45 @@ for (const [gateId, gate] of Object.entries(document.gates)) {
|
||||
if (!gate.steps?.length || !gate.evidence?.length || !gate.retentionClass) {
|
||||
failures.push(`${gateId} lacks command, evidence, or retention wiring`);
|
||||
}
|
||||
for (const [index, step] of (gate.steps ?? []).entries()) {
|
||||
if (!isRecord(step) || (step.expect !== "pass" && step.expect !== "fail")) {
|
||||
failures.push(`${gateId}[${index}] has an invalid step expectation`);
|
||||
continue;
|
||||
}
|
||||
if (step.expect === "pass") {
|
||||
if (
|
||||
step.expectedExitCode !== undefined ||
|
||||
step.expectedDiagnosticId !== undefined
|
||||
) {
|
||||
failures.push(
|
||||
`${gateId}[${index}] passing step declares a negative fixture identity`,
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
typeof step.expectedExitCode !== "number" ||
|
||||
!Number.isSafeInteger(step.expectedExitCode) ||
|
||||
step.expectedExitCode < 1 ||
|
||||
step.expectedExitCode > 255
|
||||
) {
|
||||
failures.push(`${gateId}[${index}] lacks an exact expected exit code`);
|
||||
}
|
||||
const diagnosticId = step.expectedDiagnosticId;
|
||||
if (
|
||||
typeof diagnosticId !== "string" ||
|
||||
diagnosticId.trim().length === 0 ||
|
||||
diagnosticId.length > 256 ||
|
||||
["\r", "\n", "\0"].some(
|
||||
(character) =>
|
||||
typeof diagnosticId === "string" && diagnosticId.includes(character),
|
||||
)
|
||||
) {
|
||||
failures.push(
|
||||
`${gateId}[${index}] lacks a bounded expected diagnostic identity`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const runbookGateEvidence = Object.freeze({
|
||||
@@ -107,7 +146,6 @@ if (
|
||||
const forbiddenWorkflowPatterns = [
|
||||
/continue-on-error\s*:/,
|
||||
/retention-days\s*:/,
|
||||
/timeout-minutes\s*:/,
|
||||
/allow_failure\s*:/,
|
||||
];
|
||||
for (const pattern of forbiddenWorkflowPatterns) {
|
||||
@@ -115,6 +153,13 @@ for (const pattern of forbiddenWorkflowPatterns) {
|
||||
failures.push(`workflow contains forbidden downgrade/unsupported setting ${pattern}`);
|
||||
}
|
||||
}
|
||||
const jobTimeoutCount = workflow.match(/timeout-minutes:\s*45/g)?.length ?? 0;
|
||||
if (jobTimeoutCount !== 5) {
|
||||
failures.push("every CI gate job must declare timeout-minutes: 45");
|
||||
}
|
||||
if (/if-no-files-found:\s*warn/.test(workflow)) {
|
||||
failures.push("CI evidence upload must fail when artifacts are absent");
|
||||
}
|
||||
for (const requiredToken of [
|
||||
"merge_gate:",
|
||||
"release_gate:",
|
||||
@@ -144,6 +189,8 @@ for (const requiredToken of [
|
||||
"SOURCE_DATE_EPOCH",
|
||||
'"--format=%H%n%ct"',
|
||||
"env: gateEnvironment",
|
||||
"classifyGateStepResult",
|
||||
"timeout: step.timeoutMs ?? DEFAULT_STEP_TIMEOUT_MS",
|
||||
]) {
|
||||
if (!gateRunner.includes(requiredToken)) {
|
||||
failures.push(`CI gate runner missing ${requiredToken}`);
|
||||
|
||||
Reference in New Issue
Block a user