feat: ship skill and MCP workflows with signed updater for v0.0.7
This commit is contained in:
1 parent
1b52df0603
commit
a01085c656
136 files changed
+18646
-217
No files matched your search
@@ -0,0 +1,71 @@
|
||||
import fsp from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import {
|
||||
DEFAULT_BASE_URL,
|
||||
DEFAULT_PRIVATE_KEY,
|
||||
DEFAULT_PUBLIC_KEY,
|
||||
assertOutsideRepo,
|
||||
buildManifestPayload,
|
||||
canonicalNow,
|
||||
createSignedManifest,
|
||||
normalizeBaseUrl,
|
||||
parseOptions,
|
||||
readPrivateKey,
|
||||
readPublicKey,
|
||||
resolvePath,
|
||||
serializeSignedManifest,
|
||||
usageError,
|
||||
verifyReleaseInstaller,
|
||||
verifySignedManifest,
|
||||
writeFileAtomic
|
||||
} from './lib.mjs'
|
||||
|
||||
const usage = `Usage:
|
||||
node scripts/updates/prepare-release.mjs --installer <YCode-Setup.exe> --version <x.y.z>
|
||||
--notes-zh <text> --notes-en <text> [--base-url <url>] [--published-at <ISO>]
|
||||
[--private-key <path>] [--public-key <path>] [--output <latest.json>]
|
||||
|
||||
This validates the actual EXE ProductVersion, current package.json version, size and SHA-256,
|
||||
then signs exact JSON.stringify(payload) with Ed25519. It never deploys.
|
||||
`
|
||||
|
||||
async function main() {
|
||||
const options = parseOptions(process.argv.slice(2), {
|
||||
values: ['installer', 'version', 'notes-zh', 'notes-en', 'base-url', 'published-at', 'private-key', 'public-key', 'output']
|
||||
})
|
||||
if (!options.installer || !options.version || !options['notes-zh'] || !options['notes-en']) {
|
||||
throw new Error('--installer, --version, --notes-zh and --notes-en are required')
|
||||
}
|
||||
|
||||
const baseUrl = normalizeBaseUrl(options['base-url'] || DEFAULT_BASE_URL)
|
||||
const installerPath = resolvePath(options.installer)
|
||||
const installer = await verifyReleaseInstaller(installerPath, options.version)
|
||||
const output = resolvePath(options.output || path.join('.tmp', 'updates', options.version, 'latest.json'))
|
||||
const privateKeyPath = await assertOutsideRepo(
|
||||
resolvePath(options['private-key'] || DEFAULT_PRIVATE_KEY),
|
||||
'Private key'
|
||||
)
|
||||
const privateKey = await readPrivateKey(privateKeyPath)
|
||||
const publicKeyPath = resolvePath(options['public-key'] || DEFAULT_PUBLIC_KEY)
|
||||
const publicKey = await readPublicKey(publicKeyPath)
|
||||
const payload = buildManifestPayload({
|
||||
version: options.version,
|
||||
publishedAt: options['published-at'] || canonicalNow(),
|
||||
notes: { zh: options['notes-zh'], en: options['notes-en'] },
|
||||
installer,
|
||||
baseUrl
|
||||
})
|
||||
const document = createSignedManifest({ payload, privateKeyPem: privateKey, publicKeyPem: publicKey, baseUrl })
|
||||
verifySignedManifest(document, publicKey, { baseUrl })
|
||||
await writeFileAtomic(output, serializeSignedManifest(document))
|
||||
await fsp.access(output)
|
||||
|
||||
console.log(`Manifest: ${output}`)
|
||||
console.log(`Version: ${payload.version}`)
|
||||
console.log(`Installer: ${installer.filename}`)
|
||||
console.log(`Size: ${installer.size}`)
|
||||
console.log(`SHA-256: ${installer.sha256}`)
|
||||
console.log(`URL: ${payload.platforms['windows-x64'].url}`)
|
||||
}
|
||||
|
||||
main().catch((error) => usageError(usage, error))
|
||||
Reference in new issue
Block a user