目前项目是使用cordova + vue搭建的,在打包后为了方便测试人员拿到安装包,目前是使用蒲公英这个平台去做发布的,以前是每次打完包之后需要到蒲公英的页面上去发布,后来想到是不是可以拿到蒲公英网页上的上传接口自己做下封装实现上线呢。
直到我发现蒲公英早就替打工仔们想到了,在蒲公英的帮助文档里找到了api!
api文档在这里:www.pgyer.com/doc/view/ap…
那还等什么,直接开干!
在根目录新建一个scripts文件夹,里面新建一个upload.js文件,代码如下:
#!/usr/bin/env node
import fetch, { FormData, fileFromSync } from 'node-fetch'
import shelljs from 'shelljs'
// 蒲公英上传地址
const uploadUrl = 'https://www.pgyer.com/apiv2/app/upload'
// 蒲公英api_key
const apiKey = '[api key]'
// iOS包地址
const iosBundle = './platforms/ios/build/device/[包名].ipa'
// Android包地址
const androidBundle = './platforms/android/app/build/outputs/apk/release/app-release.apk'
// 解析需要上传的是Android还是iOS
process.argv.splice(-1).forEach(arg => {
if (arg === 'android') upload(androidBundle)
if (arg === 'ios') upload(iosBundle)
})
// 封装上传逻辑
function upload(file = '') {
shelljs.which('curl')
? uploadForCurl(file)
: uploadForForm(file)
}
// 使用cURL上传
function uploadForCurl(file = '') {
const sign = shelljs.exec(`curl -F 'file=@${file}' -F '_api_key=${apiKey}' ${uploadUrl}`)
uploaded(sign.code === 0, JSON.parse(sign.stdout), sign)
}
// 使用form方式上传
async function uploadForForm(file = '') {
console.log('正在上传...')
const formData = new FormData()
formData.append('_api_key', apiKey)
formData.append('file', fileFromSync(file))
const res = await fetch(uploadUrl, { method: 'POST', body: formData })
uploaded(res.status === 200, await res.json(), res)
}
/**
* @param {Boolean} success
* @param {Object} response
* @param {any} reject
*/
function uploaded(success, response, reject) {
if (success) {
// 拼接蒲公英地址并打开
const pgyerUrl = 'https://www.pgyer.com/' + response.data.buildKey
console.log(`\n\n 上传成功,下载地址: ${pgyerUrl}`)
shelljs.which('open') && shelljs.exec(`open ${pgyerUrl}`)
} else {
console.log('上传失败:', reject)
}
}
然后在package.json的scripts里加上
"upload:android": "node ./scripts/upload.mjs android",
"upload:ios": "node ./scripts/upload.mjs ios",
这样就可以执行npm run upload:android
直接上传打包出来的安装包了。
到这里还不够,打包和上传我都要!一条命令同时搞定打包和上传它不香么!
于是通过cordova的hooks去执行上传的想法产生了。
在config.xml中加上<hook type="after_build" src="scripts/afterBuild.js"></hook>
afterBuild.js代码如下:
#!/usr/bin/env node
module.exports = function (context) {
return new Promise((resolve, reject) => {
const sign = require('shelljs').exec(`node ./scripts/upload.mjs ${context.opts.platforms[0]}`)
sign.code === 0 ? resolve(true) : reject('上传失败')
})
}
在build命令完成后去执行这个hook,执行上面的上传方法。
就很棒!