mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-18 03:23:28 +03:00
Try to split the artifacts when package is bigger than 400MB.
This commit is contained in:
@@ -52,12 +52,20 @@ jobs:
|
||||
|
||||
- name: Upload development environment
|
||||
if: github.event_name == 'push'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: eepp-dev-linux-x86_64
|
||||
path: ${{ runner.temp }}/eepp-dev-linux-x86_64.tar.zst
|
||||
retention-days: 5
|
||||
compression-level: 0
|
||||
run: |
|
||||
npm install \
|
||||
--no-save \
|
||||
--no-package-lock \
|
||||
--prefix "$RUNNER_TEMP/eepp-artifact-uploader" \
|
||||
@actions/artifact@6.2.1
|
||||
|
||||
NODE_PATH="$RUNNER_TEMP/eepp-artifact-uploader/node_modules" \
|
||||
node projects/scripts/upload_split_artifact.cjs \
|
||||
"$RUNNER_TEMP/eepp-dev-linux-x86_64.tar.zst" \
|
||||
eepp-dev-linux-x86_64 \
|
||||
400M \
|
||||
5 \
|
||||
8
|
||||
- name: Set SDK version
|
||||
id: sdk_version
|
||||
run: |
|
||||
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { pipeline } = require('stream/promises');
|
||||
const { DefaultArtifactClient } = require('@actions/artifact');
|
||||
|
||||
function parseSize(value) {
|
||||
const match = /^(\d+)([KMG]?)$/i.exec(value);
|
||||
if (!match)
|
||||
throw new Error(`Invalid size '${value}' (expected e.g. 400M)`);
|
||||
|
||||
const multipliers = {
|
||||
'': 1,
|
||||
K: 1024,
|
||||
M: 1024 * 1024,
|
||||
G: 1024 * 1024 * 1024,
|
||||
};
|
||||
|
||||
return Number(match[1]) * multipliers[match[2].toUpperCase()];
|
||||
}
|
||||
|
||||
async function writeChunk(source, destination, start, end) {
|
||||
await pipeline(
|
||||
fs.createReadStream(source, { start, end }),
|
||||
fs.createWriteStream(destination)
|
||||
);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const [
|
||||
archiveArg,
|
||||
artifactPrefix = 'eepp-dev-linux-x86_64',
|
||||
chunkSizeArg = '400M',
|
||||
retentionDaysArg = '5',
|
||||
maxPartsArg = '8',
|
||||
] = process.argv.slice(2);
|
||||
|
||||
if (!archiveArg) {
|
||||
console.error(
|
||||
'Usage: upload_split_artifact.cjs <archive> [artifact-prefix] [chunk-size] [retention-days] [max-parts]'
|
||||
);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const archive = path.resolve(archiveArg);
|
||||
const chunkSize = parseSize(chunkSizeArg);
|
||||
const retentionDays = Number(retentionDaysArg);
|
||||
const maxParts = Number(maxPartsArg);
|
||||
const stat = await fs.promises.stat(archive);
|
||||
|
||||
if (!stat.isFile())
|
||||
throw new Error(`Not a regular file: ${archive}`);
|
||||
if (!Number.isInteger(retentionDays) || retentionDays < 1)
|
||||
throw new Error(`Invalid retention days: ${retentionDaysArg}`);
|
||||
if (!Number.isInteger(maxParts) || maxParts < 1)
|
||||
throw new Error(`Invalid max parts: ${maxPartsArg}`);
|
||||
|
||||
const partCount = Math.ceil(stat.size / chunkSize);
|
||||
if (partCount > maxParts) {
|
||||
throw new Error(
|
||||
`Archive requires ${partCount} artifacts at ${chunkSizeArg} per part, ` +
|
||||
`but the configured maximum is ${maxParts}. Increase the chunk size or artifact budget.`
|
||||
);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Uploading ${archive} (${stat.size} bytes) as ${partCount} artifact part(s) of at most ${chunkSizeArg}`
|
||||
);
|
||||
|
||||
const artifact = new DefaultArtifactClient();
|
||||
const suffixWidth = Math.max(2, String(partCount - 1).length);
|
||||
|
||||
for (let index = 0; index < partCount; ++index) {
|
||||
const suffix = String(index).padStart(suffixWidth, '0');
|
||||
const partPath = `${archive}.part-${suffix}`;
|
||||
const start = index * chunkSize;
|
||||
const end = Math.min(stat.size, start + chunkSize) - 1;
|
||||
const artifactName = `${artifactPrefix}-part-${suffix}`;
|
||||
|
||||
console.log(
|
||||
`Creating ${path.basename(partPath)} (${start}-${end}, ${end - start + 1} bytes)`
|
||||
);
|
||||
await writeChunk(archive, partPath, start, end);
|
||||
|
||||
try {
|
||||
const { id, size } = await artifact.uploadArtifact(
|
||||
artifactName,
|
||||
[partPath],
|
||||
{
|
||||
retentionDays,
|
||||
compressionLevel: 0,
|
||||
}
|
||||
);
|
||||
console.log(`Uploaded ${artifactName}: id=${id}, size=${size}`);
|
||||
} finally {
|
||||
await fs.promises.rm(partPath, { force: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error.stack || error.message || error);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user