import { spawnSync } from 'node:child_process'; import path from 'node:path'; const bucket = process.env.AGC_OSS_BUCKET?.trim() || 'agc-dev'; const endpoint = process.env.AGC_OSS_ENDPOINT?.trim() || 'oss-rg-china-mainland.aliyuncs.com'; if (!/^[a-z0-9][a-z0-9.-]{1,62}$/u.test(bucket) || /[\r\n\0]/u.test(endpoint)) { throw new Error('OSS bucket 或 endpoint 配置无效'); } process.env.AGC_UPDATE_OSS_BASE_URL ||= `https://${bucket}.${endpoint}/agc`; const { generateUpdateManifest, prepareReleaseVersion, runTauriBuild } = await import('./build-release.mjs'); function runOssutil(args) { const binary = process.env.OSSUTIL_BIN?.trim() || 'ossutil'; const accessKeyId = process.env.AGC_OSS_ACCESS_KEY_ID?.trim(); const accessKeySecret = process.env.AGC_OSS_ACCESS_KEY_SECRET; if (Boolean(accessKeyId) !== Boolean(accessKeySecret)) { throw new Error('OSS AccessKey ID 和 Secret 必须同时提供'); } const credentialArgs = accessKeyId ? ['--access-key-id', accessKeyId, '--access-key-secret', accessKeySecret] : []; const result = spawnSync( binary, [...args, '--endpoint', endpoint, ...credentialArgs], { stdio: 'inherit', shell: false, }, ); if (result.error) { throw new Error(`无法执行 ${binary},请先安装并配置 ossutil`); } if (result.status !== 0) process.exit(result.status ?? 1); } await prepareReleaseVersion(); runTauriBuild([]); const { artifact, manifestPath, manifest } = generateUpdateManifest(); const artifactKey = `agc/${manifest.version}/${path.basename(artifact)}`; // Jenkins/ossutil 默认会在目标对象已存在时交互询问并按默认值跳过; // 发布清单是固定的 latest 指针,必须显式覆盖,否则流水线会误报成功但远端仍保留旧版本。 runOssutil(['cp', '--force', artifact, `oss://${bucket}/${artifactKey}`]); runOssutil(['cp', '--force', manifestPath, `oss://${bucket}/agc/latest.json`]); console.log(`[ai-game-creator-shell] 已上传 oss://${bucket}/${artifactKey}`); console.log(`[ai-game-creator-shell] 已上传 oss://${bucket}/agc/latest.json`);