78 lines
2.5 KiB
JavaScript
78 lines
2.5 KiB
JavaScript
import { createHash } from 'node:crypto'
|
||
import { createReadStream, createWriteStream } from 'node:fs'
|
||
import { mkdir, readFile, stat } from 'node:fs/promises'
|
||
import path from 'node:path'
|
||
import { fileURLToPath } from 'node:url'
|
||
import { ZipArchive } from 'archiver'
|
||
|
||
const scriptDirectory = path.dirname(fileURLToPath(import.meta.url))
|
||
const webDirectory = path.resolve(scriptDirectory, '..')
|
||
const distDirectory = path.join(webDirectory, 'dist')
|
||
const versionIndex = process.argv.indexOf('--version')
|
||
const requestedVersion =
|
||
versionIndex >= 0 ? process.argv[versionIndex + 1] : undefined
|
||
const versionProps = await readFile(path.join(webDirectory, '..', 'versions.props'), 'utf8')
|
||
const version = /<JiaowuFrontendVersion>([^<]+)<\/JiaowuFrontendVersion>/.exec(
|
||
versionProps,
|
||
)?.[1]?.trim()
|
||
|
||
if (!version) {
|
||
throw new Error('versions.props 中缺少 JiaowuFrontendVersion。')
|
||
}
|
||
|
||
if (versionIndex >= 0 && !requestedVersion) {
|
||
throw new Error('请在 --version 后提供版本号。')
|
||
}
|
||
|
||
if (requestedVersion && requestedVersion !== version) {
|
||
throw new Error(
|
||
`更新包版本必须与 JiaowuFrontendVersion 一致(当前为 ${version})。`,
|
||
)
|
||
}
|
||
|
||
if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z]+(?:[.-][0-9A-Za-z]+)*)?$/.test(version)) {
|
||
throw new Error('JiaowuFrontendVersion 必须使用语义版本,例如 1.0.1。')
|
||
}
|
||
|
||
await stat(path.join(distDirectory, 'index.html')).catch(() => {
|
||
throw new Error('dist/index.html 不存在,请先完成 Capacitor 前端构建。')
|
||
})
|
||
|
||
const outputDirectory = path.resolve(
|
||
webDirectory,
|
||
'..',
|
||
'.artifacts',
|
||
'app-updates',
|
||
)
|
||
await mkdir(outputDirectory, { recursive: true })
|
||
const outputPath = path.join(
|
||
outputDirectory,
|
||
`jiaowu-web-${version}.zip`,
|
||
)
|
||
|
||
await new Promise((resolve, reject) => {
|
||
const output = createWriteStream(outputPath)
|
||
const archive = new ZipArchive({ zlib: { level: 9 } })
|
||
output.on('close', resolve)
|
||
output.on('error', reject)
|
||
archive.on('warning', reject)
|
||
archive.on('error', reject)
|
||
archive.pipe(output)
|
||
archive.directory(distDirectory, false)
|
||
archive.finalize()
|
||
})
|
||
|
||
const hash = createHash('sha256')
|
||
await new Promise((resolve, reject) => {
|
||
const source = createReadStream(outputPath)
|
||
source.on('data', (chunk) => hash.update(chunk))
|
||
source.on('end', resolve)
|
||
source.on('error', reject)
|
||
})
|
||
const file = await stat(outputPath)
|
||
|
||
console.log(`更新包:${outputPath}`)
|
||
console.log(`版本:${version}`)
|
||
console.log(`大小:${file.size} bytes`)
|
||
console.log(`SHA-256:${hash.digest('hex')}`)
|