diff --git a/src/env.d.ts b/src/env.d.ts index 3522299..c15d0f2 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -3,4 +3,5 @@ export interface Env { R2_PUBLIC_URL: string; ZIGTOOLS_BUILDS: R2Bucket; ZIGTOOLS_DB: D1Database; + FORCE_MINISIGN?: string; } diff --git a/src/publish.ts b/src/publish.ts index 250f8c5..5b15a34 100644 --- a/src/publish.ts +++ b/src/publish.ts @@ -375,6 +375,15 @@ export async function handlePublish( artifactHasMinisign[artifactIndex] = true; } + if ( + env.FORCE_MINISIGN !== undefined && + artifactHasMinisign.some((hasMinisign) => !hasMinisign) + ) { + return new Response(`Every artifact must have a minisign file!`, { + status: 400, // Bad Request + }); + } + if ( artifactHasMinisign.length !== 0 && !artifactHasMinisign.every((value) => value === artifactHasMinisign[0]) diff --git a/test/publish.test.ts b/test/publish.test.ts index 3c12aae..4fef2d2 100644 --- a/test/publish.test.ts +++ b/test/publish.test.ts @@ -56,6 +56,35 @@ async function sendPublish({ artifacts: [fileName: string, file: Blob][]; withMinisign?: boolean; }): Promise { + const form = initPublishForm({ + zlsVersion, + zigVersion, + minimumBuildZigVersion, + minimumRuntimeZigVersion, + compatibility, + artifacts, + withMinisign, + }); + return await sendPublishForm(form); +} + +function initPublishForm({ + zlsVersion, + zigVersion, + minimumBuildZigVersion, + minimumRuntimeZigVersion, + compatibility, + artifacts, + withMinisign, +}: { + zlsVersion: string; + zigVersion: string; + minimumBuildZigVersion?: string; + minimumRuntimeZigVersion?: string; + compatibility?: VersionCompatibility; + artifacts: [fileName: string, file: Blob][]; + withMinisign?: boolean; +}): FormData { const form = new FormData(); form.set("zls-version", zlsVersion); form.set("zig-version", zigVersion); @@ -86,7 +115,7 @@ async function sendPublish({ ); } } - return await sendPublishForm(form); + return form; } function getSampleArtifacts( @@ -119,10 +148,8 @@ describe("/v1/zls/publish", () => { method: "POST", }), { + ...env, API_TOKEN: value as string, - R2_PUBLIC_URL: env.R2_PUBLIC_URL, - ZIGTOOLS_BUILDS: env.ZIGTOOLS_BUILDS, - ZIGTOOLS_DB: env.ZIGTOOLS_DB, }, ); expect(response.status).toBe(500); @@ -939,23 +966,80 @@ describe("/v1/zls/publish", () => { expect(response.status).toBe(400); }); + test("FORCE_MINISIGN with missing minisign file", async () => { + const form = initPublishForm({ + zlsVersion: "0.1.0-dev.1+aaaaaaa", + zigVersion: "0.1.0", + artifacts: [ + [ + "zls-windows-aarch64-0.1.0.zip", + new Blob([zipMagicNumber, "binary2"]), + ], + ], + }); + + const response = await handlePublish( + new Request("https://example.com/v1/zls/publish", { + body: form, + method: "POST", + headers: { + Authorization: `Basic ${Buffer.from(`admin:${env.API_TOKEN}`).toString("base64")}`, + }, + }), + { + ...env, + FORCE_MINISIGN: "1", + }, + ); + + expect(await response.text()).toBe( + "Every artifact must have a minisign file!", + ); + expect(response.status).toBe(400); + }); + + test("FORCE_MINISIGN with all minisign file", async () => { + const form = initPublishForm({ + zlsVersion: "0.1.0", + zigVersion: "0.1.0", + artifacts: [ + ["zls-windows-x86_64-0.1.0.zip", new Blob([zipMagicNumber, "binary2"])], + ["zls-windows-x86_64-0.1.0.zip.minisig", new Blob(["something"])], + ], + }); + + const response = await handlePublish( + new Request("https://example.com/v1/zls/publish", { + body: form, + method: "POST", + headers: { + Authorization: `Basic ${Buffer.from(`admin:${env.API_TOKEN}`).toString("base64")}`, + }, + }), + { + ...env, + FORCE_MINISIGN: "1", + }, + ); + + expect(await response.text()).toBe(""); + expect(response.status).toBe(200); + }); + test("disallow publishing partial minisigns", async () => { const response = await sendPublish({ zlsVersion: "0.1.0", zigVersion: "0.1.0", artifacts: [ + ["zls-linux-x86_64-0.1.0.tar.xz", new Blob([xzMagicNumber, "binary1"])], + ["zls-linux-x86_64-0.1.0.tar.xz.minisig", new Blob(["something"])], [ - "zls-linux-x86_64-0.11.0.tar.xz", - new Blob([xzMagicNumber, "binary1"]), - ], - ["zls-linux-x86_64-0.11.0.tar.xz.minisig", new Blob(["something"])], - [ - "zls-linux-x86_64-0.11.0.tar.gz", + "zls-linux-x86_64-0.1.0.tar.gz", new Blob([gzipMagicNumber, "binary1"]), ], - ["zls-linux-x86_64-0.11.0.tar.gz.minisig", new Blob(["something"])], + ["zls-linux-x86_64-0.1.0.tar.gz.minisig", new Blob(["something"])], [ - "zls-windows-aarch64-0.11.0.zip", + "zls-windows-aarch64-0.1.0.zip", new Blob([zipMagicNumber, "binary2"]), ], ], @@ -972,12 +1056,12 @@ describe("/v1/zls/publish", () => { zlsVersion: "0.1.0", zigVersion: "0.1.0", artifacts: [ - ["zls-linux-x86_64-0.11.0.tar.xz.minisig", new Blob(["something"])], + ["zls-linux-x86_64-0.1.0.tar.xz.minisig", new Blob(["something"])], ], }); expect(await response.text()).toBe( - "minisign file 'zls-linux-x86_64-0.11.0.tar.xz.minisig' has not matching artifact!", + "minisign file 'zls-linux-x86_64-0.1.0.tar.xz.minisig' has not matching artifact!", ); expect(response.status).toBe(400); }); diff --git a/test/select-zls-version.test.ts b/test/select-zls-version.test.ts index 77b8f10..c07f46c 100644 --- a/test/select-zls-version.test.ts +++ b/test/select-zls-version.test.ts @@ -214,10 +214,8 @@ describe("/v1/zls/index.json", () => { const response = await handleZLSIndex( new Request("https://example.com/v1/zls/index.json"), { - API_TOKEN: env.API_TOKEN, + ...env, R2_PUBLIC_URL: value as string, - ZIGTOOLS_BUILDS: env.ZIGTOOLS_BUILDS, - ZIGTOOLS_DB: env.ZIGTOOLS_DB, }, ); expect(response.status).toBe(500); @@ -350,10 +348,8 @@ describe("/v1/zls/select-version", () => { const response = await handleSelectVersion( new Request("https://example.com/v1/zls/select-version"), { - API_TOKEN: env.API_TOKEN, + ...env, R2_PUBLIC_URL: value as string, - ZIGTOOLS_BUILDS: env.ZIGTOOLS_BUILDS, - ZIGTOOLS_DB: env.ZIGTOOLS_DB, }, ); expect(response.status).toBe(500);