mirror of
https://github.com/github/awesome-copilot.git
synced 2026-07-17 19:31:20 +00:00
Migrate extension plugin materialization to extensions container (#2334)
* Migrate extension plugin materialization layout Materialize extension plugins into a dedicated extensions/ container, validate the new manifest convention, and bump extension plugin versions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1 * Keep extension manifests source-compatible Restore source extension manifests to "extensions": "." while preserving materialization-time rewrite to "extensions" in distribution output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1 * Validate canvas extension layout for external submissions Add intake and quality-gate checks for canvas-tagged external plugins so they must include extensions/extension.mjs and optional manifest extensions is validated when present. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1 * Fix plugin clean extension pass and typo guard text Declare EXTENSIONS_DIR in clean-materialized-plugins and run extension cleanup once after plugin cleanup. Also normalize misspelled-key detection strings to satisfy spelling checks without changing validation behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1 * Proper codespell fix * Separate canvas structure quality gate status Track canvas structure as its own gate status and output, include it in aggregate summaries, and enforce Git object types so extensions/ is a tree and extensions/extension.mjs is a blob. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1 * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -459,6 +459,55 @@ async function validateCanvasPluginMetadata(plugin, errors, warnings, token) {
|
||||
);
|
||||
}
|
||||
|
||||
if (manifest.extenions !== undefined) {
|
||||
errors.push(
|
||||
`submission: plugins tagged with "canvas" must use "extensions" (found misspelled key "extenions") in "${manifestPath}"`,
|
||||
);
|
||||
}
|
||||
|
||||
if (manifest.extensions !== undefined && manifest.extensions !== "extensions") {
|
||||
errors.push(
|
||||
`submission: plugins tagged with "canvas" may omit "extensions", but if provided it must be "extensions" in "${manifestPath}"`,
|
||||
);
|
||||
}
|
||||
|
||||
const extensionContainerPath = joinRepoPath(pluginRoot, "extensions");
|
||||
const extensionContainerResponse = await fetchGitHubFile(repo, extensionContainerPath, releaseLocator, token);
|
||||
if (extensionContainerResponse.kind === "notFound") {
|
||||
errors.push(
|
||||
`submission: plugins tagged with "canvas" must include an "extensions" directory at ${releaseLocatorDescription}`,
|
||||
);
|
||||
} else if (extensionContainerResponse.kind === "apiError") {
|
||||
warnings.push(
|
||||
`submission: could not verify "extensions" directory in GitHub repository "${repo}" at ${releaseLocatorDescription}; a maintainer should re-run intake`,
|
||||
);
|
||||
} else if (
|
||||
!(
|
||||
extensionContainerResponse.data?.type === "dir"
|
||||
|| Array.isArray(extensionContainerResponse.data)
|
||||
)
|
||||
) {
|
||||
errors.push(
|
||||
`submission: "extensions" must be a directory in ${releaseLocatorDescription}`,
|
||||
);
|
||||
}
|
||||
|
||||
const extensionEntryPath = joinRepoPath(pluginRoot, "extensions", "extension.mjs");
|
||||
const extensionEntryResponse = await fetchGitHubFile(repo, extensionEntryPath, releaseLocator, token);
|
||||
if (extensionEntryResponse.kind === "notFound") {
|
||||
errors.push(
|
||||
`submission: plugins tagged with "canvas" must include "extensions/extension.mjs" at ${releaseLocatorDescription}`,
|
||||
);
|
||||
} else if (extensionEntryResponse.kind === "apiError") {
|
||||
warnings.push(
|
||||
`submission: could not verify "extensions/extension.mjs" in GitHub repository "${repo}" at ${releaseLocatorDescription}; a maintainer should re-run intake`,
|
||||
);
|
||||
} else if (extensionEntryResponse.data?.type !== "file") {
|
||||
errors.push(
|
||||
`submission: "extensions/extension.mjs" must be a file in ${releaseLocatorDescription}`,
|
||||
);
|
||||
}
|
||||
|
||||
const previewPath = joinRepoPath(pluginRoot, EXTERNAL_CANVAS_PREVIEW_PATH);
|
||||
const previewResponse = await fetchGitHubFile(repo, previewPath, releaseLocator, token);
|
||||
if (previewResponse.kind === "notFound") {
|
||||
@@ -580,11 +629,13 @@ function normalizeQualityGateResult(rawResult) {
|
||||
vally_lint_status: "not_run",
|
||||
smoke_status: "not_run",
|
||||
version_match_status: "not_run",
|
||||
canvas_structure_status: "not_run",
|
||||
failure_class: "none",
|
||||
summary: "",
|
||||
vally_lint_output: "",
|
||||
smoke_output: "",
|
||||
version_match_output: "",
|
||||
canvas_structure_output: "",
|
||||
};
|
||||
|
||||
if (!rawResult || typeof rawResult !== "object" || Array.isArray(rawResult)) {
|
||||
@@ -601,6 +652,7 @@ function buildQualityGatesCommentSection(qualityResult) {
|
||||
const vallyState = qualityResult.vally_lint_status || "not_run";
|
||||
const smokeState = qualityResult.smoke_status || "not_run";
|
||||
const versionMatchState = qualityResult.version_match_status || "not_run";
|
||||
const canvasStructureState = qualityResult.canvas_structure_status || "not_run";
|
||||
const summaryText = String(qualityResult.summary || "").trim() || "_No quality gate details were provided._";
|
||||
|
||||
const sections = [
|
||||
@@ -611,6 +663,7 @@ function buildQualityGatesCommentSection(qualityResult) {
|
||||
`| vally lint | ${vallyState} |`,
|
||||
`| install smoke test | ${smokeState} |`,
|
||||
`| version match | ${versionMatchState} |`,
|
||||
`| canvas structure | ${canvasStructureState} |`,
|
||||
"",
|
||||
summaryText,
|
||||
];
|
||||
@@ -660,6 +713,21 @@ function buildQualityGatesCommentSection(qualityResult) {
|
||||
);
|
||||
}
|
||||
|
||||
const canvasStructureOutput = String(qualityResult.canvas_structure_output || "").trim();
|
||||
if (canvasStructureOutput) {
|
||||
sections.push(
|
||||
"",
|
||||
"<details>",
|
||||
"<summary>Canvas structure output</summary>",
|
||||
"",
|
||||
"```text",
|
||||
canvasStructureOutput,
|
||||
"```",
|
||||
"",
|
||||
"</details>",
|
||||
);
|
||||
}
|
||||
|
||||
return sections.join("\n");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user