From e746559dc05365099a577fcdbfdab19649347bb9 Mon Sep 17 00:00:00 2001 From: kdletters Date: Tue, 1 Sep 2026 14:23:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5Jenkins=20OSS=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E5=87=AD=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通过受保护凭据注入阿里云AccessKey 让Windows x64发布流水线完成安装包和latest.json上传 --- .../scripts/release-upload.mjs | 20 ++++++++++++++---- ...方案】AGC客户端更新检查与下载-2026-08-31.md | 10 +++++---- .../Jenkinsfile.ai-game-creator-shell-build | 21 ++++++++++++------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/apps/ai-game-creator-shell/scripts/release-upload.mjs b/apps/ai-game-creator-shell/scripts/release-upload.mjs index 43bd53520..e2085345a 100644 --- a/apps/ai-game-creator-shell/scripts/release-upload.mjs +++ b/apps/ai-game-creator-shell/scripts/release-upload.mjs @@ -14,10 +14,22 @@ const { generateUpdateManifest, prepareReleaseVersion, runTauriBuild } = function runOssutil(args) { const binary = process.env.OSSUTIL_BIN?.trim() || 'ossutil'; - const result = spawnSync(binary, [...args, '--endpoint', endpoint], { - stdio: 'inherit', - shell: false, - }); + 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`); } diff --git a/docs/technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md b/docs/technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md index e3128e7fe..01ca8122e 100644 --- a/docs/technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md +++ b/docs/technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md @@ -39,12 +39,12 @@ OSS 请求失败、清单格式错误或版本无效会终止发布,避免覆 Windows x64),通过 `AGC_UPDATE_ARTIFACT` 指定要发布的安装包,通过 `AGC_UPDATE_OSS_BASE_URL` 指定 OSS 前缀,通过 `AGC_UPDATE_RELEASE_NOTES` 写入发布说明;`--no-bundle` smoke 构建不会读取 OSS、修改版本或生成清单。 -每次发布安装包上传完成后,再上传同一目录生成的 `latest.json`,确保 `downloadUrl` 指向已存在的 OSS 对象;清单和安装包均使用公开可读对象,不在清单中保存凭据、签名或本地路径。构建脚本不自动上传 OSS,避免把 AccessKey 写入本地配置或 CI 日志。 +每次发布安装包上传完成后,再上传同一目录生成的 `latest.json`,确保 `downloadUrl` 指向已存在的 OSS 对象;清单和安装包均使用公开可读对象,不在清单中保存凭据、签名或本地路径。构建脚本本身不负责上传 OSS,发布流水线通过 `release:upload` 完成上传。 如需一键构建并上传,可执行 `npm run ai-game-creator-shell:release:upload`。该命令要求本机已安装并配置 `ossutil`, 先按上述规则比较 OSS 版本、递增 patch、构建 Windows x64 NSIS,再上传安装包和 `latest.json`。默认上传到 `agc-dev` / `oss-rg-china-mainland.aliyuncs.com`,也可用 `AGC_OSS_BUCKET`、`AGC_OSS_ENDPOINT` 和 `OSSUTIL_BIN` -覆盖;凭据由 ossutil 本机配置读取,不能写入仓库或命令行参数。 +覆盖;本机执行时凭据由 ossutil 本机配置读取,不能写入仓库或命令行参数。 ## Jenkins Windows 构建节点 @@ -54,6 +54,8 @@ AGC 发布流水线使用 `jenkins/Jenkinsfile.ai-game-creator-shell-build`, Jenkins Agent 服务必须能在同一用户环境中找到这些命令。流水线执行根 workspace 的 `npm ci`,然后调用 `npm run ai-game-creator-shell:release:upload`,并归档 Windows 安装包、`latest.json` 与源码 commit。 -Jenkins 节点上的 ossutil 必须使用具备 `PutObject` 权限的受保护配置;OSS 对客户端保持公共读即可, -公共读本身不授予 Jenkins 上传权限。由于版本号取决于 OSS 当前清单,Job 已关闭并发构建;若 Jenkins +Jenkins Job 在“Build and upload”阶段通过受保护凭据 ID `AliyunAccessKeyId` 和 +`AliyunaccessKeySecret` 注入 AccessKey,仅在当前进程运行时传给 ossutil,不写入仓库、workspace 或构建日志; +本机运行仍使用 ossutil 配置。凭据必须具备 `PutObject` 权限;OSS 对客户端保持公共读即可,公共读本身不授予 +Jenkins 上传权限。由于版本号取决于 OSS 当前清单,Job 已关闭并发构建;若 Jenkins 上存在多个 AGC 发布 Job,还应使用同一个 Lockable Resource 串行化发布。 diff --git a/jenkins/Jenkinsfile.ai-game-creator-shell-build b/jenkins/Jenkinsfile.ai-game-creator-shell-build index c2e74bcfd..f8fd93c8a 100644 --- a/jenkins/Jenkinsfile.ai-game-creator-shell-build +++ b/jenkins/Jenkinsfile.ai-game-creator-shell-build @@ -112,15 +112,20 @@ pipeline { stage('Build and upload') { steps { - withEnv([ - "PATH=${env.AGC_WINDOWS_PATH}", - "OSSUTIL_BIN=${params.OSSUTIL_BIN}", - "AGC_UPDATE_RELEASE_NOTES=${params.AGC_UPDATE_RELEASE_NOTES}", + withCredentials([ + string(credentialsId: 'AliyunAccessKeyId', variable: 'AGC_OSS_ACCESS_KEY_ID'), + string(credentialsId: 'AliyunaccessKeySecret', variable: 'AGC_OSS_ACCESS_KEY_SECRET'), ]) { - powershell ''' - $ErrorActionPreference = 'Stop' - npm run ai-game-creator-shell:release:upload - ''' + withEnv([ + "PATH=${env.AGC_WINDOWS_PATH}", + "OSSUTIL_BIN=${params.OSSUTIL_BIN}", + "AGC_UPDATE_RELEASE_NOTES=${params.AGC_UPDATE_RELEASE_NOTES}", + ]) { + powershell ''' + $ErrorActionPreference = 'Stop' + npm run ai-game-creator-shell:release:upload + ''' + } } } }