mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-26 10:31:17 +00:00
Suppress triage bot comment spam
This commit is contained in:
parent
b1a2f2aba3
commit
f6656950a9
1 changed files with 92 additions and 30 deletions
122
.github/workflows/issue-version-triage.yml
vendored
122
.github/workflows/issue-version-triage.yml
vendored
|
|
@ -22,17 +22,29 @@ jobs:
|
|||
script: |
|
||||
const issue = context.payload.issue;
|
||||
const labelNames = new Set((issue.labels || []).map((label) => label.name));
|
||||
|
||||
// Restrict automation to bug reports only.
|
||||
if (!labelNames.has("bug")) {
|
||||
core.info("Issue is not labeled bug. Skipping version triage.");
|
||||
return;
|
||||
}
|
||||
|
||||
const VERSION_LABEL_PREFIX = "affects-";
|
||||
const NEEDS_VERSION_LABEL = "needs-version-info";
|
||||
const RETEST_LABEL = "needs-retest-on-latest";
|
||||
const RETEST_COMMENT_MARKER = "<!-- issue-version-triage:v1 -->";
|
||||
const BUG_LABEL = "bug";
|
||||
const DOCS_LABEL = "documentation";
|
||||
const ENHANCEMENT_LABEL = "enhancement";
|
||||
|
||||
function escapeRegExp(value) {
|
||||
return String(value || "").replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
function extractSectionValue(body, heading) {
|
||||
if (!body) return null;
|
||||
const pattern = new RegExp(
|
||||
`^#+\\s*${escapeRegExp(heading)}\\s*$\\n+([\\s\\S]*?)(?=^#+\\s+|$)`,
|
||||
"im"
|
||||
);
|
||||
const match = body.match(pattern);
|
||||
if (!match) return null;
|
||||
const value = match[1].trim();
|
||||
return value || null;
|
||||
}
|
||||
|
||||
function normalizeVersion(value) {
|
||||
if (!value) return null;
|
||||
|
|
@ -40,34 +52,60 @@ jobs:
|
|||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
function extractPulseVersion(body) {
|
||||
if (!body) return null;
|
||||
function extractPulseVersion(title, body) {
|
||||
if (body) {
|
||||
const lines = body.split(/\r?\n/);
|
||||
for (let i = 0; i < lines.length; i += 1) {
|
||||
const line = lines[i] || "";
|
||||
if (/pulse\s*(\||-)?\s*version/i.test(line)) {
|
||||
const inlineVersion = normalizeVersion(line);
|
||||
if (inlineVersion) return inlineVersion;
|
||||
|
||||
const lines = body.split(/\r?\n/);
|
||||
for (let i = 0; i < lines.length; i += 1) {
|
||||
const line = lines[i] || "";
|
||||
if (/pulse\s*(\||-)?\s*version/i.test(line)) {
|
||||
const inlineVersion = normalizeVersion(line);
|
||||
if (inlineVersion) return inlineVersion;
|
||||
|
||||
// Check nearby lines because issue forms often put values on the next line.
|
||||
for (let j = i + 1; j < Math.min(i + 6, lines.length); j += 1) {
|
||||
const nearby = (lines[j] || "").trim();
|
||||
if (!nearby) continue;
|
||||
const nearbyVersion = normalizeVersion(nearby);
|
||||
if (nearbyVersion) return nearbyVersion;
|
||||
// Check nearby lines because issue forms often put values on the next line.
|
||||
for (let j = i + 1; j < Math.min(i + 6, lines.length); j += 1) {
|
||||
const nearby = (lines[j] || "").trim();
|
||||
if (!nearby) continue;
|
||||
const nearbyVersion = normalizeVersion(nearby);
|
||||
if (nearbyVersion) return nearbyVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: issue-form block headed by "Pulse version".
|
||||
const headingMatch = body.match(/#+\s*Pulse version[\s\S]{0,80}?(\bv?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?\b)/i);
|
||||
if (headingMatch) return normalizeVersion(headingMatch[1]);
|
||||
|
||||
// Final fallback for older templates with "Pulse | Version: [6.0.0]".
|
||||
const legacyMatch = body.match(/pulse\s*\|?\s*version[^\n]*?(\bv?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?\b)/i);
|
||||
if (legacyMatch) return normalizeVersion(legacyMatch[1]);
|
||||
}
|
||||
|
||||
// Fallback: issue-form block headed by "Pulse version".
|
||||
const headingMatch = body.match(/#+\s*Pulse version[\s\S]{0,80}?(\bv?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?\b)/i);
|
||||
if (headingMatch) return normalizeVersion(headingMatch[1]);
|
||||
// Maintainer-created split issues often carry the exact version in the title.
|
||||
return normalizeVersion(title);
|
||||
}
|
||||
|
||||
// Final fallback for older templates with "Pulse | Version: [5.1.2]".
|
||||
const legacyMatch = body.match(/pulse\s*\|?\s*version[^\n]*?(\bv?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?\b)/i);
|
||||
if (legacyMatch) return normalizeVersion(legacyMatch[1]);
|
||||
function classifyV6FeedbackType(body) {
|
||||
const feedbackType = extractSectionValue(body, "Feedback type");
|
||||
if (!feedbackType) return null;
|
||||
|
||||
const normalized = feedbackType.toLowerCase();
|
||||
if (
|
||||
normalized.includes("bug") ||
|
||||
normalized.includes("regression") ||
|
||||
normalized.includes("upgrade / migration issue") ||
|
||||
normalized.includes("performance issue")
|
||||
) {
|
||||
return BUG_LABEL;
|
||||
}
|
||||
if (normalized.includes("documentation issue")) {
|
||||
return DOCS_LABEL;
|
||||
}
|
||||
if (
|
||||
normalized.includes("ux / workflow friction") ||
|
||||
normalized.includes("other actionable feedback")
|
||||
) {
|
||||
return ENHANCEMENT_LABEL;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +155,12 @@ jobs:
|
|||
return comments.some((comment) => (comment.body || "").includes(RETEST_COMMENT_MARKER));
|
||||
}
|
||||
|
||||
const reportedVersion = extractPulseVersion(issue.body);
|
||||
const action = context.payload.action || "";
|
||||
const authorAssociation = String(issue.author_association || "").toUpperCase();
|
||||
const reporterIsMaintainer = ["OWNER", "MEMBER", "COLLABORATOR"].includes(authorAssociation);
|
||||
const allowRetestComment = (action === "opened" || action === "reopened") && !reporterIsMaintainer;
|
||||
|
||||
const reportedVersion = extractPulseVersion(issue.title, issue.body);
|
||||
core.info(`Reported Pulse version: ${reportedVersion || "not found"}`);
|
||||
|
||||
let latestVersion = null;
|
||||
|
|
@ -133,6 +176,25 @@ jobs:
|
|||
core.info(`Latest stable release: ${latestVersion || "unknown"}`);
|
||||
|
||||
const nextLabels = new Set(labelNames);
|
||||
const v6FeedbackClass = classifyV6FeedbackType(issue.body);
|
||||
if (v6FeedbackClass) {
|
||||
core.info(`Detected v6 feedback issue class: ${v6FeedbackClass}`);
|
||||
nextLabels.add(v6FeedbackClass);
|
||||
}
|
||||
|
||||
const isBugLike = nextLabels.has(BUG_LABEL);
|
||||
if (!isBugLike) {
|
||||
core.info("Issue is not bug-like after classification. Skipping version triage.");
|
||||
if (v6FeedbackClass && !labelNames.has(v6FeedbackClass)) {
|
||||
await github.rest.issues.setLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
labels: [...nextLabels].sort(),
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (reportedVersion) {
|
||||
await ensureLabel(
|
||||
|
|
@ -160,7 +222,7 @@ jobs:
|
|||
if (comparison !== null && comparison < 0) {
|
||||
nextLabels.add(RETEST_LABEL);
|
||||
|
||||
if (!(await hasRetestComment(issue.number))) {
|
||||
if (allowRetestComment && !(await hasRetestComment(issue.number))) {
|
||||
const body = [
|
||||
RETEST_COMMENT_MARKER,
|
||||
"Thanks for the report.",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue