fix(release): parallelize agent asset uploads

This commit is contained in:
t8y2 2026-07-14 09:48:23 +08:00
parent ae0e3a2a57
commit 65ea4f855f
2 changed files with 41 additions and 19 deletions

View File

@ -19,7 +19,7 @@ async function main() {
const existingAssets = new Set((release.assets || []).map((asset) => asset.name));
const assets = localAssets(args.assetsDir).filter((assetPath) => {
const name = basename(assetPath);
if (existingAssets.has(name)) {
if (existingAssets.has(name) && !args.overwriteExisting) {
console.log(`Skipping existing CNB asset: ${name}`);
return false;
}
@ -27,7 +27,9 @@ async function main() {
});
console.log(`Uploading ${assets.length} CNB asset(s) with concurrency ${args.concurrency}.`);
await mapWithConcurrency(assets, args.concurrency, (assetPath) => uploadWithRetry(client, release.id, assetPath));
await mapWithConcurrency(assets, args.concurrency, (assetPath) =>
uploadWithRetry(client, release.id, assetPath, args.overwriteExisting),
);
}
function parseArgs(argv) {
@ -36,6 +38,7 @@ function parseArgs(argv) {
repository: process.env.CNB_REPOSITORY || DEFAULT_REPOSITORY,
token: process.env.CNB_TOKEN || "",
concurrency: Number.parseInt(process.env.CNB_UPLOAD_CONCURRENCY || `${DEFAULT_CONCURRENCY}`, 10),
overwriteExisting: false,
githubReleasePath: "",
assetsDir: "",
};
@ -43,6 +46,7 @@ function parseArgs(argv) {
const arg = argv[index];
if (arg === "--github-release") args.githubReleasePath = argv[++index];
else if (arg === "--assets-dir") args.assetsDir = argv[++index];
else if (arg === "--overwrite-existing") args.overwriteExisting = true;
else throw new Error(`Unknown argument: ${arg}`);
}
if (!args.token) throw new Error("CNB_TOKEN is required.");
@ -55,12 +59,12 @@ function parseArgs(argv) {
return args;
}
async function uploadWithRetry(client, releaseId, filePath) {
async function uploadWithRetry(client, releaseId, filePath, overwriteExisting) {
const name = basename(filePath);
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
try {
console.log(`Uploading ${name}, attempt ${attempt}/${MAX_ATTEMPTS}.`);
await client.uploadAsset(releaseId, filePath);
await client.uploadAsset(releaseId, filePath, overwriteExisting);
console.log(`Uploaded ${name}.`);
return;
} catch (error) {
@ -98,12 +102,12 @@ class CnbClient {
return existing;
}
async uploadAsset(releaseId, filePath) {
async uploadAsset(releaseId, filePath, overwriteExisting) {
const size = statSync(filePath).size;
const target = await this.request("POST", `/${this.repository}/-/releases/${releaseId}/asset-upload-url`, {
asset_name: basename(filePath),
size,
overwrite: false,
overwrite: overwriteExisting,
});
const uploadResponse = await fetch(target.upload_url, {
method: "PUT",

View File

@ -563,24 +563,42 @@ jobs:
matrix:
tag: ["${{ github.ref_name }}", "agents-latest"]
steps:
- name: Sync release assets to CNB
- name: Checkout repository
uses: actions/checkout@v5
- name: Download GitHub release assets
env:
TAG_NAME: ${{ matrix.tag }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_USERNAME: ${{ github.repository_owner }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CNB_REPOSITORY: dbxio.com/dbx
CNB_USERNAME: cnb
CNB_TOKEN: ${{ secrets.CNB_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
wget -q https://cnb.cool/znb/mpgrm/-/releases/download/v0.1.0/mpgrm_linux_amd64.tar.gz
tar -xf mpgrm_linux_amd64.tar.gz
chmod +x mpgrm
./mpgrm releases sync \
--repo "https://github.com/${GITHUB_REPOSITORY}.git" \
--target-repo "https://cnb.cool/${CNB_REPOSITORY}.git" \
--tags "${TAG_NAME}"
mkdir -p "$RUNNER_TEMP/github-release" "$RUNNER_TEMP/release-assets"
gh release view "$TAG_NAME" \
--repo "$GITHUB_REPOSITORY" \
--json tagName,name,body,targetCommitish,isPrerelease,isDraft,assets \
> "$RUNNER_TEMP/github-release/release.json"
gh release download "$TAG_NAME" \
--repo "$GITHUB_REPOSITORY" \
--dir "$RUNNER_TEMP/release-assets" \
--clobber
- name: Sync release assets to CNB
env:
CNB_TOKEN: ${{ secrets.CNB_TOKEN }}
CNB_UPLOAD_CONCURRENCY: "3"
OVERWRITE_EXISTING: ${{ matrix.tag == 'agents-latest' }}
run: |
set -euo pipefail
args=(
--github-release "$RUNNER_TEMP/github-release/release.json"
--assets-dir "$RUNNER_TEMP/release-assets"
)
# agents-latest is mutable, so its stable asset names must replace the previous release contents.
if [[ "$OVERWRITE_EXISTING" == "true" ]]; then
args+=(--overwrite-existing)
fi
node .github/scripts/sync-cnb-release.mjs "${args[@]}"
sync-release-to-atomgit:
name: Sync agents releases to AtomGit