- tauri.conf.json: endpoints now points at the website-hosted manifest (https://<azure-swa>/updater/latest.json) so the already-built UpdateChecker actually has somewhere to check. - website/public/updater/latest.json: placeholder manifest with empty platforms map (clients will see "up to date" until a real release ships). - scripts/build-updater-manifest.mjs: helper that ingests signed Tauri bundle artifacts and emits the manifest, so future releases are one node command instead of hand-edited JSON. - scripts/UPDATER.md: step-by-step for every release — what to set, what to upload, where to commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
102 lines
3.1 KiB
JavaScript
102 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Build the updater manifest (latest.json) consumed by tauri-plugin-updater.
|
|
*
|
|
* Usage:
|
|
* node scripts/build-updater-manifest.mjs \
|
|
* --version 0.1.1 \
|
|
* --notes "Bugfix release" \
|
|
* --base-url https://your-cdn.example.com/releases/0.1.1 \
|
|
* [--windows-x86_64 ./bundle/heicode_0.1.1_x64-setup.exe] \
|
|
* [--darwin-aarch64 ./bundle/heicode_0.1.1_aarch64.app.tar.gz] \
|
|
* [--darwin-x86_64 ./bundle/heicode_0.1.1_x64.app.tar.gz] \
|
|
* [--linux-x86_64 ./bundle/heicode_0.1.1_amd64.AppImage] \
|
|
* --out ../../../website/public/updater/latest.json
|
|
*
|
|
* For each platform path supplied, the script reads the sibling `.sig` file
|
|
* that `tauri build` produced (because `createUpdaterArtifacts: true` is
|
|
* set in tauri.conf.json) and inlines its contents into the manifest. The
|
|
* `url` field is built from `--base-url` + basename of the artifact, so the
|
|
* uploader is free to put artifacts wherever — release CDN, Azure Blob,
|
|
* GitHub Release assets — as long as `--base-url` matches.
|
|
*/
|
|
import { readFileSync, writeFileSync, mkdirSync, statSync } from 'node:fs'
|
|
import { dirname, basename, resolve } from 'node:path'
|
|
import { argv } from 'node:process'
|
|
|
|
function parseArgs(rawArgs) {
|
|
const out = {}
|
|
for (let i = 0; i < rawArgs.length; i++) {
|
|
const key = rawArgs[i]
|
|
if (!key?.startsWith('--')) continue
|
|
const k = key.slice(2)
|
|
const next = rawArgs[i + 1]
|
|
if (!next || next.startsWith('--')) {
|
|
out[k] = true
|
|
} else {
|
|
out[k] = next
|
|
i++
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
const PLATFORM_KEYS = [
|
|
'windows-x86_64',
|
|
'darwin-aarch64',
|
|
'darwin-x86_64',
|
|
'linux-x86_64',
|
|
]
|
|
|
|
const args = parseArgs(argv.slice(2))
|
|
if (!args.version || !args['base-url'] || !args.out) {
|
|
console.error('Required: --version, --base-url, --out')
|
|
process.exit(2)
|
|
}
|
|
|
|
const platforms = {}
|
|
for (const key of PLATFORM_KEYS) {
|
|
const path = args[key]
|
|
if (!path || path === true) continue
|
|
const resolvedPath = resolve(path)
|
|
try {
|
|
statSync(resolvedPath)
|
|
} catch {
|
|
console.error(`Artifact not found for ${key}: ${resolvedPath}`)
|
|
process.exit(3)
|
|
}
|
|
const sigPath = `${resolvedPath}.sig`
|
|
let signature
|
|
try {
|
|
signature = readFileSync(sigPath, 'utf8').trim()
|
|
} catch {
|
|
console.error(`Signature file missing: ${sigPath}`)
|
|
console.error('Run `bun run tauri build` with TAURI_SIGNING_PRIVATE_KEY set.')
|
|
process.exit(4)
|
|
}
|
|
platforms[key] = {
|
|
signature,
|
|
url: `${args['base-url'].replace(/\/$/, '')}/${basename(resolvedPath)}`,
|
|
}
|
|
}
|
|
|
|
if (Object.keys(platforms).length === 0) {
|
|
console.error('No platform artifacts supplied — manifest would be empty.')
|
|
process.exit(5)
|
|
}
|
|
|
|
const manifest = {
|
|
version: args.version,
|
|
notes: args.notes || `Heicode ${args.version}`,
|
|
pub_date: new Date().toISOString(),
|
|
platforms,
|
|
}
|
|
|
|
const outPath = resolve(args.out)
|
|
mkdirSync(dirname(outPath), { recursive: true })
|
|
writeFileSync(outPath, `${JSON.stringify(manifest, null, 2)}\n`)
|
|
console.log(`Wrote ${outPath}`)
|
|
console.log(` version = ${manifest.version}`)
|
|
console.log(` pub_date = ${manifest.pub_date}`)
|
|
console.log(` platforms = ${Object.keys(platforms).join(', ')}`)
|