From e22e3c2cf4e7f89c98d36cd096696497fbc7af5a Mon Sep 17 00:00:00 2001 From: AAA <35992542+TNTcraftHIM@users.noreply.github.com> Date: Wed, 23 Sep 2026 22:46:06 +0800 Subject: [PATCH] ci: accept extensible capability metadata in container checks The v1.6.2 container gate rejected `/api/capabilities` after the compatible connection-progress capability was added: it compared the entire object with the two service flags it owns. Check those flags independently, keeping optional SFU/NAT startup assertions while allowing compatible metadata extensions. The standalone container acceptance script is also classified with other non-product checks so changing this gate does not select a new App version. This unblocks the already-approved v1.6.2 release; its reviewed Chinese and English notes remain unchanged. Validation: focused release automation tests (4 passed); manual candidate CI checks the actual container recipe before integration. --- scripts/check-container.mjs | 11 +++++++++-- scripts/release-version.mjs | 2 +- tests/release-automation.test.ts | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/check-container.mjs b/scripts/check-container.mjs index 0955b14..3449331 100644 --- a/scripts/check-container.mjs +++ b/scripts/check-container.mjs @@ -43,6 +43,13 @@ async function request(path, options) { assert.ok(response.ok, `${path}: HTTP ${response.status}`); return response; } +async function expectServices(sfu, natPrediction) { + const capabilities = await (await request("/api/capabilities")).json(); + // Capability metadata is extensible. This gate checks configured services, + // not the absence of other compatible capabilities. + assert.equal(capabilities.sfu, sfu); + assert.equal(capabilities.natPrediction, natPrediction); +} async function binding(port) { const socket = createSocket("udp4"); const packet = Buffer.alloc(20); @@ -79,7 +86,7 @@ try { assert.match(compose("run", "--rm", "--no-deps", "piik", "--check-config"), /config=ok/); compose("up", "-d", "--pull", "never"); await until(async () => assert.deepEqual(await (await request("/healthz")).json(), { status: "ok" }), "ready"); - assert.deepEqual(await (await request("/api/capabilities")).json(), { sfu: false, natPrediction: false }); + await expectServices(false, false); assert.equal((await (await request("/api/site-access")).json()).required, false); const html = await (await request("/")).text(); const asset = html.match(/src="(\/assets\/index-[A-Za-z0-9_-]+\.js)"/)?.[1]; @@ -101,7 +108,7 @@ try { // Recreate with optional services on the same persistent room volume. writeFileSync(join(workspace, ".env"), `${sample}\nSFU_UDP_PORT=7882\nSFU_PUBLIC_IP=127.0.0.1\nNAT_PREDICTION_ENABLED=true\nPIIK_DEBUG=server\n`); compose("up", "-d", "--force-recreate", "--pull", "never"); - await until(async () => assert.deepEqual(await (await request("/api/capabilities")).json(), { sfu: true, natPrediction: true }), "optional services"); + await until(() => expectServices(true, true), "optional services"); await request(`/api/rooms/${room.roomId}/access`, { method: "POST", headers: { Origin: "https://share.example.com", Authorization: `Bearer ${room.hostToken}`, "Content-Type": "application/json" }, diff --git a/scripts/release-version.mjs b/scripts/release-version.mjs index 8a4a2a5..7d8ef1a 100644 --- a/scripts/release-version.mjs +++ b/scripts/release-version.mjs @@ -20,7 +20,7 @@ const nonProductPaths = [ "cmd/**/*.md", "internal/**/*.md", "native/**/*.md", "src/**/*.md", ".github/ISSUE_TEMPLATE/**", ".github/pull_request_template.md", ".github/workflows/website.yml", "scripts/build-website.mjs", "scripts/update-website-hero.mjs", "scripts/check-website-film.js", - "scripts/check-docs.mjs", "scripts/markdown-slug.mjs", "scripts/check-project-state.*", "scripts/install-hooks.*", + "scripts/check-docs.mjs", "scripts/check-container.mjs", "scripts/markdown-slug.mjs", "scripts/check-project-state.*", "scripts/install-hooks.*", "scripts/required-project-paths.txt", "scripts/tsconfig.json", "scripts/release-*.mjs", "scripts/publish-release.mjs", "scripts/publish-container.mjs", "scripts/mirror-release.mjs", "scripts/*-gate.*", "scripts/*-probe.*", "scripts/browser-*", "scripts/encoded-*", diff --git a/tests/release-automation.test.ts b/tests/release-automation.test.ts index ee367b1..6519cae 100644 --- a/tests/release-automation.test.ts +++ b/tests/release-automation.test.ts @@ -90,7 +90,7 @@ describe("release automation", () => { expect(plan()).toMatchObject({ version: "v1.0.0", publish: true }); for (const path of ["site/film/art.js", "site/docs/package.json", "site/docs/package-lock.json", "site/docs/.vitepress/config.mjs", "docs/guide/troubleshooting.md", "docs/deployment.md", "README.zh-CN.md", - "scripts/build-website.mjs", "scripts/check-docs.mjs", "scripts/markdown-slug.mjs", "scripts/release-notes.mjs", + "scripts/build-website.mjs", "scripts/check-docs.mjs", "scripts/check-container.mjs", "scripts/markdown-slug.mjs", "scripts/release-notes.mjs", "scripts/publish-container.mjs", "scripts/app-gate-endpoint.ts", "scripts/client-gate-endpoint.ts", "tests/room.test.ts", ".agents/skills/ponytail/SKILL.md", ".github/workflows/website.yml"]) {