fix: big file uploads (#562)
* fix: use readableWebStream() to stream asset contents This allows the uploads to finish without mismatched Content-Length, likely because the original method implied a wrong body encoding or something similar. Unfortunately a GitHub server API mock was not readily available so I had to test manually with a barebones repository. Fixes: #555 Fixes: #556 Signed-off-by: WANG Xuerui <git@xen0n.name> * feat: log when each asset is successfully uploaded Signed-off-by: WANG Xuerui <git@xen0n.name> * build: refresh dist Signed-off-by: WANG Xuerui <git@xen0n.name> * style: format with prettier Signed-off-by: WANG Xuerui <git@xen0n.name> --------- Signed-off-by: WANG Xuerui <git@xen0n.name>
This commit is contained in:
parent
33fcd69d45
commit
deddb09c64
@ -14,11 +14,10 @@ describe("github", () => {
|
|||||||
|
|
||||||
describe("asset", () => {
|
describe("asset", () => {
|
||||||
it("derives asset info from a path", async () => {
|
it("derives asset info from a path", async () => {
|
||||||
const { name, mime, size, data } = asset("tests/data/foo/bar.txt");
|
const { name, mime, size } = asset("tests/data/foo/bar.txt");
|
||||||
assert.equal(name, "bar.txt");
|
assert.equal(name, "bar.txt");
|
||||||
assert.equal(mime, "text/plain");
|
assert.equal(mime, "text/plain");
|
||||||
assert.equal(size, 10);
|
assert.equal(size, 10);
|
||||||
assert.equal(await text(data), "release me");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,7 @@
|
|||||||
import { GitHub } from "@actions/github/lib/utils";
|
import { GitHub } from "@actions/github/lib/utils";
|
||||||
import { Config, isTag, releaseBody, alignAssetName } from "./util";
|
import { Config, isTag, releaseBody, alignAssetName } from "./util";
|
||||||
import { createReadStream, statSync, type ReadStream } from "fs";
|
import { statSync } from "fs";
|
||||||
|
import { open } from "fs/promises";
|
||||||
import { getType } from "mime";
|
import { getType } from "mime";
|
||||||
import { basename } from "path";
|
import { basename } from "path";
|
||||||
|
|
||||||
@ -10,7 +11,6 @@ export interface ReleaseAsset {
|
|||||||
name: string;
|
name: string;
|
||||||
mime: string;
|
mime: string;
|
||||||
size: number;
|
size: number;
|
||||||
data: ReadStream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Release {
|
export interface Release {
|
||||||
@ -145,7 +145,6 @@ export const asset = (path: string): ReleaseAsset => {
|
|||||||
name: basename(path),
|
name: basename(path),
|
||||||
mime: mimeOrDefault(path),
|
mime: mimeOrDefault(path),
|
||||||
size: statSync(path).size,
|
size: statSync(path).size,
|
||||||
data: createReadStream(path, "binary"),
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -161,7 +160,7 @@ export const upload = async (
|
|||||||
currentAssets: Array<{ id: number; name: string }>,
|
currentAssets: Array<{ id: number; name: string }>,
|
||||||
): Promise<any> => {
|
): Promise<any> => {
|
||||||
const [owner, repo] = config.github_repository.split("/");
|
const [owner, repo] = config.github_repository.split("/");
|
||||||
const { name, size, mime, data: body } = asset(path);
|
const { name, mime, size } = asset(path);
|
||||||
const currentAsset = currentAssets.find(
|
const currentAsset = currentAssets.find(
|
||||||
// note: GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The "List release assets" endpoint lists the renamed filenames.
|
// note: GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The "List release assets" endpoint lists the renamed filenames.
|
||||||
// due to this renaming we need to be mindful when we compare the file name we're uploading with a name github may already have rewritten for logical comparison
|
// due to this renaming we need to be mindful when we compare the file name we're uploading with a name github may already have rewritten for logical comparison
|
||||||
@ -179,25 +178,31 @@ export const upload = async (
|
|||||||
console.log(`⬆️ Uploading ${name}...`);
|
console.log(`⬆️ Uploading ${name}...`);
|
||||||
const endpoint = new URL(url);
|
const endpoint = new URL(url);
|
||||||
endpoint.searchParams.append("name", name);
|
endpoint.searchParams.append("name", name);
|
||||||
const resp = await github.request({
|
const fh = await open(path);
|
||||||
method: "POST",
|
try {
|
||||||
url: endpoint.toString(),
|
const resp = await github.request({
|
||||||
headers: {
|
method: "POST",
|
||||||
"content-length": `${size}`,
|
url: endpoint.toString(),
|
||||||
"content-type": mime,
|
headers: {
|
||||||
authorization: `token ${config.github_token}`,
|
"content-length": `${size}`,
|
||||||
},
|
"content-type": mime,
|
||||||
data: body,
|
authorization: `token ${config.github_token}`,
|
||||||
});
|
},
|
||||||
const json = resp.data;
|
data: fh.readableWebStream({ type: "bytes" }),
|
||||||
if (resp.status !== 201) {
|
});
|
||||||
throw new Error(
|
const json = resp.data;
|
||||||
`Failed to upload release asset ${name}. received status code ${
|
if (resp.status !== 201) {
|
||||||
resp.status
|
throw new Error(
|
||||||
}\n${json.message}\n${JSON.stringify(json.errors)}`,
|
`Failed to upload release asset ${name}. received status code ${
|
||||||
);
|
resp.status
|
||||||
|
}\n${json.message}\n${JSON.stringify(json.errors)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log(`✅ Uploaded ${name}`);
|
||||||
|
return json;
|
||||||
|
} finally {
|
||||||
|
await fh.close();
|
||||||
}
|
}
|
||||||
return json;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const release = async (
|
export const release = async (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user