Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ The verifier compares all protected files on the default branch to those
tags, including additions and deletions, and pins each original tag to its
reviewed commit. Do not rewrite or move old receipts, tags, or versions.

Storage's canonical product identity is `azure-storage`, with its package under
`canvases/azure-storage`. The verifier uses that same identity for its launcher,
extension, receipt and release tags; `azure-storage-canvas` is obsolete.

A new candidate for any canvas uses the reviewed
`schemaVersion: 2`, `mutableDocumentation: true` contract: `release.json` and
`checksums.json` enumerate protected files only, and its `SHA256SUMS` covers
Expand Down
12 changes: 6 additions & 6 deletions scripts/verify-plugin-marketplace.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ const packages = {
extensionPath: "com.github.copilot/extensions/azure-sre-agent",
receipt: "canvases/azure-sre-agent/SHA256SUMS",
},
"azure-storage-canvas": {
path: "canvases/azure-storage-canvas",
"azure-storage": {
path: "canvases/azure-storage",
manifest: ".github/plugin/plugin.json",
skills: ["./skills/azure-storage-canvas/"],
extension: "azure-storage-canvas",
extensionPath: "com.github.copilot/extensions/azure-storage-canvas",
receipt: "canvases/azure-storage-canvas/SHA256SUMS",
skills: ["./skills/azure-storage/"],
extension: "azure-storage",
extensionPath: "com.github.copilot/extensions/azure-storage",
receipt: "canvases/azure-storage/SHA256SUMS",
},
"containers": {
path: "canvases/containers",
Expand Down
8 changes: 4 additions & 4 deletions test/fixtures/marketplace.candidate.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@
},
{
"name": "azure-sre-agent",
"version": "0.2.7",
"version": "0.4.2",
"source": "canvases/azure-sre-agent"
},
{
"name": "azure-storage-canvas",
"version": "0.1.1",
"source": "canvases/azure-storage-canvas"
"name": "azure-storage",
"version": "0.3.0",
"source": "canvases/azure-storage"
},
{
"name": "containers",
Expand Down
9 changes: 4 additions & 5 deletions test/plugin-marketplace.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ test("requires release tags for full verification, then checks every catalog plu
assert.ok(results[1].startsWith(`azure-resources-query@${versionOf("azure-resources-query")} azure-resources-query-v`));
assert.match(results[2], /canvas-authoring@0\.1\.1 canvas-authoring-v0-1-1-/);
assert.match(results[3], /azure-cost-health-check@0\.4\.5 azure-cost-health-check-v0-4-5-/);
assert.match(results[4], /azure-sre-agent@0\.2\.7 azure-sre-agent-v0-2-7-/);
assert.ok(results[5].startsWith(`azure-storage-canvas@${versionOf("azure-storage-canvas")} azure-storage-canvas-v`));
assert.equal(results[6], "containers@0.1.1 (candidate; immutable tag pending)");
assert.ok(results[4].startsWith(`azure-sre-agent@${versionOf("azure-sre-agent")} azure-sre-agent-v`));
assert.ok(results[5].startsWith(`azure-storage@${versionOf("azure-storage")} azure-storage-v`));
assert.ok(results[6].startsWith(`containers@${versionOf("containers")} containers-v`));
});

test("candidate validates every reviewed package and omits only missing immutable tags", () => {
Expand All @@ -74,8 +74,7 @@ test("candidate validates every reviewed package and omits only missing immutabl
assert.equal(results[index], `${name}@${version} ${tags[0] ?? "(candidate; immutable tag pending)"}`);
}
assert.match(results[2], /canvas-authoring-v0-1-1-8af10f8/);
assert.match(results[4], /azure-sre-agent@0\.2\.7 azure-sre-agent-v0-2-7-9da2e40/);
assert.equal(results[6], "containers@0.1.1 (candidate; immutable tag pending)");
assert.ok(results[4].startsWith(`azure-sre-agent@${versionOf("azure-sre-agent")} azure-sre-agent-v`));
});

test("candidate rejects corrupted protected payloads and checksum receipts", () => {
Expand Down
14 changes: 8 additions & 6 deletions test/storage-release.test.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
import { copyFileSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
Expand All @@ -12,7 +12,7 @@ import {
verifyTagSource,
} from "../scripts/verify-plugin-marketplace.mjs";

const name = "azure-storage-canvas";
const name = "azure-storage";
const source = `canvases/${name}`;
const catalog = JSON.parse(readFileSync(
new URL("../.github/plugin/marketplace.json", import.meta.url)));
Expand All @@ -31,13 +31,13 @@ test("Storage accepts reviewed semantic versions without a fixed version gate",
});

test("Storage rejects obsolete identities and noncanonical package sources", () => {
for (const obsolete of ["azure-storage", "azure-storage-explorer"]) {
for (const obsolete of ["azure-storage-canvas", "azure-storage-explorer"]) {
assert.throws(() => verifyCurrentVersion(obsolete, "0.1.1"),
/expected a reviewed product/);
}
for (const wrongSource of [
"plugins/azure-storage-canvas",
"canvases/azure-storage-canvas/src",
`plugins/${name}`,
`${source}/src`,
`${source}/com.github.copilot/extensions/${name}`,
"canvases/azure-resources-query",
{ source: "github", repo: "microsoft/azure-dev-tools", path: source, ref: "main" },
Expand Down Expand Up @@ -81,7 +81,7 @@ test("the Storage candidate verifies its canonical plugin and protected receipt"
const plugin = catalog.plugins.find((entry) => entry.name === name);
assert.ok(plugin, "Storage must have a production marketplace entry");
assert.match(verifyPlugin(plugin, { candidate: true }),
/^azure-storage-canvas@\d+\.\d+\.\d+ /);
/^azure-storage@\d+\.\d+\.\d+ /);
});

test("Storage rejects changes to its protected runtime, launcher, notices, icon and receipt", () => {
Expand All @@ -101,6 +101,8 @@ test("Storage rejects changes to its protected runtime, launcher, notices, icon
};
try {
execFileSync("git", ["clone", "--quiet", "--local", "--no-hardlinks", root, clone]);
copyFileSync(join(root, "scripts/verify-plugin-marketplace.mjs"),
join(clone, "scripts/verify-plugin-marketplace.mjs"));
git("config", "user.name", "Storage release policy test");
git("config", "user.email", "release-policy@example.invalid");
assert.doesNotThrow(verify);
Expand Down