From 6bbaed8d17c487796f9df2ae19c686d7e70e2919 Mon Sep 17 00:00:00 2001 From: stevelliu Date: Mon, 31 Aug 2026 16:58:22 +0800 Subject: [PATCH] =?UTF-8?q?fix(updater):=20=E4=BD=BF=E7=94=A8=E7=A8=B3?= =?UTF-8?q?=E5=AE=9A=E7=9A=84=20Release=20=E4=B8=8B=E8=BD=BD=E5=9C=B0?= =?UTF-8?q?=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 13 ++++++++ package.json | 2 +- scripts/stabilize-updater-json.mjs | 40 +++++++++++++++++++++++++ scripts/stabilize-updater-json.test.mjs | 23 ++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 scripts/stabilize-updater-json.mjs create mode 100644 scripts/stabilize-updater-json.test.mjs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 722cccf..a44225a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -139,6 +139,19 @@ jobs: permissions: contents: write steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Stabilize updater download URLs + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + mkdir -p "${RUNNER_TEMP}/chattake-updater" + gh release download "${GITHUB_REF_NAME}" --repo "${GITHUB_REPOSITORY}" --pattern latest.json --dir "${RUNNER_TEMP}/chattake-updater" + gh release view "${GITHUB_REF_NAME}" --repo "${GITHUB_REPOSITORY}" --json assets > "${RUNNER_TEMP}/chattake-updater/assets.json" + node scripts/stabilize-updater-json.mjs "${RUNNER_TEMP}/chattake-updater/latest.json" "${RUNNER_TEMP}/chattake-updater/assets.json" + gh release upload "${GITHUB_REF_NAME}" --repo "${GITHUB_REPOSITORY}" "${RUNNER_TEMP}/chattake-updater/latest.json" --clobber + - name: Publish complete Release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index c86914f..ace2dc6 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "sync:changelog": "node scripts/sync-changelog.mjs", "check:release-version": "node scripts/check-release-version.mjs", "build:companions": "bun scripts/build-companions.mjs", - "verify": "bun --cwd packages/sidecar test && bun --cwd packages/mcp-server test && cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml && bun run --cwd apps/desktop build", + "verify": "node --test scripts/stabilize-updater-json.test.mjs && bun --cwd packages/sidecar test && bun --cwd packages/mcp-server test && cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml && bun run --cwd apps/desktop build", "build:debug": "bun run build:companions && cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml && bun run --cwd apps/desktop tauri -- build --debug --no-bundle" }, "workspaces": [ diff --git a/scripts/stabilize-updater-json.mjs b/scripts/stabilize-updater-json.mjs new file mode 100644 index 0000000..ae4dcee --- /dev/null +++ b/scripts/stabilize-updater-json.mjs @@ -0,0 +1,40 @@ +import { readFileSync, writeFileSync } from 'node:fs' +import { fileURLToPath } from 'node:url' +import { resolve } from 'node:path' + +export function stabilizeUpdaterJson(latest, release) { + if (!latest?.platforms || !Array.isArray(release?.assets)) { + throw new Error('latest.json 或 Release assets 格式无效') + } + + const stableUrlByApiUrl = new Map( + release.assets.map((asset) => [asset.apiUrl, asset.url]), + ) + const result = structuredClone(latest) + + for (const [platform, config] of Object.entries(result.platforms)) { + if (typeof config?.url !== 'string') { + throw new Error(`${platform} 缺少 updater URL`) + } + if (!config.url.startsWith('https://api.github.com/')) continue + + const stableUrl = stableUrlByApiUrl.get(config.url) + if (!stableUrl) { + throw new Error(`${platform} 的 updater 资产不在当前 Release 中`) + } + config.url = stableUrl + } + + return result +} + +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + const [latestPath, assetsPath] = process.argv.slice(2) + if (!latestPath || !assetsPath) { + throw new Error('用法: node scripts/stabilize-updater-json.mjs ') + } + const latest = JSON.parse(readFileSync(latestPath, 'utf8')) + const release = JSON.parse(readFileSync(assetsPath, 'utf8')) + const stable = stabilizeUpdaterJson(latest, release) + writeFileSync(latestPath, `${JSON.stringify(stable, null, 2)}\n`) +} diff --git a/scripts/stabilize-updater-json.test.mjs b/scripts/stabilize-updater-json.test.mjs new file mode 100644 index 0000000..e97f096 --- /dev/null +++ b/scripts/stabilize-updater-json.test.mjs @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict' +import test from 'node:test' + +import { stabilizeUpdaterJson } from './stabilize-updater-json.mjs' + +test('replaces GitHub asset API URLs with stable download URLs', () => { + const apiUrl = 'https://api.github.com/repos/owner/repo/releases/assets/123' + const stableUrl = 'https://github.com/owner/repo/releases/download/v1.2.3/app.tar.gz' + const latest = { + version: '1.2.3', + platforms: { + 'darwin-aarch64': { url: apiUrl, signature: 'sig' }, + 'darwin-aarch64-app': { url: apiUrl, signature: 'sig' }, + }, + } + + const result = stabilizeUpdaterJson(latest, { + assets: [{ apiUrl, url: stableUrl }], + }) + + assert.equal(result.platforms['darwin-aarch64'].url, stableUrl) + assert.equal(result.platforms['darwin-aarch64-app'].url, stableUrl) +})