ci(release): harden clawhub plugin publish

This commit is contained in:
Peter Steinberger
2026-05-04 10:08:09 +01:00
parent 5b528f4dfe
commit b37fba7c07
6 changed files with 252 additions and 18 deletions

View File

@@ -4,6 +4,7 @@ import { delimiter, join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import {
collectClawHubPublishablePluginPackages,
collectClawHubOpenClawOwnerErrors,
collectClawHubVersionGateErrors,
collectPluginClawHubReleasePathsFromGitRange,
collectPluginClawHubReleasePlan,
@@ -362,6 +363,50 @@ describe("collectPluginClawHubReleasePlan", () => {
});
});
describe("collectClawHubOpenClawOwnerErrors", () => {
it("requires OpenClaw-scoped release candidates to already belong to the OpenClaw publisher", async () => {
const errors = await collectClawHubOpenClawOwnerErrors({
plugins: [
{ packageName: "@openclaw/demo-plugin" },
{ packageName: "@openclaw/missing-plugin" },
{ packageName: "@other/safe-plugin" },
],
registryBaseUrl: "https://clawhub.ai",
fetchImpl: async (url) => {
const pathname = new URL(String(url)).pathname;
if (pathname.includes("%40openclaw%2Fmissing-plugin")) {
return new Response("not found", { status: 404 });
}
return new Response(
JSON.stringify({
owner: { handle: "steipete" },
}),
{ status: 200, headers: { "Content-Type": "application/json" } },
);
},
});
expect(errors).toEqual([
"@openclaw/demo-plugin: ClawHub package owner must be @openclaw; got @steipete.",
"@openclaw/missing-plugin: ClawHub package row must already exist under @openclaw before OpenClaw release publish.",
]);
});
it("passes when OpenClaw-scoped release candidates belong to the OpenClaw publisher", async () => {
const errors = await collectClawHubOpenClawOwnerErrors({
plugins: [{ packageName: "@openclaw/demo-plugin" }],
registryBaseUrl: "https://clawhub.ai",
fetchImpl: async () =>
new Response(JSON.stringify({ owner: { handle: "openclaw" } }), {
status: 200,
headers: { "Content-Type": "application/json" },
}),
});
expect(errors).toEqual([]);
});
});
describe("plugin-clawhub-publish.sh", () => {
it("previews the publish command through the ClawHub CLI dry-run preflight", () => {
const repoDir = createTempPluginRepo();