const fs = require("fs"); const path = require("path"); const https = require("https"); const ci = require("miniprogram-ci"); const execSync = require("child_process").execSync; const distDir = path.resolve(__dirname, "../dist"); // 实例化小程序 ci const project = new ci.Project({ appid: "", type: "miniProgram", projectPath: path.resolve(distDir, "./build/mp-weixin"), privateKeyPath: path.resolve(__dirname, "./private..key"), ignores: [], }); // 钉钉webhook const dingTalkWebHook = `https://oapi.dingtalk.com/robot/send?access_token=${ process.env.DINGTALK_WEBHOOK_TOKEN || "" }`; const gitShortKey = execSync("git rev-parse --short HEAD").toString().trim(); const gitCommitMsg = execSync("git log --pretty=format:“%s” -1") .toString() .trim() .replace(/(^["“])|(["”]$)/g, ""); const gitCommitName = execSync("git log --pretty=format:“%cn” -1") .toString() .trim() .replace(/(^["“])|(["”]$)/g, ""); let desc = `${gitCommitName}: ${gitCommitMsg}`; if (process.env.change_desc && process.env.operator) { desc = `${process.env.operator}: ${process.env.change_desc}`; } // 发布钉钉通知 const postDingTalk = (qrcode, isPro = false, version) => { const ver = isPro ? "体验版" : "开发版"; const data = JSON.stringify({ msgtype: "markdown", markdown: { title: `小程序 【${ver}】上传成功`, text: `# [小程序 【${ver}】](${qrcode})上传成功 \n\n @13718996400 \n\n > ${desc} ${ version ? `\n\n > version: ${version}` : "" } \n\n ![小程序二维码](${qrcode})${ isPro ? " \n\n 小程序发布请前往[小程序版本管理](https://mp.weixin.qq.com/)" : "" }`, }, at: { atMobiles: ["13718996400"], atUserIds: [""], isAtAll: false, }, }); return new Promise((resolve, reject) => { const req = https.request( { hostname: "oapi.dingtalk.com", port: 443, path: dingTalkWebHook, method: "POST", headers: { "Content-Type": "application/json", }, }, (res) => { res.on("data", (d) => { const resData = JSON.parse(d.toString()); if (res.statusCode === 200 && resData.errcode === 0) { resolve(resData); } else { reject(resData); } }); } ); req.on("error", (e) => { reject(e); }); req.write(data); req.end(); }); }; const onProgressUpdate = (taskStatus) => { switch (taskStatus._status) { case "doing": console.log("上传中: ", taskStatus._msg); break; case "done": console.log("上传完成: ", taskStatus._msg); break; } }; // 测试环境用开发版,不上传至小程序后台 const preview = async () => { try { fs.mkdirSync(path.resolve(distDir, `./qrcode`)); } catch (e) {} const previewResult = await ci.preview({ project, desc, setting: {}, qrcodeFormat: "image", qrcodeOutputDest: path.resolve(distDir, `./qrcode/${gitShortKey}.jpg`), onProgressUpdate, pagePath: "pages/index/index", // 预览页面 // searchQuery: 'a=1&b=2', // 预览参数 [注意!]这里的`&`字符在命令行中应写成转义字符`\&` }); console.log("小程序上传完成🚀 ", previewResult); try { console.info("上传二维码完成 🚀", `/${gitShortKey}.jpg`); } catch (e) { console.info("上传出错,请检查网络或过会再试 ❌", e); throw new Error(e); } try { await postDingTalk(`/${gitShortKey}.jpg`); } catch (e) {} }; // 正式环境用体验版,上传至小程序后台 const publish = async () => { const version = process.env.MP_VERSON || process.env.version ? `1.0.${process.env.version}` : "1.0.0"; try { const uploadResult = await ci.upload({ project, version, desc, setting: {}, onProgressUpdate, }); console.log("小程序上传完成🚀 ", uploadResult); } catch (e) { console.info("上传出错,请检查网络或过会再试 ❌", e); throw new Error(e); } try { await postDingTalk(`.jpg`, true, version); } catch (e) { console.log("钉钉通知失败:", e); } }; (async () => { if (process.argv.includes("--publish")) { console.log("发布小程序🚀"); publish(); } else { console.log("上传预览小程序🚀"); preview(); } })();