aaa434afbd
The About section hardcoded its version; the main process now exposes get-app-info so it reads app.getVersion() dynamically, and the update result carries the manifest release date. The manifest generator orders versions numerically (0.10.0 outranks 0.9.0). A new stage-release script copies releases.json plus installers into the deepseek-harness-web site root's updates/, which deploy.py publishes to OSS alongside the download page, so the app and web share one update channel. The About section also gains links to the release site and official site. Co-Authored-By: Claude <noreply@anthropic.com>
77 lines
3.0 KiB
JavaScript
77 lines
3.0 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Generate the OSS update manifest (`releases.json`) from the packaged
|
|
* installers in `apps/desktop/dist`. The manifest drives both the desktop app's
|
|
* manual "check for updates" (main-process fetch + version compare) and the
|
|
* web download page. Run after `desktop:pack`, then upload `releases.json`
|
|
* together with the installers to the OSS `updates/` folder.
|
|
*
|
|
* The installer URLs are derived from the `DSH_UPDATE_BASE` (default
|
|
* `https://deepseek.pinesound.cn/updates/`) plus the artifact filename.
|
|
* `DSH_RELEASE_NOTES` optionally supplies the release-notes text.
|
|
*/
|
|
|
|
import { readdirSync, writeFileSync } from 'node:fs'
|
|
import { dirname, join, resolve } from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const root = resolve(dirname(fileURLToPath(import.meta.url)), '../../..')
|
|
const dist = join(root, 'apps/desktop/dist')
|
|
const base = process.env.DSH_UPDATE_BASE ?? 'https://deepseek.pinesound.cn/updates/'
|
|
|
|
/** Extract a semver-ish version from a filename like `…0.1.0-rc.5-arm64.dmg`. */
|
|
function versionOf(filename) {
|
|
const base = filename.replace(/\.(dmg|exe)$/, '').replace(/-(arm64|x64)$/, '')
|
|
const match = /(\d+\.\d+\.\d+(?:-[0-9A-Za-z.]+)?)$/.exec(base)
|
|
return match === null ? undefined : match[1]
|
|
}
|
|
|
|
/** Order two versions: numeric segments first, then the pre-release suffix. */
|
|
function compareVersions(a, b) {
|
|
const num = (v) => v.split(/[-+]/)[0].split('.').map((n) => Number(n))
|
|
const pre = (v) => { const i = v.indexOf('-'); return i === -1 ? '' : v.slice(i + 1) }
|
|
const an = num(a), bn = num(b)
|
|
for (let i = 0; i < 3; i++) {
|
|
if (an[i] !== bn[i]) return an[i] - bn[i]
|
|
}
|
|
// Equal numeric core: a release with a pre-release suffix is OLDER than a
|
|
// stable one (e.g. `1.0.0-rc.1` < `1.0.0`); two suffixes compare by string.
|
|
const ap = pre(a), bp = pre(b)
|
|
if (ap === bp) return 0
|
|
if (ap === '') return 1
|
|
if (bp === '') return -1
|
|
return ap < bp ? -1 : 1
|
|
}
|
|
|
|
const platforms = {}
|
|
let latestVersion
|
|
let latestDate = process.env.DSH_RELEASE_DATE ?? new Date().toISOString().slice(0, 10)
|
|
|
|
for (const entry of readdirSync(dist)) {
|
|
if (!entry.endsWith('.dmg') && !entry.endsWith('.exe')) continue
|
|
const version = versionOf(entry)
|
|
if (version === undefined) continue
|
|
const key = entry.endsWith('.dmg')
|
|
? entry.includes('arm64') ? 'mac-arm64' : 'mac-x64'
|
|
: 'win-x64'
|
|
platforms[key] = { url: `${base}${encodeURIComponent(entry)}` }
|
|
if (latestVersion === undefined || compareVersions(version, latestVersion) > 0) {
|
|
latestVersion = version
|
|
latestDate = process.env.DSH_RELEASE_DATE ?? new Date().toISOString().slice(0, 10)
|
|
}
|
|
}
|
|
|
|
if (latestVersion === undefined) {
|
|
console.error(`generate-release-json: no installers found in ${dist}`)
|
|
process.exit(1)
|
|
}
|
|
|
|
const manifest = {
|
|
latest: { version: latestVersion, date: latestDate },
|
|
releaseNotes: process.env.DSH_RELEASE_NOTES ?? '',
|
|
platforms,
|
|
}
|
|
|
|
writeFileSync(join(dist, 'releases.json'), `${JSON.stringify(manifest, null, 2)}\n`)
|
|
console.log(`wrote ${join(dist, 'releases.json')} for ${latestVersion}`)
|