Files

77 lines
3.0 KiB
JavaScript
Raw Permalink Normal View History

#!/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}`)