mirror of
https://github.com/github/awesome-copilot.git
synced 2026-05-28 09:31:44 +00:00
47701d25f4
* Add external plugin quality gates and override flow Introduce a dedicated reusable quality-gates workflow for external plugin submissions and wire intake/rerun orchestration to consume its results. Add quality-aware intake state handling, including a submitter-fix blocker state and richer intake comments. Also add a maintainer /mark-ready-for-review command workflow for explicit overrides, update related approval-label handling, and document the new external plugin review flow in CONTRIBUTING and AGENTS guidance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: use specific auth/network patterns in classifySmokeFailure Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com> * refactor: hoist INFRA_ERROR_PATTERNS to module level, fix timeout regex Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com> * fix: install Copilot CLI in external-plugin-quality-gates workflow Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>
174 lines
4.2 KiB
JavaScript
174 lines
4.2 KiB
JavaScript
export const EXTERNAL_PLUGIN_INTAKE_LABELS = Object.freeze({
|
|
"external-plugin": {
|
|
color: "FEF2C0",
|
|
description: "Public external plugin submission",
|
|
},
|
|
"awaiting-review": {
|
|
color: "FBCA04",
|
|
description: "Submission is waiting for automated intake validation",
|
|
},
|
|
"ready-for-review": {
|
|
color: "0E8A16",
|
|
description: "Submission passed intake validation and is ready for maintainer review",
|
|
},
|
|
"requires-submitter-fixes": {
|
|
color: "D93F0B",
|
|
description: "Submission has quality-gate findings that submitter must fix before maintainer review",
|
|
},
|
|
approved: {
|
|
color: "1D76DB",
|
|
description: "Submission was approved by a maintainer",
|
|
},
|
|
rejected: {
|
|
color: "B60205",
|
|
description: "Submission was rejected or failed intake validation",
|
|
},
|
|
});
|
|
|
|
const EXTERNAL_PLUGIN_INTAKE_SYNC_LABELS = Object.freeze([
|
|
"external-plugin",
|
|
"awaiting-review",
|
|
"ready-for-review",
|
|
"requires-submitter-fixes",
|
|
"rejected",
|
|
]);
|
|
|
|
async function ensureLabel({ github, owner, repo, name, config }) {
|
|
try {
|
|
await github.rest.issues.createLabel({
|
|
owner,
|
|
repo,
|
|
name,
|
|
color: config.color,
|
|
description: config.description,
|
|
});
|
|
} catch (error) {
|
|
if (error.status !== 422) {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
async function removeLabel({ github, owner, repo, issueNumber, name }) {
|
|
try {
|
|
await github.rest.issues.removeLabel({
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
name,
|
|
});
|
|
} catch (error) {
|
|
if (error.status !== 404) {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function syncExternalPluginIntakeLabels({ github, owner, repo, issueNumber, desiredLabels }) {
|
|
await Promise.all(
|
|
Object.entries(EXTERNAL_PLUGIN_INTAKE_LABELS).map(([name, config]) =>
|
|
ensureLabel({ github, owner, repo, name, config })
|
|
)
|
|
);
|
|
|
|
const currentLabels = await github.paginate(github.rest.issues.listLabelsOnIssue, {
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
per_page: 100,
|
|
});
|
|
|
|
const currentManagedLabels = currentLabels
|
|
.map((label) => label.name)
|
|
.filter((name) => EXTERNAL_PLUGIN_INTAKE_SYNC_LABELS.includes(name));
|
|
|
|
const labelsToAdd = [...desiredLabels].filter((name) => !currentManagedLabels.includes(name));
|
|
const labelsToRemove = currentManagedLabels.filter((name) => !desiredLabels.has(name));
|
|
|
|
if (labelsToAdd.length > 0) {
|
|
await github.rest.issues.addLabels({
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
labels: labelsToAdd,
|
|
});
|
|
}
|
|
|
|
for (const name of labelsToRemove) {
|
|
await removeLabel({ github, owner, repo, issueNumber, name });
|
|
}
|
|
}
|
|
|
|
export async function upsertExternalPluginIntakeComment({
|
|
github,
|
|
owner,
|
|
repo,
|
|
issueNumber,
|
|
marker,
|
|
body,
|
|
}) {
|
|
const { data: comments } = await github.rest.issues.listComments({
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
per_page: 100,
|
|
});
|
|
|
|
const existingComment = comments.find(
|
|
(comment) => comment.user?.login === "github-actions[bot]" && comment.body?.includes(marker)
|
|
);
|
|
|
|
if (existingComment) {
|
|
await github.rest.issues.updateComment({
|
|
owner,
|
|
repo,
|
|
comment_id: existingComment.id,
|
|
body,
|
|
});
|
|
return;
|
|
}
|
|
|
|
await github.rest.issues.createComment({
|
|
owner,
|
|
repo,
|
|
issue_number: issueNumber,
|
|
body,
|
|
});
|
|
}
|
|
|
|
export async function applyExternalPluginIntakeEvaluation({
|
|
github,
|
|
owner,
|
|
repo,
|
|
issueNumber,
|
|
evaluation,
|
|
}) {
|
|
const state = evaluation.intakeState ?? (evaluation.valid ? "ready-for-review" : "rejected");
|
|
const desiredLabelsByState = {
|
|
"ready-for-review": new Set(["external-plugin", "ready-for-review"]),
|
|
"requires-submitter-fixes": new Set(["external-plugin", "requires-submitter-fixes"]),
|
|
"awaiting-review": new Set(["external-plugin", "awaiting-review"]),
|
|
rejected: new Set(["external-plugin", "rejected"]),
|
|
};
|
|
const desiredLabels = desiredLabelsByState[state] ?? desiredLabelsByState.rejected;
|
|
|
|
await syncExternalPluginIntakeLabels({
|
|
github,
|
|
owner,
|
|
repo,
|
|
issueNumber,
|
|
desiredLabels,
|
|
});
|
|
|
|
await upsertExternalPluginIntakeComment({
|
|
github,
|
|
owner,
|
|
repo,
|
|
issueNumber,
|
|
marker: evaluation.commentMarker,
|
|
body: evaluation.commentBody,
|
|
});
|
|
|
|
return { desiredLabels };
|
|
}
|