mirror of
https://github.com/github/awesome-copilot.git
synced 2026-07-18 11:50:00 +00:00
Fix extension materialization to move bundles into container (#2339)
* 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 * Move extension bundles during materialization Change extension-plugin materialization to move root bundle entries into extensions/ instead of copying them, and assert originals are removed in test coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1 * Nest materialized extension bundles by plugin name Materialize extension plugins into extensions/<plugin-name>/... (moved entries) so resulting paths are duplicated by design, and bump extension plugin versions to the next patch release. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1 * Fix extension materialization publish and cleanup Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1 * Preserve root extension logo asset Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d26008fb-9928-4ba7-b7c8-36f35320f7c1
This commit is contained in:
@@ -4,6 +4,7 @@ import os from "os";
|
||||
import path from "path";
|
||||
import { after, test } from "node:test";
|
||||
import { materializeExtensionPlugin } from "./materialize-plugins.mjs";
|
||||
import { cleanMaterializedExtensionPlugin } from "./clean-materialized-plugins.mjs";
|
||||
|
||||
const tempDirs = [];
|
||||
|
||||
@@ -13,7 +14,7 @@ after(() => {
|
||||
}
|
||||
});
|
||||
|
||||
test("materializeExtensionPlugin writes extension bundles to ./extensions and rewrites manifest", () => {
|
||||
test("materializeExtensionPlugin writes extension bundles to ./extensions and preserves root logo assets", () => {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "materialize-extension-plugin-"));
|
||||
tempDirs.push(tempDir);
|
||||
|
||||
@@ -32,17 +33,57 @@ test("materializeExtensionPlugin writes extension bundles to ./extensions and re
|
||||
fs.writeFileSync(path.join(pluginDir, "assets", "preview.png"), "fake-image-bytes");
|
||||
|
||||
const result = materializeExtensionPlugin(pluginDir);
|
||||
const bundleRoot = path.join(pluginDir, "extensions", "extension-plugin");
|
||||
|
||||
assert.equal(result.skipped, false);
|
||||
assert.equal(result.manifestUpdated, true);
|
||||
assert.equal(result.copiedEntries, 3);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "extensions", "extension.mjs")), true);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "extensions", "assets", "preview.png")), true);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "extensions", "README.md")), true);
|
||||
assert.equal(result.movedEntries, 3);
|
||||
assert.equal(fs.existsSync(path.join(bundleRoot, "extension.mjs")), true);
|
||||
assert.equal(fs.existsSync(path.join(bundleRoot, "assets", "preview.png")), true);
|
||||
assert.equal(fs.existsSync(path.join(bundleRoot, "README.md")), true);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "extensions", ".github")), false);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "extension.mjs")), false);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "README.md")), false);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "assets", "preview.png")), true);
|
||||
|
||||
const pluginManifest = JSON.parse(
|
||||
fs.readFileSync(path.join(pluginDir, ".github", "plugin", "plugin.json"), "utf8")
|
||||
);
|
||||
assert.equal(pluginManifest.extensions, "extensions");
|
||||
assert.equal(pluginManifest.logo, "assets/preview.png");
|
||||
});
|
||||
|
||||
test("cleanMaterializedExtensionPlugin restores moved extension files to root", () => {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "clean-materialized-extension-plugin-"));
|
||||
tempDirs.push(tempDir);
|
||||
|
||||
const pluginDir = path.join(tempDir, "extension-plugin");
|
||||
fs.mkdirSync(path.join(pluginDir, ".github", "plugin"), { recursive: true });
|
||||
fs.mkdirSync(path.join(pluginDir, "assets"), { recursive: true });
|
||||
fs.writeFileSync(path.join(pluginDir, ".github", "plugin", "plugin.json"), JSON.stringify({
|
||||
name: "test-extension-plugin",
|
||||
description: "test plugin",
|
||||
version: "1.0.0",
|
||||
logo: "assets/preview.png",
|
||||
extensions: ".",
|
||||
}, null, 2));
|
||||
fs.writeFileSync(path.join(pluginDir, "extension.mjs"), "export default {};\n");
|
||||
fs.writeFileSync(path.join(pluginDir, "README.md"), "# test\n");
|
||||
fs.writeFileSync(path.join(pluginDir, "assets", "preview.png"), "fake-image-bytes");
|
||||
|
||||
materializeExtensionPlugin(pluginDir);
|
||||
const result = cleanMaterializedExtensionPlugin(pluginDir);
|
||||
|
||||
assert.equal(result.removed, 3);
|
||||
assert.equal(result.manifestUpdated, true);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "extension.mjs")), true);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "README.md")), true);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "assets", "preview.png")), true);
|
||||
assert.equal(fs.existsSync(path.join(pluginDir, "extensions")), false);
|
||||
|
||||
const pluginManifest = JSON.parse(
|
||||
fs.readFileSync(path.join(pluginDir, ".github", "plugin", "plugin.json"), "utf8")
|
||||
);
|
||||
assert.equal(pluginManifest.extensions, ".");
|
||||
assert.equal(pluginManifest.logo, "assets/preview.png");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user