mirror of
https://github.com/github/awesome-copilot.git
synced 2026-08-01 23:12:29 +00:00
Harden external plugin PR quality gate rendering and name validation (#2444)
* Harden external plugin PR quality gates Reference: https://github.com/github/awesome-copilot/pull/2398 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a79923be-c65f-4d51-8fe3-a86e05fd02f1 * 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> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Copilot-Session: a79923be-c65f-4d51-8fe3-a86e05fd02f1
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { runExternalPluginQualityGates } from "./external-plugin-quality-gates.mjs";
|
||||
import { validateExternalPlugin } from "./external-plugin-validation.mjs";
|
||||
|
||||
function normalizePluginPath(pluginPath) {
|
||||
if (!pluginPath || pluginPath === "/") {
|
||||
@@ -66,13 +67,33 @@ function aggregateResultStatus(pluginResults) {
|
||||
};
|
||||
}
|
||||
|
||||
function createValidationFailureQuality(errors) {
|
||||
const output = errors.map((error) => `- ${error}`).join("\n");
|
||||
return {
|
||||
overall_status: "fail",
|
||||
vally_lint_status: "fail",
|
||||
smoke_status: "not_run",
|
||||
version_match_status: "not_run",
|
||||
canvas_structure_status: "not_run",
|
||||
failure_class: "submitter_fixes",
|
||||
summary: "Plugin entry failed external.json validation. Fix the listed errors and re-run quality checks.",
|
||||
vally_lint_output: output,
|
||||
smoke_output: "Install smoke test skipped due to external.json validation errors.",
|
||||
version_match_output: "Version match skipped due to external.json validation errors.",
|
||||
canvas_structure_output: "Canvas structure check skipped due to external.json validation errors.",
|
||||
};
|
||||
}
|
||||
|
||||
export async function runExternalPluginPrQualityGates(plugins) {
|
||||
if (!Array.isArray(plugins)) {
|
||||
throw new Error("plugins must be an array");
|
||||
}
|
||||
|
||||
const checkedPlugins = await Promise.all(plugins.map(async (plugin) => {
|
||||
const quality = await runExternalPluginQualityGates(plugin);
|
||||
const validation = validateExternalPlugin(plugin, "changed-plugin", { policy: "marketplace" });
|
||||
const quality = validation.errors.length > 0
|
||||
? createValidationFailureQuality(validation.errors)
|
||||
: await runExternalPluginQualityGates(plugin);
|
||||
return {
|
||||
name: plugin?.name ?? "unknown",
|
||||
source: plugin?.source ?? {},
|
||||
|
||||
@@ -60,12 +60,20 @@ function validatePluginName(name, prefix, errors) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.length > 50) {
|
||||
errors.push(`${prefix}: "name" must be 50 characters or fewer`);
|
||||
if (name.length > 64) {
|
||||
errors.push(`${prefix}: "name" must be 64 characters or fewer`);
|
||||
}
|
||||
|
||||
if (!/^[a-z0-9-]+$/.test(name)) {
|
||||
errors.push(`${prefix}: "name" must contain only lowercase letters, numbers, and hyphens`);
|
||||
if (!/^[a-z0-9.-]+$/.test(name)) {
|
||||
errors.push(`${prefix}: "name" must contain only lowercase letters, numbers, hyphens, and periods`);
|
||||
}
|
||||
|
||||
if (!/^[a-z0-9].*[a-z0-9]$/.test(name) && !/^[a-z0-9]$/.test(name)) {
|
||||
errors.push(`${prefix}: "name" must start and end with a lowercase letter or number`);
|
||||
}
|
||||
|
||||
if (name.includes("--") || name.includes("..")) {
|
||||
errors.push(`${prefix}: "name" must not contain consecutive hyphens or periods`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user