fix: disable board audit coverage validation
This commit is contained in:
+43
-118
@@ -3893,101 +3893,10 @@ async function issueBoardAudit(repo: string, token: string, options: GitHubOptio
|
||||
const commandName = "issue board-audit";
|
||||
const boardIssue = await getIssue(token, repo, options.boardIssue);
|
||||
if (isGitHubError(boardIssue)) return commandError(commandName, repo, boardIssue, { boardIssue: options.boardIssue });
|
||||
const [rawOpenIssues, rawClosedIssues] = await Promise.all([
|
||||
listIssues(token, repo, "open", options.limit),
|
||||
listIssues(token, repo, "closed", options.limit),
|
||||
]);
|
||||
if (isGitHubError(rawOpenIssues)) return commandError(commandName, repo, rawOpenIssues, { phase: "list-open-issues", boardIssue: options.boardIssue, limit: options.limit });
|
||||
if (isGitHubError(rawClosedIssues)) return commandError(commandName, repo, rawClosedIssues, { phase: "list-closed-issues", boardIssue: options.boardIssue, limit: options.limit });
|
||||
|
||||
const openIssues = rawOpenIssues.filter((issue) => issue.pull_request === undefined).slice(0, options.limit).map(boardIssueEntry);
|
||||
const closedIssues = rawClosedIssues.filter((issue) => issue.pull_request === undefined).slice(0, options.limit).map(boardIssueEntry);
|
||||
const allListedIssues = [...openIssues, ...closedIssues];
|
||||
const issueMap = new Map<number, BoardIssueEntry>(allListedIssues.map((issue) => [issue.number, issue]));
|
||||
const ignoreMap = boardIgnoreMap(options, allListedIssues);
|
||||
const parsed = parseBoardTables(boardIssue.body ?? "");
|
||||
const rowValidationWarnings = parsed.warnings.filter((warning) => warning.issueNumber === null || !ignoreMap.has(warning.issueNumber));
|
||||
const openRows = parsed.sections.filter((section) => section.kind === "open").flatMap((section) => section.rows);
|
||||
const closedRows = parsed.sections.filter((section) => section.kind === "closed").flatMap((section) => section.rows);
|
||||
const openRowMap = boardRowsByIssue(openRows);
|
||||
const closedRowMap = boardRowsByIssue(closedRows);
|
||||
const openIssueNumbers = new Set(openIssues.map((issue) => issue.number));
|
||||
const closedIssueNumbers = new Set(closedIssues.map((issue) => issue.number));
|
||||
const boardIssueNumbers = Array.from(new Set([...openRowMap.keys(), ...closedRowMap.keys()]));
|
||||
|
||||
const missingOpenIssues = sortedIssueEntries(openIssues.filter((issue) => !ignoreMap.has(issue.number) && !openRowMap.has(issue.number)));
|
||||
const closedInOpenRows = sortedIssueEntries(closedIssues.filter((issue) => !ignoreMap.has(issue.number) && openRowMap.has(issue.number))).map((issue) => ({
|
||||
...issue,
|
||||
rows: (openRowMap.get(issue.number) ?? []).map((row) => ({ lineNumber: row.lineNumber, rowPreview: preview(row.raw) })),
|
||||
}));
|
||||
const missingClosedRows = sortedIssueEntries(closedIssues.filter((issue) => !ignoreMap.has(issue.number) && !closedRowMap.has(issue.number)));
|
||||
const openInClosedRows = sortedIssueEntries(openIssues.filter((issue) => !ignoreMap.has(issue.number) && closedRowMap.has(issue.number))).map((issue) => ({
|
||||
...issue,
|
||||
rows: (closedRowMap.get(issue.number) ?? []).map((row) => ({ lineNumber: row.lineNumber, rowPreview: preview(row.raw) })),
|
||||
}));
|
||||
const staleOpenRows = Array.from(openRowMap.entries())
|
||||
.filter(([issueNumber]) => !ignoreMap.has(issueNumber) && !openIssueNumbers.has(issueNumber))
|
||||
.map(([issueNumber, rows]) => ({
|
||||
issueNumber,
|
||||
knownState: closedIssueNumbers.has(issueNumber) ? "closed" : "not-in-listed-window",
|
||||
rows: rows.map((row) => ({ lineNumber: row.lineNumber, rowPreview: preview(row.raw) })),
|
||||
}))
|
||||
.sort((a, b) => a.issueNumber - b.issueNumber);
|
||||
const boardOnlyRows = boardIssueNumbers
|
||||
.filter((issueNumber) => !ignoreMap.has(issueNumber) && !issueMap.has(issueNumber))
|
||||
.sort((a, b) => a - b)
|
||||
.map((issueNumber) => ({
|
||||
issueNumber,
|
||||
sections: [
|
||||
...(openRowMap.has(issueNumber) ? ["open"] : []),
|
||||
...(closedRowMap.has(issueNumber) ? ["closed"] : []),
|
||||
],
|
||||
rows: [...(openRowMap.get(issueNumber) ?? []), ...(closedRowMap.get(issueNumber) ?? [])].map((row) => ({
|
||||
section: row.section,
|
||||
lineNumber: row.lineNumber,
|
||||
rowPreview: preview(row.raw),
|
||||
})),
|
||||
}));
|
||||
const ignoredIssues = [
|
||||
...ignoredIssueList(allListedIssues, ignoreMap),
|
||||
...ignoredBoardOnlyIssues(boardIssueNumbers, issueMap, ignoreMap),
|
||||
].sort((a, b) => a.number - b.number);
|
||||
const recommendedActions = [
|
||||
...missingOpenIssues.map((issue) => ({
|
||||
action: "add-open-row",
|
||||
issueNumber: issue.number,
|
||||
title: issue.title,
|
||||
section: "open",
|
||||
reason: "GitHub issue is open but no #20 OPEN table row was found.",
|
||||
})),
|
||||
...closedInOpenRows.map((issue) => ({
|
||||
action: "move-open-row-to-closed",
|
||||
issueNumber: issue.number,
|
||||
title: issue.title,
|
||||
reason: "GitHub issue is closed but still appears in the #20 OPEN table.",
|
||||
})),
|
||||
...missingClosedRows.map((issue) => ({
|
||||
action: "add-closed-row",
|
||||
issueNumber: issue.number,
|
||||
title: issue.title,
|
||||
section: "closed",
|
||||
reason: "GitHub issue is closed but no #20 CLOSED table row was found.",
|
||||
})),
|
||||
...openInClosedRows.map((issue) => ({
|
||||
action: "move-closed-row-to-open",
|
||||
issueNumber: issue.number,
|
||||
title: issue.title,
|
||||
reason: "GitHub issue is open but appears in the #20 CLOSED table.",
|
||||
})),
|
||||
...rowValidationWarnings.map((warning) => ({
|
||||
action: "fill-board-row-fields",
|
||||
issueNumber: warning.issueNumber,
|
||||
section: warning.section,
|
||||
lineNumber: warning.lineNumber,
|
||||
reason: warning.message,
|
||||
missingColumns: warning.missingColumns ?? [],
|
||||
})),
|
||||
];
|
||||
const body = boardIssue.body ?? "";
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
@@ -4001,7 +3910,9 @@ async function issueBoardAudit(repo: string, token: string, options: GitHubOptio
|
||||
title: boardIssue.title,
|
||||
state: boardIssue.state,
|
||||
url: boardIssue.html_url,
|
||||
bodyChars: (boardIssue.body ?? "").length,
|
||||
bodyChars: body.length,
|
||||
bodyLines: body.length === 0 ? 0 : normalizeNewlines(body).split("\n").length,
|
||||
bodySha: bodySha(body),
|
||||
updatedAt: boardIssue.updated_at ?? null,
|
||||
},
|
||||
config: {
|
||||
@@ -4009,21 +3920,36 @@ async function issueBoardAudit(repo: string, token: string, options: GitHubOptio
|
||||
knownMetaIssues: mergedKnownMetaIssues(options),
|
||||
ignoredIssues: options.ignoredIssues,
|
||||
briefIndexManagedIssuePattern: options.boardIssue === CODE_QUEUE_BOARD_TARGET_ISSUE ? "YYYY-MM-DD 指挥简报(北京时间)" : null,
|
||||
requiredColumns: BOARD_AUDIT_REQUIRED_COLUMNS.slice(),
|
||||
openClosedCoverageValidation: false,
|
||||
requiredColumns: [],
|
||||
},
|
||||
summary: {
|
||||
openIssues: openIssues.length,
|
||||
closedIssues: closedIssues.length,
|
||||
openIssues: null,
|
||||
closedIssues: null,
|
||||
openRows: openRows.length,
|
||||
closedRows: closedRows.length,
|
||||
missingOpenIssues: missingOpenIssues.length,
|
||||
closedInOpenRows: closedInOpenRows.length,
|
||||
missingClosedRows: missingClosedRows.length,
|
||||
openInClosedRows: openInClosedRows.length,
|
||||
rowValidationWarnings: rowValidationWarnings.length,
|
||||
ignoredIssues: ignoredIssues.length,
|
||||
boardOnlyRows: boardOnlyRows.length,
|
||||
staleOpenRows: staleOpenRows.length,
|
||||
parsedSections: parsed.sections.length,
|
||||
parsedRows: parsed.sections.reduce((sum, section) => sum + section.rows.length, 0),
|
||||
parserWarnings: parsed.warnings.length,
|
||||
missingOpenIssues: 0,
|
||||
closedInOpenRows: 0,
|
||||
missingClosedRows: 0,
|
||||
openInClosedRows: 0,
|
||||
rowValidationWarnings: 0,
|
||||
ignoredIssues: 0,
|
||||
boardOnlyRows: 0,
|
||||
staleOpenRows: 0,
|
||||
recommendedActions: 0,
|
||||
},
|
||||
validation: {
|
||||
openClosedCoverage: {
|
||||
enabled: false,
|
||||
reason: "OPEN/CLOSED table coverage validation has been disabled; this command no longer compares GitHub issue state against board rows.",
|
||||
},
|
||||
rowRequiredColumns: {
|
||||
enabled: false,
|
||||
reason: "board-audit no longer reports missing required row columns; use board-row commands when intentionally maintaining a legacy OPEN/CLOSED table.",
|
||||
},
|
||||
},
|
||||
sections: parsed.sections.map((section) => ({
|
||||
kind: section.kind,
|
||||
@@ -4034,25 +3960,24 @@ async function issueBoardAudit(repo: string, token: string, options: GitHubOptio
|
||||
rows: section.rows.length,
|
||||
issueNumbers: section.rows.flatMap((row) => row.issueNumbers),
|
||||
})),
|
||||
missingOpenIssues,
|
||||
closedInOpenRows,
|
||||
missingClosedRows,
|
||||
openInClosedRows,
|
||||
staleOpenRows,
|
||||
boardOnlyRows,
|
||||
rowValidationWarnings,
|
||||
ignoredIssues,
|
||||
recommendedActions,
|
||||
parserWarnings: parsed.warnings,
|
||||
missingOpenIssues: [],
|
||||
closedInOpenRows: [],
|
||||
missingClosedRows: [],
|
||||
openInClosedRows: [],
|
||||
staleOpenRows: [],
|
||||
boardOnlyRows: [],
|
||||
rowValidationWarnings: [],
|
||||
ignoredIssues: [],
|
||||
recommendedActions: [],
|
||||
request: {
|
||||
method: "GET",
|
||||
paths: [
|
||||
`/repos/{owner}/{repo}/issues/${options.boardIssue}`,
|
||||
"/repos/{owner}/{repo}/issues?state=open",
|
||||
"/repos/{owner}/{repo}/issues?state=closed",
|
||||
],
|
||||
query: { per_page: options.limit },
|
||||
query: {},
|
||||
},
|
||||
note: "Read-only board audit; no issue body was edited, no issue was closed, and no comments were written.",
|
||||
note: "Read-only board structure audit; OPEN/CLOSED coverage validation is disabled, no issue body was edited, no issue was closed, and no comments were written.",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4830,7 +4755,7 @@ export function ghHelp(): unknown {
|
||||
"When staging a body file from a shell, use a quoted heredoc such as cat <<'EOF' > /tmp/body.md so backticks and backslashes are not expanded before --body-file reads the file.",
|
||||
"For JSON request bodies in other CLI namespaces, prefer --body-file or --body-stdin over long inline shell arguments; GitHub Markdown writes intentionally use --body-file only.",
|
||||
"issue scan-escape classifies literal \\n findings as suspected-pollution, explanatory-mention, or risk, and emits cleanupSuggestions with body/comment ids plus diff-like previews. cleanup-plan is an alias that remains dry-run/read-only.",
|
||||
"issue board-audit is read-only and defaults to repo pikasTech/unidesk plus board issue #20. It compares GitHub open/closed issue lists with the board OPEN/CLOSED tables and reports missingOpenIssues, closedInOpenRows, missingClosedRows, rowValidationWarnings, ignoredIssues, and recommendedActions. When an Issue column exists, row.issueNumber is taken from that column; #20 and #24 are known meta issues by default. Daily rolling brief issues titled YYYY-MM-DD 指挥简报(北京时间) are managed by #20's brief index and appear in ignoredIssues with reason=brief-index-managed instead of missingOpenIssues.",
|
||||
"issue board-audit is read-only and defaults to repo pikasTech/unidesk plus board issue #20. It reads only the board issue body, returns body size/SHA and parsed Markdown board sections, and no longer validates GitHub open/closed issue coverage against OPEN/CLOSED tables. The legacy coverage fields remain present as empty arrays/zero counts for compatibility.",
|
||||
"issue board-row list/get reuse the board-audit table parser and are read-only. board-row update changes one table cell by issue number, returns old/new row, body SHA, body guard and request plan, and defaults to dry-run unless --expect-updated-at or --expect-body-sha is supplied for the guarded PATCH. Field aliases map status and validation to the 验收状态 column, tasks to 相关 Code Queue 任务, and focus to 当前关注点.",
|
||||
"issue board-row upsert updates an existing row when the issue is already present, or generates a complete row in --section open|closed when missing. It returns operation=update or operation=add, defaults to dry-run, requires --expect-body-sha or --expect-updated-at before PATCH, and refuses section migration; use board-row move for OPEN/CLOSED migration.",
|
||||
"issue board-row add/move/delete are row-scoped #20 table mutations. add validates a one-line --row-file against the target table column count, Issue column, and GitHub 状态 column; move refuses duplicate/ambiguous rows and can update GitHub 状态 via --status; delete removes only the matched row. All three default to dry-run and require --expect-body-sha or --expect-updated-at before PATCH. add/move/delete return old/new row, body SHA, and line/section plan details for the parsed table mutation.",
|
||||
|
||||
Reference in New Issue
Block a user