From 27a9c358096b4fd4817c0588eb2ab8b89aab3d47 Mon Sep 17 00:00:00 2001 From: whyour Date: Mon, 26 Oct 2026 00:16:28 +0800 Subject: [PATCH] build: name develop upgrade batches by workflow run (#3113) --- docs/development/platform-upgrade-bundles.md | 2 +- scripts/publish-upgrade-bundles.cjs | 12 +++++---- test/back/publish-upgrade-bundles.test.cjs | 27 +++++++++++--------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/docs/development/platform-upgrade-bundles.md b/docs/development/platform-upgrade-bundles.md index 6b2f019f..315553fa 100644 --- a/docs/development/platform-upgrade-bundles.md +++ b/docs/development/platform-upgrade-bundles.md @@ -14,7 +14,7 @@ CI 从同次构建的不可变镜像摘要导出完整 tar.gz,包含源码中 gh workflow run build-docker-image.yml --ref develop ``` -开发包更新共用的 `upgrade-develop/latest.json`。`develop` 和 `debian-dev` 镜像都使用该索引,按实际 Node 架构和 musl/glibc 选择包,无需设置测试专用下载源。开发批次位于 `upgrade-build-develop-v--`,不会改写正式版本或 `upgrade-master`。同一开发渠道的镜像构建和包发布串行执行,与 master 独立。 +开发包更新共用的 `upgrade-develop/latest.json`。`develop` 和 `debian-dev` 镜像都使用该索引,按实际 Node 架构和 musl/glibc 选择包,无需设置测试专用下载源。开发批次位于 `upgrade-build-develop--`,tag 不带版本号;索引中仍保留开发版本供客户端判断更新。开发批次不会改写正式版本或 `upgrade-master`。同一开发渠道的镜像构建和包发布串行执行,与 master 独立。 开发包只保留最新一个已验证批次:所有平台资产和渠道索引的大小、SHA256 校验成功后,删除其他名称匹配的开发构建 prerelease;不删除正式包、渠道索引或无法分类的旧 release。构建或上传失败不会删除上一套可用包。旧批次被删除后,已选中旧索引但尚未下载完的客户端可能需要重新发起下载;准备失败仍保留旧服务和数据。 diff --git a/scripts/publish-upgrade-bundles.cjs b/scripts/publish-upgrade-bundles.cjs index 866d206b..9d4773df 100644 --- a/scripts/publish-upgrade-bundles.cjs +++ b/scripts/publish-upgrade-bundles.cjs @@ -75,9 +75,9 @@ function publishBundles({ // unchanged. Only the version/channel pointer is overwritten, never bytes // that an in-flight download has already selected by hash. const development = branch === 'develop'; - const tag = `upgrade-build-${ - development ? 'develop-' : '' - }v${version}-${buildId}`; + const tag = development + ? `upgrade-build-develop-${buildId}` + : `upgrade-build-v${version}-${buildId}`; const index = { ...releaseIndex(directory, commit, repository, { version, @@ -149,7 +149,9 @@ function publishBundles({ } ensureRelease( tag, - `${development ? 'Development platform upgrade' : 'Platform upgrade'} v${version} (${buildId})`, + development + ? `Development platform upgrade (${buildId})` + : `Platform upgrade v${version} (${buildId})`, ); const assets = platforms .flatMap((target) => { @@ -243,7 +245,7 @@ function publishBundles({ for (const release of pages.flat()) { if ( release.tag_name !== tag && - /^upgrade-build-develop-v\d+\.\d+\.\d+(?:-[\w.-]+)?(?:\+[\w.-]+)?-\d+-\d+$/.test( + /^upgrade-build-develop-(?:v\d+\.\d+\.\d+(?:-[\w.-]+)?(?:\+[\w.-]+)?-)?\d+-\d+$/.test( release.tag_name, ) && release.prerelease === true && diff --git a/test/back/publish-upgrade-bundles.test.cjs b/test/back/publish-upgrade-bundles.test.cjs index 1bad0613..627a2d5c 100644 --- a/test/back/publish-upgrade-bundles.test.cjs +++ b/test/back/publish-upgrade-bundles.test.cjs @@ -366,22 +366,22 @@ test('automatic development publication keeps its prerelease version separate fr ...Object.values(development.packages), development.installer, ]) - assert.ok(entry.url.includes('/upgrade-build-develop-v2.24.0-dev.0-100-1/')); + assert.ok(entry.url.includes('/upgrade-build-develop-100-1/')); assert.ok( f.state.calls.some( (args) => args[0] === 'release' && args[1] === 'create' && - args[2] === 'upgrade-build-develop-v2.24.0-dev.0-100-1' && + args[2] === 'upgrade-build-develop-100-1' && args[args.indexOf('--title') + 1] === - 'Development platform upgrade v2.24.0-dev.0 (100-1)', + 'Development platform upgrade (100-1)', ), ); assert.deepEqual(f.index(), production); assert.deepEqual(f.index('upgrade-v2.24.0'), production); assert.equal(f.state.releases.get('upgrade-build-v2.24.0-100-1').size, 24); assert.equal( - f.state.releases.get('upgrade-build-develop-v2.24.0-dev.0-100-1').size, + f.state.releases.get('upgrade-build-develop-100-1').size, 24, ); }); @@ -433,14 +433,16 @@ for (const fault of [ const options = { branch: 'develop', commit: f.state.developHead }; f.write(options.commit, 'development'); f.publish(options); - const oldTag = 'upgrade-build-develop-v2.24.0-100-1'; + const oldTag = 'upgrade-build-develop-100-1'; + const legacyTag = 'upgrade-build-develop-v2.24.0-99-1'; + f.state.releases.set(legacyTag, new Map()); // Never prune production, channel aliases, legacy/unclassified releases, // drafts or a non-prerelease even when its name resembles a dev build. const protectedTags = [ 'upgrade-86c37f426a5ba9945d6af1910a7885a26f77e4bc', 'v2.24.0', - 'upgrade-build-develop-v2.24.0-10-1', - 'upgrade-build-develop-v2.24.0-11-1', + 'upgrade-build-develop-10-1', + 'upgrade-build-develop-11-1', ]; for (const tag of protectedTags) f.state.releases.set(tag, new Map()); f.state.releaseMetadata = { @@ -472,9 +474,10 @@ for (const fault of [ a[0] === 'api' && a[1].includes('/releases/tags/upgrade-develop'), ), ); - assert.ok(f.state.releases.has('upgrade-build-develop-v2.24.0-101-1')); + assert.ok(f.state.releases.has('upgrade-build-develop-101-1')); } assert.equal(f.state.releases.has(oldTag), Boolean(fault)); + assert.equal(f.state.releases.has(legacyTag), Boolean(fault)); for (const tag of protectedTags) assert.ok(f.state.releases.has(tag)); assert.deepEqual(f.index(), production); assert.deepEqual(f.index('upgrade-v2.24.0'), production); @@ -491,11 +494,11 @@ test('failed development cleanup is retryable without overwriting immutable asse /Delete unavailable/, ); assert.equal(f.index('upgrade-develop').buildId, '101-1'); - assert.ok(f.state.releases.has('upgrade-build-develop-v2.24.0-100-1')); + assert.ok(f.state.releases.has('upgrade-build-develop-100-1')); f.state.failDelete = false; f.publish({ ...options, buildId: '101-1' }); - assert.ok(!f.state.releases.has('upgrade-build-develop-v2.24.0-100-1')); - assert.ok(f.state.releases.has('upgrade-build-develop-v2.24.0-101-1')); + assert.ok(!f.state.releases.has('upgrade-build-develop-100-1')); + assert.ok(f.state.releases.has('upgrade-build-develop-101-1')); }); test('a newer development commit during upload preserves the published channel and its old package', (t) => { @@ -507,7 +510,7 @@ test('a newer development commit during upload preserves the published channel a f.state.changeDevelopHeadAfterUpload = true; assert.equal(f.publish({ ...options, buildId: '101-1' }), false); assert.deepEqual(f.index('upgrade-develop'), before); - assert.ok(f.state.releases.has('upgrade-build-develop-v2.24.0-100-1')); + assert.ok(f.state.releases.has('upgrade-build-develop-100-1')); assert.ok( !f.state.calls.some((a) => a[0] === 'release' && a[1] === 'delete'), );