初始提交
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
const del = require('del')
|
||||
// const copyFile = require('./copyFile')
|
||||
|
||||
module.exports = () => {
|
||||
del.sync(['publish/assets/*'])
|
||||
// return copyFile(false)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
const { spawn } = require('child_process')
|
||||
const { jp } = require('./index')
|
||||
const chalk = require('chalk')
|
||||
|
||||
module.exports = () => new Promise((resolve, reject) => {
|
||||
const pack = spawn('node', [jp('../../build-config/pack.js')])
|
||||
|
||||
// pack.stdout.on('data', (data) => {
|
||||
// console.log(chalk.blue(data))
|
||||
// })
|
||||
|
||||
pack.stderr.on('data', (data) => {
|
||||
console.log(chalk.red(data))
|
||||
})
|
||||
|
||||
pack.on('close', code => {
|
||||
if (code === 0) {
|
||||
resolve()
|
||||
} else {
|
||||
console.log(chalk.red('Asset compilation failed.'))
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
const fs = require('fs')
|
||||
const chalk = require('chalk')
|
||||
const { jp, copyFile } = require('./index')
|
||||
|
||||
const buildDir = '../../build'
|
||||
|
||||
|
||||
const getBuildFileName = () => {
|
||||
const names = []
|
||||
const pathRegExp = [
|
||||
/latest\.yml$/,
|
||||
/\.exe$/,
|
||||
/\.blockmap$/,
|
||||
]
|
||||
const files = fs.readdirSync(jp(buildDir), 'utf8')
|
||||
files.forEach(name => {
|
||||
pathRegExp.forEach(regexp => {
|
||||
if (regexp.test(name)) names.push(name)
|
||||
})
|
||||
})
|
||||
return names
|
||||
}
|
||||
|
||||
const copy = names => {
|
||||
const tasks = names.map(name => copyFile(jp(buildDir, name), jp('../assets', name)))
|
||||
return Promise.all(tasks)
|
||||
}
|
||||
|
||||
|
||||
module.exports = (isCopyVersion = true) => {
|
||||
copy(getBuildFileName()).then(() => {
|
||||
if (isCopyVersion) fs.writeFileSync(jp('../assets/version.json'), JSON.stringify(require('../version.json')), 'utf8')
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
console.log(chalk.red('File copy failed.'))
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
const fs = require('fs')
|
||||
const { jp, sizeFormate } = require('./index')
|
||||
const chalk = require('chalk')
|
||||
const COS = require('cos-nodejs-sdk-v5')
|
||||
const config = require('./cosConfig')
|
||||
const MultiProgress = require('multi-progress')
|
||||
const multi = new MultiProgress(process.stderr)
|
||||
|
||||
const cos = new COS({
|
||||
SecretId: config.secretId,
|
||||
SecretKey: config.secretKey,
|
||||
KeepAlive: false,
|
||||
})
|
||||
|
||||
const getCosFileList = () => new Promise((resolve, reject) => {
|
||||
cos.getBucket({
|
||||
Bucket: config.bucket,
|
||||
Region: config.region,
|
||||
Prefix: config.prefix,
|
||||
}, function(err, data) {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
console.log(chalk.red('COS文件列表获取失败'))
|
||||
}
|
||||
resolve(data.Contents.filter(o => o.Key !== config.prefix).map(o => o.Key.replace(config.prefix, '')))
|
||||
})
|
||||
})
|
||||
|
||||
const getLocalFileList = () => fs.readdirSync(jp('../assets'), 'utf8')
|
||||
|
||||
const diffFileList = (localFiles, cosFiles) => {
|
||||
const removeFiles = []
|
||||
cosFiles.forEach(file => {
|
||||
let index = localFiles.indexOf(file)
|
||||
if (index < 0) return removeFiles.push(file)
|
||||
localFiles.splice(index, 1)
|
||||
})
|
||||
if (cosFiles.includes('latest.yml')) {
|
||||
removeFiles.push('latest.yml')
|
||||
localFiles.push('latest.yml')
|
||||
}
|
||||
if (cosFiles.includes('version.json')) {
|
||||
removeFiles.push('version.json')
|
||||
localFiles.push('version.json')
|
||||
}
|
||||
return removeFiles
|
||||
}
|
||||
|
||||
const deleteCosFiles = files => new Promise((resolve, reject) => {
|
||||
files = files.map(f => ({ Key: config.prefix + f }))
|
||||
cos.deleteMultipleObject({
|
||||
Bucket: config.bucket,
|
||||
Region: config.region,
|
||||
Objects: files,
|
||||
}, function(err, data) {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
const createProgressBar = (name, spacekLen, total) => multi.newBar(
|
||||
`${` ${name}`.padEnd(spacekLen, ' ')} :status [:bar] :current/:total :percent :speed`, {
|
||||
complete: '=',
|
||||
incomplete: ' ',
|
||||
width: 30,
|
||||
total,
|
||||
})
|
||||
|
||||
|
||||
const uploadFile = (fileName, len) => new Promise((resolve, reject) => {
|
||||
const filePath = jp('../assets', fileName)
|
||||
// let size = fs.statSync(filePath).size
|
||||
let bar = null
|
||||
let prevLoaded = 0
|
||||
|
||||
cos.sliceUploadFile({
|
||||
Bucket: config.bucket,
|
||||
Region: config.region,
|
||||
Key: config.prefix + fileName, /* 必须 */
|
||||
FilePath: filePath, /* 必须 */
|
||||
// TaskReady: function(taskId) { /* 非必须 */
|
||||
// console.log(taskId)
|
||||
// },
|
||||
onHashProgress(progressData) { /* 非必须 */
|
||||
if (!bar) {
|
||||
bar = createProgressBar(fileName, len, progressData.total)
|
||||
prevLoaded = 0
|
||||
}
|
||||
bar.tick(progressData.loaded - prevLoaded, {
|
||||
status: '校验中',
|
||||
speed: sizeFormate(progressData.speed) + '/s',
|
||||
})
|
||||
prevLoaded = progressData.loaded
|
||||
// console.log('校验', fileName, JSON.stringify(progressData))
|
||||
// console.log('校验', JSON.stringify(progressData))
|
||||
},
|
||||
onProgress(progressData) { /* 非必须 */
|
||||
if (!bar) {
|
||||
bar = createProgressBar(fileName, len, progressData.total)
|
||||
prevLoaded = 0
|
||||
}
|
||||
bar.tick(progressData.loaded - prevLoaded, {
|
||||
status: '上传中',
|
||||
speed: sizeFormate(progressData.speed) + '/s',
|
||||
})
|
||||
prevLoaded = progressData.loaded
|
||||
// console.log('上传', fileName, JSON.stringify(progressData))
|
||||
// console.log('上传', JSON.stringify(progressData))
|
||||
},
|
||||
}, (err, data) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
return reject(err)
|
||||
}
|
||||
bar.tick({
|
||||
status: '已完成',
|
||||
speed: '',
|
||||
})
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
module.exports = async() => {
|
||||
console.log(chalk.blue('正在获取COS文件列表...'))
|
||||
const cosFiles = await getCosFileList()
|
||||
console.log(chalk.green('COS文件列表获取成功'))
|
||||
const uploadFiles = getLocalFileList()
|
||||
const removeFiles = diffFileList(uploadFiles, cosFiles)
|
||||
if (removeFiles.length) {
|
||||
console.log(chalk.blue('共需删除') + chalk.yellow(removeFiles.length) + chalk.blue('个文件'))
|
||||
console.log(chalk.blue('正在从COS删除多余的文件...'))
|
||||
await deleteCosFiles(removeFiles)
|
||||
console.log(chalk.green('多余文件删除成功'))
|
||||
} else {
|
||||
console.log(chalk.blue('没有在COS发现多余的文件'))
|
||||
}
|
||||
if (uploadFiles.length) {
|
||||
console.log(chalk.blue('共需上传') + chalk.green(uploadFiles.length) + chalk.blue('个文件'))
|
||||
console.log(chalk.blue('正在上传新文件到COS...'))
|
||||
let max = Math.max(...uploadFiles.map(f => f.length)) + 2
|
||||
let tasks = uploadFiles.map(f => uploadFile(f, max))
|
||||
await Promise.all(tasks)
|
||||
console.log(''.padEnd(Math.max(2, tasks.length - 2), '\n'))
|
||||
console.log(chalk.green('所有文件上传完成'))
|
||||
} else {
|
||||
console.log(chalk.blue('没有需要上传的文件'))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
secretId: '',
|
||||
secretKey: '',
|
||||
|
||||
bucket: '', // 存储桶
|
||||
region: '', // 区域
|
||||
prefix: '', // 路径
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
const fs = require('fs')
|
||||
const ghRelease = require('gh-release')
|
||||
const token = require('./githubToken')
|
||||
const pkg = require('../../package.json')
|
||||
const { jp } = require('./index')
|
||||
|
||||
const changeLog = fs.readFileSync(jp('../changeLog.md'), 'utf-8')
|
||||
|
||||
const assetsDir = '../assets'
|
||||
|
||||
const getBuildFiles = () => {
|
||||
const files = []
|
||||
const pathRegExp = [
|
||||
/latest\.yml$/,
|
||||
/\.exe$/,
|
||||
/\.blockmap$/,
|
||||
]
|
||||
const names = fs.readdirSync(jp(assetsDir), 'utf8')
|
||||
names.forEach(name => {
|
||||
pathRegExp.forEach(regexp => {
|
||||
if (regexp.test(name)) files.push(jp(assetsDir, name))
|
||||
})
|
||||
})
|
||||
return files
|
||||
}
|
||||
|
||||
// all options have defaults and can be omitted
|
||||
const options = {
|
||||
tag_name: `v${pkg.version}`,
|
||||
target_commitish: 'master',
|
||||
name: `v${pkg.version}`,
|
||||
body: changeLog,
|
||||
draft: false,
|
||||
prerelease: false,
|
||||
repo: pkg.name,
|
||||
owner: pkg.author,
|
||||
endpoint: 'https://api.github.com', // for GitHub enterprise, use http(s)://hostname/api/v3
|
||||
auth: {
|
||||
token,
|
||||
},
|
||||
assets: getBuildFiles(),
|
||||
}
|
||||
|
||||
|
||||
module.exports = ({ isDraft = false, isPrerelease = false, target_commitish = 'master' }) => new Promise((resolve, reject) => {
|
||||
options.target_commitish = target_commitish
|
||||
options.draft = isDraft
|
||||
options.prerelease = isPrerelease
|
||||
|
||||
ghRelease(options, function(err, result) {
|
||||
if (err) return reject(err)
|
||||
resolve(result)
|
||||
console.log(result) // create release response: https://developer.github.com/v3/repos/releases/#response-4
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
exports.jp = (...p) => p.length ? path.join(__dirname, ...p) : __dirname
|
||||
|
||||
exports.copyFile = (source, target) => new Promise((resolve, reject) => {
|
||||
const rd = fs.createReadStream(source)
|
||||
rd.on('error', err => reject(err))
|
||||
const wr = fs.createWriteStream(target)
|
||||
wr.on('error', err => reject(err))
|
||||
wr.on('close', () => resolve())
|
||||
rd.pipe(wr)
|
||||
})
|
||||
|
||||
/**
|
||||
* 时间格式化
|
||||
* @param {Date} d 格式化的时间
|
||||
* @param {boolean} b 是否精确到秒
|
||||
*/
|
||||
exports.formatTime = (d, b) => {
|
||||
const _date = d == null ? new Date() : typeof d == 'string' ? new Date(d) : d
|
||||
const year = _date.getFullYear()
|
||||
const month = fm(_date.getMonth() + 1)
|
||||
const day = fm(_date.getDate())
|
||||
if (!b) return year + '-' + month + '-' + day
|
||||
return year + '-' + month + '-' + day + ' ' + fm(_date.getHours()) + ':' + fm(_date.getMinutes()) + ':' + fm(_date.getSeconds())
|
||||
}
|
||||
|
||||
function fm(value) {
|
||||
if (value < 10) return '0' + value
|
||||
return value
|
||||
}
|
||||
|
||||
exports.sizeFormate = size => {
|
||||
// https://gist.github.com/thomseddon/3511330
|
||||
if (!size) return '0 b'
|
||||
let units = ['b', 'kB', 'MB', 'GB', 'TB']
|
||||
let number = Math.floor(Math.log(size) / Math.log(1024))
|
||||
return `${(size / Math.pow(1024, Math.floor(number))).toFixed(2)} ${units[number]}`
|
||||
}
|
||||
|
||||
exports.parseArgv = argv => {
|
||||
const params = {}
|
||||
argv.forEach(item => {
|
||||
const argv = item.split('=')
|
||||
switch (argv[0]) {
|
||||
case 'ver':
|
||||
params.ver = argv[1]
|
||||
break
|
||||
case 'draft':
|
||||
params.isDraft = argv[1] === 'true' || argv[1] === undefined
|
||||
break
|
||||
case 'prerelease':
|
||||
params.isPrerelease = argv[1] === 'true' || argv[1] === undefined
|
||||
break
|
||||
case 'target_commitish':
|
||||
params.target_commitish = argv[1]
|
||||
break
|
||||
}
|
||||
})
|
||||
return params
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
const builder = require('electron-builder')
|
||||
const chalk = require('chalk')
|
||||
|
||||
// Promise is returned
|
||||
module.exports = () => builder.build().catch(error => {
|
||||
console.log(error)
|
||||
console.log(chalk.red('Asset build failed.'))
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
const fs = require('fs')
|
||||
const { jp, formatTime } = require('./index')
|
||||
const pkgDir = '../../package.json'
|
||||
const pkg = require(pkgDir)
|
||||
const version = require('../version.json')
|
||||
const chalk = require('chalk')
|
||||
const pkg_bak = JSON.stringify(pkg, null, 2)
|
||||
const version_bak = JSON.stringify(version, null, 2)
|
||||
const parseChangelog = require('changelog-parser')
|
||||
const changelogPath = jp('../../CHANGELOG.md')
|
||||
|
||||
const md_renderer = markdownStr => new (require('markdown-it'))({
|
||||
html: true,
|
||||
linkify: true,
|
||||
typographer: true,
|
||||
breaks: true,
|
||||
}).render(markdownStr)
|
||||
|
||||
const getPrevVer = () => parseChangelog(changelogPath).then(res => {
|
||||
if (!res.versions.length) throw new Error('CHANGELOG 无法解析到版本号')
|
||||
return res.versions[0].version
|
||||
})
|
||||
|
||||
const updateChangeLog = async(newVerNum, newChangeLog) => {
|
||||
let changeLog = fs.readFileSync(changelogPath, 'utf-8')
|
||||
const prevVer = await getPrevVer()
|
||||
const log = `## [${newVerNum}](${pkg.repository.url.replace(/^git\+(http.+)\.git$/, '$1')}/compare/v${prevVer}...v${newVerNum}) - ${formatTime()}\n\n${newChangeLog}`
|
||||
fs.writeFileSync(changelogPath, changeLog.replace(new RegExp(`(## [?0.1.1]?)`), log + '\n$1'), 'utf-8')
|
||||
}
|
||||
|
||||
const renderChangeLog = md => md_renderer(md)
|
||||
|
||||
|
||||
module.exports = async newVerNum => {
|
||||
if (!newVerNum) {
|
||||
let verArr = pkg.version.split('.')
|
||||
verArr[verArr.length - 1] = parseInt(verArr[verArr.length - 1]) + 1
|
||||
newVerNum = verArr.join('.')
|
||||
}
|
||||
const newMDChangeLog = fs.readFileSync(jp('../changeLog.md'), 'utf-8')
|
||||
const newChangeLog = renderChangeLog(newMDChangeLog)
|
||||
version.history.unshift({
|
||||
version: version.version,
|
||||
desc: version.desc,
|
||||
})
|
||||
version.version = newVerNum
|
||||
version.desc = newChangeLog
|
||||
pkg.version = newVerNum
|
||||
|
||||
console.log(chalk.blue('new version: ') + chalk.green(newVerNum))
|
||||
|
||||
fs.writeFileSync(jp('../version.json'), JSON.stringify(version, null, 2) + '\n', 'utf-8')
|
||||
|
||||
fs.writeFileSync(jp(pkgDir), JSON.stringify(pkg, null, 2) + '\n', 'utf-8')
|
||||
|
||||
await updateChangeLog(newVerNum, newMDChangeLog)
|
||||
|
||||
return {
|
||||
pkg_bak,
|
||||
version_bak,
|
||||
changeLog: newChangeLog,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user