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.
This commit is contained in:
3 files changed
+11
-4
No files matched your search
@@ -43,6 +43,13 @@ async function request(path, options) {
|
|||||||
assert.ok(response.ok, `${path}: HTTP ${response.status}`);
|
assert.ok(response.ok, `${path}: HTTP ${response.status}`);
|
||||||
return response;
|
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) {
|
async function binding(port) {
|
||||||
const socket = createSocket("udp4");
|
const socket = createSocket("udp4");
|
||||||
const packet = Buffer.alloc(20);
|
const packet = Buffer.alloc(20);
|
||||||
@@ -79,7 +86,7 @@ try {
|
|||||||
assert.match(compose("run", "--rm", "--no-deps", "piik", "--check-config"), /config=ok/);
|
assert.match(compose("run", "--rm", "--no-deps", "piik", "--check-config"), /config=ok/);
|
||||||
compose("up", "-d", "--pull", "never");
|
compose("up", "-d", "--pull", "never");
|
||||||
await until(async () => assert.deepEqual(await (await request("/healthz")).json(), { status: "ok" }), "ready");
|
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);
|
assert.equal((await (await request("/api/site-access")).json()).required, false);
|
||||||
const html = await (await request("/")).text();
|
const html = await (await request("/")).text();
|
||||||
const asset = html.match(/src="(\/assets\/index-[A-Za-z0-9_-]+\.js)"/)?.[1];
|
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.
|
// 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`);
|
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");
|
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`, {
|
await request(`/api/rooms/${room.roomId}/access`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { Origin: "https://share.example.com", Authorization: `Bearer ${room.hostToken}`, "Content-Type": "application/json" },
|
headers: { Origin: "https://share.example.com", Authorization: `Bearer ${room.hostToken}`, "Content-Type": "application/json" },
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const nonProductPaths = [
|
|||||||
"cmd/**/*.md", "internal/**/*.md", "native/**/*.md", "src/**/*.md",
|
"cmd/**/*.md", "internal/**/*.md", "native/**/*.md", "src/**/*.md",
|
||||||
".github/ISSUE_TEMPLATE/**", ".github/pull_request_template.md", ".github/workflows/website.yml",
|
".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/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/required-project-paths.txt", "scripts/tsconfig.json",
|
||||||
"scripts/release-*.mjs", "scripts/publish-release.mjs", "scripts/publish-container.mjs", "scripts/mirror-release.mjs",
|
"scripts/release-*.mjs", "scripts/publish-release.mjs", "scripts/publish-container.mjs", "scripts/mirror-release.mjs",
|
||||||
"scripts/*-gate.*", "scripts/*-probe.*", "scripts/browser-*", "scripts/encoded-*",
|
"scripts/*-gate.*", "scripts/*-probe.*", "scripts/browser-*", "scripts/encoded-*",
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ describe("release automation", () => {
|
|||||||
expect(plan()).toMatchObject({ version: "v1.0.0", publish: true });
|
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",
|
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",
|
"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/publish-container.mjs",
|
||||||
"scripts/app-gate-endpoint.ts", "scripts/client-gate-endpoint.ts",
|
"scripts/app-gate-endpoint.ts", "scripts/client-gate-endpoint.ts",
|
||||||
"tests/room.test.ts", ".agents/skills/ponytail/SKILL.md", ".github/workflows/website.yml"]) {
|
"tests/room.test.ts", ".agents/skills/ponytail/SKILL.md", ".github/workflows/website.yml"]) {
|
||||||
|
|||||||
Reference in new issue
Block a user