60 lines
2.7 KiB
JavaScript
60 lines
2.7 KiB
JavaScript
import { createHash } from 'node:crypto'
|
|
import { access, copyFile, mkdir, readFile, stat, writeFile } from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { buildPlan, root, targets } from './build-plugins.mjs'
|
|
|
|
export function packagePlan(target) {
|
|
buildPlan({ target })
|
|
const [goos, goarch] = target.split('_')
|
|
const extension = goos === 'windows' ? '.exe' : ''
|
|
const suffix = `${goos === 'darwin' ? 'mac' : goos}_${goarch}${extension}`
|
|
const directory = path.join(root, 'out', 'package', target)
|
|
return [
|
|
...['smail', 'smail-admin'].map(name => ({
|
|
source: path.join(root, 'out', 'backend', `${name}_${suffix}`),
|
|
target: path.join(directory, `${name}${extension}`)
|
|
}))
|
|
]
|
|
}
|
|
|
|
async function digestFile(filename) {
|
|
const [bytes, info] = await Promise.all([readFile(filename), stat(filename)])
|
|
if (!info.isFile() || info.size === 0) throw new Error(`发布产物无效:${filename}`)
|
|
return { bytes: info.size, sha256: createHash('sha256').update(bytes).digest('hex') }
|
|
}
|
|
|
|
export async function packageRelease(selectedTargets = targets) {
|
|
const plan = selectedTargets.flatMap(packagePlan)
|
|
// 所有输入齐备后才写发布目录,不把旧的或其他平台插件混入发布包。
|
|
for (const item of plan) await access(item.source)
|
|
for (const item of plan) {
|
|
await mkdir(path.dirname(item.target), { recursive: true })
|
|
await copyFile(item.source, item.target)
|
|
}
|
|
for (const target of selectedTargets) {
|
|
for (const name of ['config', 'ssl', 'data', 'log']) await mkdir(path.join(root, 'out', 'package', target, name), { recursive: true })
|
|
await mkdir(path.join(root, 'out', 'release-receipts'), { recursive: true })
|
|
const directory = path.join(root, 'out', 'package', target)
|
|
const files = await Promise.all(plan
|
|
.filter(item => path.dirname(item.target) === directory)
|
|
.map(async item => ({
|
|
name: path.basename(item.target),
|
|
...await digestFile(item.target)
|
|
})))
|
|
await writeFile(path.join(root, 'out', 'release-receipts', `${target}.json`), JSON.stringify({
|
|
version: process.env.SMAIL_VERSION || 'dev', gitHash: process.env.GIT_HASH || '',
|
|
protocolVersion: 1, target, plugins: buildPlan({ target }).map(item => item.id), files,
|
|
createdAt: new Date().toISOString()
|
|
}, null, 2) + '\n')
|
|
}
|
|
console.log(`发布包已生成:${selectedTargets.map(target => `out/package/${target}`).join('、')}`)
|
|
}
|
|
|
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
packageRelease(process.argv.length > 2 ? process.argv.slice(2) : targets).catch(error => {
|
|
console.error(`发布打包失败:${error.message}`)
|
|
process.exitCode = 1
|
|
})
|
|
}
|