Files
tutti/tools/scripts/desktop-release-upload.test.mjs
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

117 lines
3.5 KiB
JavaScript

import assert from "node:assert/strict";
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import test from "node:test";
import {
resolveUploadUrl,
uploadReleaseAssets
} from "../../apps/desktop/scripts/upload-github-release-assets.mjs";
test("release asset upload uses the REST upload URL returned for the release", async () => {
const dir = await mkdtemp(path.join(tmpdir(), "desktop-release-upload-"));
const releasePath = path.join(dir, "release.json");
const assetsDirectory = path.join(dir, "assets");
await mkdir(assetsDirectory);
await writeFile(
releasePath,
JSON.stringify({
id: 42,
upload_url:
"https://uploads.github.test/repos/tutti-os/tutti/releases/42/assets{?name,label}"
})
);
await writeFile(path.join(assetsDirectory, "b file.zip"), "second");
await writeFile(path.join(assetsDirectory, "a.dmg"), "first");
const requests = [];
const fetchImpl = async (url, init) => {
const chunks = [];
for await (const chunk of init.body) chunks.push(chunk);
requests.push({
url: String(url),
method: init.method,
headers: init.headers,
body: Buffer.concat(chunks).toString("utf8")
});
return new Response(null, { status: 201 });
};
try {
const result = await uploadReleaseAssets({
releasePath,
assetsDirectory,
token: "test-token",
fetchImpl
});
assert.deepEqual(result, {
releaseId: "42",
assetNames: ["a.dmg", "b file.zip"]
});
assert.deepEqual(
requests.map(({ url, body }) => ({ url, body })),
[
{
url: "https://uploads.github.test/repos/tutti-os/tutti/releases/42/assets?name=a.dmg",
body: "first"
},
{
url: "https://uploads.github.test/repos/tutti-os/tutti/releases/42/assets?name=b+file.zip",
body: "second"
}
]
);
for (const request of requests) {
assert.equal(request.method, "POST");
assert.equal(request.headers.Authorization, "Bearer test-token");
assert.equal(request.headers["Content-Type"], "application/octet-stream");
assert.equal(
request.headers["Content-Length"],
String(request.body.length)
);
}
} finally {
await rm(dir, { force: true, recursive: true });
}
});
test("release asset upload reports the release id and failed asset", async () => {
const dir = await mkdtemp(path.join(tmpdir(), "desktop-release-upload-"));
const releasePath = path.join(dir, "release.json");
await writeFile(
releasePath,
JSON.stringify({
id: 99,
upload_url:
"https://uploads.github.test/repos/tutti-os/tutti/releases/99/assets{?name,label}"
})
);
await writeFile(path.join(dir, "broken.zip"), "payload");
try {
await assert.rejects(
uploadReleaseAssets({
releasePath,
assetsDirectory: dir,
token: "test-token",
fetchImpl: async () => new Response("upstream failure", { status: 502 })
}),
/Failed to upload broken\.zip to GitHub release 99: 502 upstream failure/
);
} finally {
await rm(dir, { force: true, recursive: true });
}
});
test("release upload URL preserves the endpoint and encodes the asset name", () => {
assert.equal(
resolveUploadUrl(
"https://uploads.github.com/releases/7/assets{?name,label}",
"Tutti Setup.exe"
).href,
"https://uploads.github.com/releases/7/assets?name=Tutti+Setup.exe"
);
});