├── .eslintrc.js ├── .fatherrc.ts ├── .github └── workflows │ └── npmpublish.yml ├── .gitignore ├── README.md ├── bin └── minici.js ├── dist ├── index.d.ts ├── index.esm.js ├── index.js ├── template.d.ts └── utils.d.ts ├── package-lock.json ├── package.json ├── src ├── index.ts ├── template.ts └── utils.ts └── tsconfig.json /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@tools-list/eslint-config-self'], 3 | rules: { 4 | 'import/no-default-export': 0, 5 | 'no-useless-catch': 0, 6 | '@typescript-eslint/explicit-module-boundary-types': 0, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /.fatherrc.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | esm: 'rollup', 3 | cjs: 'rollup', 4 | target: 'node' 5 | }; 6 | -------------------------------------------------------------------------------- /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: Create Release CI 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | PUBLISH: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | fetch-depth: 0 15 | - run: git fetch --prune 16 | - name: Use Node.js 12 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: 12 20 | registry-url: https://registry.npmjs.org/ 21 | - run: npm i 22 | - run: npm run build 23 | - run: npm publish --access public 24 | env: 25 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mini-ci 2 | 基于微信提供的CI方法封装的更加方便、自动化构建的CI工具库。 3 | 4 | ### Installation 5 | 6 | Install `mini-ci` via yarn or npm. 7 | 8 | ```shell 9 | npm i @tools-list/mini-ci -g 10 | ``` 11 | 12 | ### Usage 13 | 14 | ```shell 15 | # 初始化配置文件 16 | $ mini init 17 | 18 | # 小程序上传 19 | $ mini upload 20 | 21 | # 小程序 预览 22 | $ mini preview 23 | 24 | # 小程序 最近上传版本的sourceMap 25 | $ mini getDevSourceMap 26 | 27 | # 小程序 上传云开发云函数 28 | $ mini uploadFunction 29 | 30 | # 小程序 上传云开发静态网站 31 | $ mini uploadStaticStorage 32 | 33 | # 小程序 上传云存储 34 | $ mini uploadStorage 35 | 36 | # 小程序 新建云开发云托管版本 37 | $ mini uploadContainer 38 | ``` 39 | 40 | ### mini.config.js 41 | 42 | ```js 43 | const path = require('path'); 44 | 45 | module.exports = { 46 | // 项目配置 47 | project: { 48 | appid: '小程序appid', 49 | type: 'miniProgram', 50 | projectPath: '小程序目录', 51 | privateKeyPath: '上传秘钥', 52 | }, 53 | // 小程序上传 54 | upload: { 55 | version: '1.1.1', 56 | desc: 'upload', 57 | setting: { 58 | es6: true, 59 | }, 60 | }, 61 | // 小程序预览 62 | preview: { 63 | version: '1.1.1', 64 | desc: 'preview', 65 | setting: { 66 | es6: true, 67 | }, 68 | qrcodeFormat: 'image', 69 | qrcodeOutputDest: `${path.join(__dirname)}/qrcode.jpg`, 70 | }, 71 | //最近上传版本的sourceMap 72 | sourceMapOption: { 73 | robot: 1, 74 | sourceMapSavePath: `${path.join(__dirname)}/sourceMap.zip`, 75 | }, 76 | // 上传云开发云函数 77 | uploadFunctionOptions: { 78 | env: '云环境 ID', 79 | name: '云函数名称', 80 | path: '云函数代码目录', 81 | remoteNpmInstall: true, 82 | }, 83 | // 上传云开发静态网站 84 | uploadStaticStorageOptions: { 85 | env: '云环境 ID', 86 | path: '本地文件目录', 87 | remotePath: '要上传到的远端文件目录', 88 | }, 89 | // 上传云存储 90 | uploadStorageOptions: { 91 | env: '云环境 ID', 92 | path: '本地文件目录', 93 | remotePath: '要上传到的远端文件目录', 94 | }, 95 | // 新建云开发云托管版本 96 | uploadContainer: { 97 | env: '云环境 ID', 98 | version: { 99 | uploadType: 'package', 100 | flowRatio: 0, 101 | cpu: 0.25, 102 | mem: 0.5, 103 | minNum: 0, 104 | maxNum: 1, 105 | policyType: 'cpu', 106 | policyThreshold: 60, 107 | containerPort: 80, 108 | serverName: 'server', 109 | versionRemark: 'ci', 110 | envParams: '{}', 111 | buildDir: '', 112 | dockerfilePath: '', 113 | }, 114 | containerRoot: 'the/path/to/container', 115 | }, 116 | }; 117 | ``` 118 | 119 | **参数与官方保持一致 https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html** 120 | 121 | -------------------------------------------------------------------------------- /bin/minici.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | function start() { 4 | require('../dist/index'); 5 | } 6 | 7 | start(); 8 | -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/index.esm.js: -------------------------------------------------------------------------------- 1 | import { cac } from 'cac'; 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | import ci from 'miniprogram-ci'; 5 | 6 | function ownKeys(object, enumerableOnly) { 7 | var keys = Object.keys(object); 8 | 9 | if (Object.getOwnPropertySymbols) { 10 | var symbols = Object.getOwnPropertySymbols(object); 11 | 12 | if (enumerableOnly) { 13 | symbols = symbols.filter(function (sym) { 14 | return Object.getOwnPropertyDescriptor(object, sym).enumerable; 15 | }); 16 | } 17 | 18 | keys.push.apply(keys, symbols); 19 | } 20 | 21 | return keys; 22 | } 23 | 24 | function _objectSpread2(target) { 25 | for (var i = 1; i < arguments.length; i++) { 26 | var source = arguments[i] != null ? arguments[i] : {}; 27 | 28 | if (i % 2) { 29 | ownKeys(Object(source), true).forEach(function (key) { 30 | _defineProperty(target, key, source[key]); 31 | }); 32 | } else if (Object.getOwnPropertyDescriptors) { 33 | Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); 34 | } else { 35 | ownKeys(Object(source)).forEach(function (key) { 36 | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); 37 | }); 38 | } 39 | } 40 | 41 | return target; 42 | } 43 | 44 | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { 45 | try { 46 | var info = gen[key](arg); 47 | var value = info.value; 48 | } catch (error) { 49 | reject(error); 50 | return; 51 | } 52 | 53 | if (info.done) { 54 | resolve(value); 55 | } else { 56 | Promise.resolve(value).then(_next, _throw); 57 | } 58 | } 59 | 60 | function _asyncToGenerator(fn) { 61 | return function () { 62 | var self = this, 63 | args = arguments; 64 | return new Promise(function (resolve, reject) { 65 | var gen = fn.apply(self, args); 66 | 67 | function _next(value) { 68 | asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); 69 | } 70 | 71 | function _throw(err) { 72 | asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); 73 | } 74 | 75 | _next(undefined); 76 | }); 77 | }; 78 | } 79 | 80 | function _defineProperty(obj, key, value) { 81 | if (key in obj) { 82 | Object.defineProperty(obj, key, { 83 | value: value, 84 | enumerable: true, 85 | configurable: true, 86 | writable: true 87 | }); 88 | } else { 89 | obj[key] = value; 90 | } 91 | 92 | return obj; 93 | } 94 | 95 | var getTemplate = function getTemplate() { 96 | return "const path = require('path');\n\nmodule.exports = {\n project: {\n appid: '\u5C0F\u7A0B\u5E8Fappid',\n type: 'miniProgram',\n projectPath: path.join(__dirname, './dist'),\n privateKeyPath: path.join(__dirname, './private.key'),\n },\n upload: {\n version: '1.1.1',\n desc: 'upload',\n setting: {\n es6: true,\n },\n },\n preview: {\n version: '1.1.1',\n desc: 'preview',\n setting: {\n es6: true,\n },\n qrcodeFormat: 'image',\n qrcodeOutputDest: `${path.join(__dirname)}/qrcode.jpg`,\n },\n sourceMapOption: {\n robot: 1,\n sourceMapSavePath: `${path.join(__dirname)}/sourceMap.zip`,\n },\n uploadFunctionOptions: {\n env: '\u4E91\u73AF\u5883 ID',\n name: '\u4E91\u51FD\u6570\u540D\u79F0',\n path: '\u4E91\u51FD\u6570\u4EE3\u7801\u76EE\u5F55',\n remoteNpmInstall: true,\n },\n uploadStaticStorageOptions: {\n env: '\u4E91\u73AF\u5883 ID',\n path: '\u672C\u5730\u6587\u4EF6\u76EE\u5F55',\n remotePath: '\u8981\u4E0A\u4F20\u5230\u7684\u8FDC\u7AEF\u6587\u4EF6\u76EE\u5F55',\n },\n uploadStorageOptions: {\n env: '\u4E91\u73AF\u5883 ID',\n path: '\u672C\u5730\u6587\u4EF6\u76EE\u5F55',\n remotePath: '\u8981\u4E0A\u4F20\u5230\u7684\u8FDC\u7AEF\u6587\u4EF6\u76EE\u5F55',\n },\n uploadContainer: {\n env: '\u4E91\u73AF\u5883 ID',\n version: {\n uploadType: 'package',\n flowRatio: 0,\n cpu: 0.25,\n mem: 0.5,\n minNum: 0,\n maxNum: 1,\n policyType: 'cpu',\n policyThreshold: 60,\n containerPort: 80,\n serverName: 'server',\n versionRemark: 'ci',\n envParams: '{}',\n buildDir: '',\n dockerfilePath: '',\n },\n containerRoot: 'the/path/to/container',\n },\n};\n"; 97 | }; 98 | 99 | /** 100 | * 获取工程目录的配置文件 101 | * @param {string} root 102 | * @returns UserConfig 103 | */ 104 | 105 | var getConfig = function getConfig(root) { 106 | var resolvedPath = path.join(root || process.cwd(), 'mini.config.js'); 107 | 108 | try { 109 | var userConfig; 110 | 111 | if (fs.existsSync(resolvedPath)) { 112 | delete require.cache[require.resolve(resolvedPath)]; 113 | userConfig = require(resolvedPath); 114 | 115 | if (!('project' in userConfig)) { 116 | console.log('project config is no exit'); 117 | throw 'project config is no exit'; 118 | } 119 | 120 | return userConfig; 121 | } else { 122 | throw "".concat(resolvedPath, " is no exit"); 123 | } 124 | } catch (e) { 125 | console.log("failed to load config from ".concat(resolvedPath)); 126 | throw e; 127 | } 128 | }; 129 | /** 130 | * 生成 mini.config.js 131 | * @param {string} root 132 | */ 133 | 134 | var createTemplate = function createTemplate(root) { 135 | var resolvedPath = path.join(root || process.cwd(), 'mini.config.js'); 136 | 137 | if (fs.existsSync(resolvedPath)) { 138 | console.log("\n[".concat(resolvedPath, "] \u5DF2\u751F\u6210!\n")); 139 | } else { 140 | fs.writeFile(resolvedPath, getTemplate(), function (err) { 141 | if (err) throw err; 142 | console.log("\n[".concat(resolvedPath, "] \u5DF2\u751F\u6210!\n")); 143 | }); 144 | } 145 | }; 146 | /** 147 | * 上传小程序 148 | * @param {ICreateProjectOptions} projectConfig 149 | * @param {UploadInfo} uploadInfo 150 | */ 151 | 152 | var uploadProject = /*#__PURE__*/function () { 153 | var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(projectConfig, uploadInfo) { 154 | return regeneratorRuntime.wrap(function _callee$(_context) { 155 | while (1) { 156 | switch (_context.prev = _context.next) { 157 | case 0: 158 | _context.prev = 0; 159 | _context.next = 3; 160 | return ci.upload(_objectSpread2({ 161 | project: new ci.Project(projectConfig) 162 | }, uploadInfo)); 163 | 164 | case 3: 165 | console.log('已更新至微信小程序助手~'); 166 | _context.next = 9; 167 | break; 168 | 169 | case 6: 170 | _context.prev = 6; 171 | _context.t0 = _context["catch"](0); 172 | console.log(JSON.stringify(_context.t0)); 173 | 174 | case 9: 175 | case "end": 176 | return _context.stop(); 177 | } 178 | } 179 | }, _callee, null, [[0, 6]]); 180 | })); 181 | 182 | return function uploadProject(_x, _x2) { 183 | return _ref.apply(this, arguments); 184 | }; 185 | }(); 186 | /** 187 | * 预览小程序 188 | * @param {ICreateProjectOptions} projectConfig 189 | * @param {PreviewInfo} previewInfo 190 | */ 191 | 192 | var previewProject = /*#__PURE__*/function () { 193 | var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(projectConfig, previewInfo) { 194 | return regeneratorRuntime.wrap(function _callee2$(_context2) { 195 | while (1) { 196 | switch (_context2.prev = _context2.next) { 197 | case 0: 198 | _context2.prev = 0; 199 | _context2.next = 3; 200 | return ci.preview(_objectSpread2({ 201 | project: new ci.Project(projectConfig) 202 | }, previewInfo)); 203 | 204 | case 3: 205 | console.log('已更新至微信小程序助手~'); 206 | _context2.next = 9; 207 | break; 208 | 209 | case 6: 210 | _context2.prev = 6; 211 | _context2.t0 = _context2["catch"](0); 212 | console.log('error', JSON.stringify(_context2.t0)); 213 | 214 | case 9: 215 | case "end": 216 | return _context2.stop(); 217 | } 218 | } 219 | }, _callee2, null, [[0, 6]]); 220 | })); 221 | 222 | return function previewProject(_x3, _x4) { 223 | return _ref2.apply(this, arguments); 224 | }; 225 | }(); 226 | /** 227 | * 最近上传版本的sourceMap 228 | * @param {ICreateProjectOptions} projectConfig 229 | * @param {GetDevSourceMapOption} sourceMapOption 230 | */ 231 | 232 | var getDevSourceMap = /*#__PURE__*/function () { 233 | var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(projectConfig, sourceMapOption) { 234 | return regeneratorRuntime.wrap(function _callee3$(_context3) { 235 | while (1) { 236 | switch (_context3.prev = _context3.next) { 237 | case 0: 238 | _context3.prev = 0; 239 | _context3.next = 3; 240 | return ci.getDevSourceMap(_objectSpread2({ 241 | project: new ci.Project(projectConfig) 242 | }, sourceMapOption)); 243 | 244 | case 3: 245 | console.log('getDevSourceMap 执行完~'); 246 | _context3.next = 9; 247 | break; 248 | 249 | case 6: 250 | _context3.prev = 6; 251 | _context3.t0 = _context3["catch"](0); 252 | console.log('error', JSON.stringify(_context3.t0)); 253 | 254 | case 9: 255 | case "end": 256 | return _context3.stop(); 257 | } 258 | } 259 | }, _callee3, null, [[0, 6]]); 260 | })); 261 | 262 | return function getDevSourceMap(_x5, _x6) { 263 | return _ref3.apply(this, arguments); 264 | }; 265 | }(); 266 | /** 267 | * 上传云开发云函数 268 | * @param {ICreateProjectOptions} projectConfig 269 | * @param {UploadFunctionOptions} uploadFunctionOptions 270 | */ 271 | 272 | var uploadFunction = /*#__PURE__*/function () { 273 | var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(projectConfig, uploadFunctionOptions) { 274 | return regeneratorRuntime.wrap(function _callee4$(_context4) { 275 | while (1) { 276 | switch (_context4.prev = _context4.next) { 277 | case 0: 278 | _context4.prev = 0; 279 | _context4.next = 3; 280 | return ci.cloud.uploadFunction(_objectSpread2({ 281 | project: new ci.Project(projectConfig) 282 | }, uploadFunctionOptions)); 283 | 284 | case 3: 285 | console.log('getDevSourceMap 执行完~'); 286 | _context4.next = 9; 287 | break; 288 | 289 | case 6: 290 | _context4.prev = 6; 291 | _context4.t0 = _context4["catch"](0); 292 | console.log('error', JSON.stringify(_context4.t0)); 293 | 294 | case 9: 295 | case "end": 296 | return _context4.stop(); 297 | } 298 | } 299 | }, _callee4, null, [[0, 6]]); 300 | })); 301 | 302 | return function uploadFunction(_x7, _x8) { 303 | return _ref4.apply(this, arguments); 304 | }; 305 | }(); 306 | /** 307 | * 上传云开发静态网站 308 | * @param {ICreateProjectOptions} projectConfig 309 | * @param {UploadStaticStorageOptions} uploadStaticStorageOptions 310 | */ 311 | 312 | var uploadStaticStorage = /*#__PURE__*/function () { 313 | var _ref5 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(projectConfig, uploadStaticStorageOptions) { 314 | return regeneratorRuntime.wrap(function _callee5$(_context5) { 315 | while (1) { 316 | switch (_context5.prev = _context5.next) { 317 | case 0: 318 | _context5.prev = 0; 319 | _context5.next = 3; 320 | return ci.cloud.uploadStaticStorage(_objectSpread2({ 321 | project: new ci.Project(projectConfig) 322 | }, uploadStaticStorageOptions)); 323 | 324 | case 3: 325 | console.log('uploadStaticStorage 执行完~'); 326 | _context5.next = 9; 327 | break; 328 | 329 | case 6: 330 | _context5.prev = 6; 331 | _context5.t0 = _context5["catch"](0); 332 | console.log('error', JSON.stringify(_context5.t0)); 333 | 334 | case 9: 335 | case "end": 336 | return _context5.stop(); 337 | } 338 | } 339 | }, _callee5, null, [[0, 6]]); 340 | })); 341 | 342 | return function uploadStaticStorage(_x9, _x10) { 343 | return _ref5.apply(this, arguments); 344 | }; 345 | }(); 346 | /** 347 | * 新建云开发云托管版本 348 | * @param {ICreateProjectOptions} projectConfig 349 | * @param {any} uploadContainer 350 | */ 351 | 352 | var uploadContainer = /*#__PURE__*/function () { 353 | var _ref7 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(projectConfig, _uploadContainer) { 354 | return regeneratorRuntime.wrap(function _callee7$(_context7) { 355 | while (1) { 356 | switch (_context7.prev = _context7.next) { 357 | case 0: 358 | _context7.prev = 0; 359 | _context7.next = 3; 360 | return ci.cloud.uploadContainer(_objectSpread2({ 361 | project: new ci.Project(projectConfig) 362 | }, _uploadContainer)); 363 | 364 | case 3: 365 | console.log('uploadContainer 执行完~'); 366 | _context7.next = 9; 367 | break; 368 | 369 | case 6: 370 | _context7.prev = 6; 371 | _context7.t0 = _context7["catch"](0); 372 | console.log('error', JSON.stringify(_context7.t0)); 373 | 374 | case 9: 375 | case "end": 376 | return _context7.stop(); 377 | } 378 | } 379 | }, _callee7, null, [[0, 6]]); 380 | })); 381 | 382 | return function uploadContainer(_x13, _x14) { 383 | return _ref7.apply(this, arguments); 384 | }; 385 | }(); 386 | 387 | var cli = cac('mini'); 388 | cli.option('init', '初始化默认的配置文件').option('upload', '小程序上传').option('preview', '小程序预览').option('getDevSourceMap', '最近上传版本的sourceMap').option('uploadFunction', '上传云开发云函数').option('uploadStaticStorage', '上传云开发静态网站').option('uploadStorageOptions', '上传云存储').option('uploadContainer', '新建云开发云托管版本'); // 上传 389 | 390 | cli.command('[root]').alias('init').action( /*#__PURE__*/function () { 391 | var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(root) { 392 | return regeneratorRuntime.wrap(function _callee$(_context) { 393 | while (1) { 394 | switch (_context.prev = _context.next) { 395 | case 0: 396 | createTemplate(root); 397 | 398 | case 1: 399 | case "end": 400 | return _context.stop(); 401 | } 402 | } 403 | }, _callee); 404 | })); 405 | 406 | return function (_x) { 407 | return _ref.apply(this, arguments); 408 | }; 409 | }()); // 上传 410 | 411 | cli.command('[root]').alias('upload').action( /*#__PURE__*/function () { 412 | var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(root) { 413 | var config; 414 | return regeneratorRuntime.wrap(function _callee2$(_context2) { 415 | while (1) { 416 | switch (_context2.prev = _context2.next) { 417 | case 0: 418 | config = getConfig(root); 419 | 420 | if (!config.upload) { 421 | _context2.next = 6; 422 | break; 423 | } 424 | 425 | _context2.next = 4; 426 | return uploadProject(config.project, config.upload); 427 | 428 | case 4: 429 | _context2.next = 7; 430 | break; 431 | 432 | case 6: 433 | console.log('upload字段缺少配置信息'); 434 | 435 | case 7: 436 | case "end": 437 | return _context2.stop(); 438 | } 439 | } 440 | }, _callee2); 441 | })); 442 | 443 | return function (_x2) { 444 | return _ref2.apply(this, arguments); 445 | }; 446 | }()); // 预览 447 | 448 | cli.command('[root]').alias('preview').action( /*#__PURE__*/function () { 449 | var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(root) { 450 | var config; 451 | return regeneratorRuntime.wrap(function _callee3$(_context3) { 452 | while (1) { 453 | switch (_context3.prev = _context3.next) { 454 | case 0: 455 | config = getConfig(root); 456 | 457 | if (!config.preview) { 458 | _context3.next = 6; 459 | break; 460 | } 461 | 462 | _context3.next = 4; 463 | return previewProject(config.project, config.preview); 464 | 465 | case 4: 466 | _context3.next = 7; 467 | break; 468 | 469 | case 6: 470 | console.log('preview字段缺少配置信息'); 471 | 472 | case 7: 473 | case "end": 474 | return _context3.stop(); 475 | } 476 | } 477 | }, _callee3); 478 | })); 479 | 480 | return function (_x3) { 481 | return _ref3.apply(this, arguments); 482 | }; 483 | }()); // 最近上传版本的sourceMap 484 | 485 | cli.command('[root]').alias('getDevSourceMap').action( /*#__PURE__*/function () { 486 | var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(root) { 487 | var config; 488 | return regeneratorRuntime.wrap(function _callee4$(_context4) { 489 | while (1) { 490 | switch (_context4.prev = _context4.next) { 491 | case 0: 492 | config = getConfig(root); 493 | 494 | if (!config.sourceMapOption) { 495 | _context4.next = 6; 496 | break; 497 | } 498 | 499 | _context4.next = 4; 500 | return getDevSourceMap(config.project, config.sourceMapOption); 501 | 502 | case 4: 503 | _context4.next = 7; 504 | break; 505 | 506 | case 6: 507 | console.log('sourceMapOption字段缺少配置信息'); 508 | 509 | case 7: 510 | case "end": 511 | return _context4.stop(); 512 | } 513 | } 514 | }, _callee4); 515 | })); 516 | 517 | return function (_x4) { 518 | return _ref4.apply(this, arguments); 519 | }; 520 | }()); // 上传云开发云函数 521 | 522 | cli.command('[root]').alias('uploadFunction').action( /*#__PURE__*/function () { 523 | var _ref5 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(root) { 524 | var config; 525 | return regeneratorRuntime.wrap(function _callee5$(_context5) { 526 | while (1) { 527 | switch (_context5.prev = _context5.next) { 528 | case 0: 529 | config = getConfig(root); 530 | 531 | if (!config.uploadFunctionOptions) { 532 | _context5.next = 6; 533 | break; 534 | } 535 | 536 | _context5.next = 4; 537 | return uploadFunction(config.project, config.uploadFunctionOptions); 538 | 539 | case 4: 540 | _context5.next = 7; 541 | break; 542 | 543 | case 6: 544 | console.log('uploadFunction字段缺少配置信息'); 545 | 546 | case 7: 547 | case "end": 548 | return _context5.stop(); 549 | } 550 | } 551 | }, _callee5); 552 | })); 553 | 554 | return function (_x5) { 555 | return _ref5.apply(this, arguments); 556 | }; 557 | }()); // 上传云开发静态网站 558 | 559 | cli.command('[root]').alias('uploadStaticStorage').action( /*#__PURE__*/function () { 560 | var _ref6 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6(root) { 561 | var config; 562 | return regeneratorRuntime.wrap(function _callee6$(_context6) { 563 | while (1) { 564 | switch (_context6.prev = _context6.next) { 565 | case 0: 566 | config = getConfig(root); 567 | 568 | if (!config.uploadStaticStorageOptions) { 569 | _context6.next = 6; 570 | break; 571 | } 572 | 573 | _context6.next = 4; 574 | return uploadStaticStorage(config.project, config.uploadStaticStorageOptions); 575 | 576 | case 4: 577 | _context6.next = 7; 578 | break; 579 | 580 | case 6: 581 | console.log('uploadStaticStorage字段缺少配置信息'); 582 | 583 | case 7: 584 | case "end": 585 | return _context6.stop(); 586 | } 587 | } 588 | }, _callee6); 589 | })); 590 | 591 | return function (_x6) { 592 | return _ref6.apply(this, arguments); 593 | }; 594 | }()); // 上传云存储 595 | 596 | cli.command('[root]').alias('uploadStorageOptions').action( /*#__PURE__*/function () { 597 | var _ref7 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(root) { 598 | var config; 599 | return regeneratorRuntime.wrap(function _callee7$(_context7) { 600 | while (1) { 601 | switch (_context7.prev = _context7.next) { 602 | case 0: 603 | config = getConfig(root); 604 | 605 | if (!config.uploadStorageOptions) { 606 | _context7.next = 6; 607 | break; 608 | } 609 | 610 | _context7.next = 4; 611 | return uploadStaticStorage(config.project, config.uploadStorageOptions); 612 | 613 | case 4: 614 | _context7.next = 7; 615 | break; 616 | 617 | case 6: 618 | console.log('uploadStorageOptions字段缺少配置信息'); 619 | 620 | case 7: 621 | case "end": 622 | return _context7.stop(); 623 | } 624 | } 625 | }, _callee7); 626 | })); 627 | 628 | return function (_x7) { 629 | return _ref7.apply(this, arguments); 630 | }; 631 | }()); // 新建云开发云托管版本 632 | 633 | cli.command('[root]').alias('uploadContainer').action( /*#__PURE__*/function () { 634 | var _ref8 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(root) { 635 | var config; 636 | return regeneratorRuntime.wrap(function _callee8$(_context8) { 637 | while (1) { 638 | switch (_context8.prev = _context8.next) { 639 | case 0: 640 | config = getConfig(root); 641 | 642 | if (!config.uploadContainer) { 643 | _context8.next = 6; 644 | break; 645 | } 646 | 647 | _context8.next = 4; 648 | return uploadContainer(config.project, config.uploadContainer); 649 | 650 | case 4: 651 | _context8.next = 7; 652 | break; 653 | 654 | case 6: 655 | console.log('uploadContainer字段缺少配置信息'); 656 | 657 | case 7: 658 | case "end": 659 | return _context8.stop(); 660 | } 661 | } 662 | }, _callee8); 663 | })); 664 | 665 | return function (_x8) { 666 | return _ref8.apply(this, arguments); 667 | }; 668 | }()); 669 | cli.help(); 670 | cli.version(require('../package.json').version); 671 | cli.parse(); 672 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var cac = require('cac'); 4 | var fs = require('fs'); 5 | var path = require('path'); 6 | var ci = require('miniprogram-ci'); 7 | 8 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } 9 | 10 | var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); 11 | var path__default = /*#__PURE__*/_interopDefaultLegacy(path); 12 | var ci__default = /*#__PURE__*/_interopDefaultLegacy(ci); 13 | 14 | function ownKeys(object, enumerableOnly) { 15 | var keys = Object.keys(object); 16 | 17 | if (Object.getOwnPropertySymbols) { 18 | var symbols = Object.getOwnPropertySymbols(object); 19 | 20 | if (enumerableOnly) { 21 | symbols = symbols.filter(function (sym) { 22 | return Object.getOwnPropertyDescriptor(object, sym).enumerable; 23 | }); 24 | } 25 | 26 | keys.push.apply(keys, symbols); 27 | } 28 | 29 | return keys; 30 | } 31 | 32 | function _objectSpread2(target) { 33 | for (var i = 1; i < arguments.length; i++) { 34 | var source = arguments[i] != null ? arguments[i] : {}; 35 | 36 | if (i % 2) { 37 | ownKeys(Object(source), true).forEach(function (key) { 38 | _defineProperty(target, key, source[key]); 39 | }); 40 | } else if (Object.getOwnPropertyDescriptors) { 41 | Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); 42 | } else { 43 | ownKeys(Object(source)).forEach(function (key) { 44 | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); 45 | }); 46 | } 47 | } 48 | 49 | return target; 50 | } 51 | 52 | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { 53 | try { 54 | var info = gen[key](arg); 55 | var value = info.value; 56 | } catch (error) { 57 | reject(error); 58 | return; 59 | } 60 | 61 | if (info.done) { 62 | resolve(value); 63 | } else { 64 | Promise.resolve(value).then(_next, _throw); 65 | } 66 | } 67 | 68 | function _asyncToGenerator(fn) { 69 | return function () { 70 | var self = this, 71 | args = arguments; 72 | return new Promise(function (resolve, reject) { 73 | var gen = fn.apply(self, args); 74 | 75 | function _next(value) { 76 | asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); 77 | } 78 | 79 | function _throw(err) { 80 | asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); 81 | } 82 | 83 | _next(undefined); 84 | }); 85 | }; 86 | } 87 | 88 | function _defineProperty(obj, key, value) { 89 | if (key in obj) { 90 | Object.defineProperty(obj, key, { 91 | value: value, 92 | enumerable: true, 93 | configurable: true, 94 | writable: true 95 | }); 96 | } else { 97 | obj[key] = value; 98 | } 99 | 100 | return obj; 101 | } 102 | 103 | const getTemplate = () => `const path = require('path'); 104 | 105 | module.exports = { 106 | project: { 107 | appid: '小程序appid', 108 | type: 'miniProgram', 109 | projectPath: path.join(__dirname, './dist'), 110 | privateKeyPath: path.join(__dirname, './private.key'), 111 | }, 112 | upload: { 113 | version: '1.1.1', 114 | desc: 'upload', 115 | setting: { 116 | es6: true, 117 | }, 118 | }, 119 | preview: { 120 | version: '1.1.1', 121 | desc: 'preview', 122 | setting: { 123 | es6: true, 124 | }, 125 | qrcodeFormat: 'image', 126 | qrcodeOutputDest: \`\${path.join(__dirname)}/qrcode.jpg\`, 127 | }, 128 | sourceMapOption: { 129 | robot: 1, 130 | sourceMapSavePath: \`\${path.join(__dirname)}/sourceMap.zip\`, 131 | }, 132 | uploadFunctionOptions: { 133 | env: '云环境 ID', 134 | name: '云函数名称', 135 | path: '云函数代码目录', 136 | remoteNpmInstall: true, 137 | }, 138 | uploadStaticStorageOptions: { 139 | env: '云环境 ID', 140 | path: '本地文件目录', 141 | remotePath: '要上传到的远端文件目录', 142 | }, 143 | uploadStorageOptions: { 144 | env: '云环境 ID', 145 | path: '本地文件目录', 146 | remotePath: '要上传到的远端文件目录', 147 | }, 148 | uploadContainer: { 149 | env: '云环境 ID', 150 | version: { 151 | uploadType: 'package', 152 | flowRatio: 0, 153 | cpu: 0.25, 154 | mem: 0.5, 155 | minNum: 0, 156 | maxNum: 1, 157 | policyType: 'cpu', 158 | policyThreshold: 60, 159 | containerPort: 80, 160 | serverName: 'server', 161 | versionRemark: 'ci', 162 | envParams: '{}', 163 | buildDir: '', 164 | dockerfilePath: '', 165 | }, 166 | containerRoot: 'the/path/to/container', 167 | }, 168 | }; 169 | `; 170 | 171 | /** 172 | * 获取工程目录的配置文件 173 | * @param {string} root 174 | * @returns UserConfig 175 | */ 176 | 177 | const getConfig = root => { 178 | const resolvedPath = path__default['default'].join(root || process.cwd(), 'mini.config.js'); 179 | 180 | try { 181 | let userConfig; 182 | 183 | if (fs__default['default'].existsSync(resolvedPath)) { 184 | delete require.cache[require.resolve(resolvedPath)]; 185 | userConfig = require(resolvedPath); 186 | 187 | if (!('project' in userConfig)) { 188 | console.log('project config is no exit'); 189 | throw 'project config is no exit'; 190 | } 191 | 192 | return userConfig; 193 | } else { 194 | throw `${resolvedPath} is no exit`; 195 | } 196 | } catch (e) { 197 | console.log(`failed to load config from ${resolvedPath}`); 198 | throw e; 199 | } 200 | }; 201 | /** 202 | * 生成 mini.config.js 203 | * @param {string} root 204 | */ 205 | 206 | const createTemplate = root => { 207 | const resolvedPath = path__default['default'].join(root || process.cwd(), 'mini.config.js'); 208 | 209 | if (fs__default['default'].existsSync(resolvedPath)) { 210 | console.log(`\n[${resolvedPath}] 已生成!\n`); 211 | } else { 212 | fs__default['default'].writeFile(resolvedPath, getTemplate(), err => { 213 | if (err) throw err; 214 | console.log(`\n[${resolvedPath}] 已生成!\n`); 215 | }); 216 | } 217 | }; 218 | /** 219 | * 上传小程序 220 | * @param {ICreateProjectOptions} projectConfig 221 | * @param {UploadInfo} uploadInfo 222 | */ 223 | 224 | const uploadProject = /*#__PURE__*/function () { 225 | var _ref = _asyncToGenerator(function* (projectConfig, uploadInfo) { 226 | try { 227 | yield ci__default['default'].upload(_objectSpread2({ 228 | project: new ci__default['default'].Project(projectConfig) 229 | }, uploadInfo)); 230 | console.log('已更新至微信小程序助手~'); 231 | } catch (error) { 232 | console.log(JSON.stringify(error)); 233 | } 234 | }); 235 | 236 | return function uploadProject(_x, _x2) { 237 | return _ref.apply(this, arguments); 238 | }; 239 | }(); 240 | /** 241 | * 预览小程序 242 | * @param {ICreateProjectOptions} projectConfig 243 | * @param {PreviewInfo} previewInfo 244 | */ 245 | 246 | const previewProject = /*#__PURE__*/function () { 247 | var _ref2 = _asyncToGenerator(function* (projectConfig, previewInfo) { 248 | try { 249 | yield ci__default['default'].preview(_objectSpread2({ 250 | project: new ci__default['default'].Project(projectConfig) 251 | }, previewInfo)); 252 | console.log('已更新至微信小程序助手~'); 253 | } catch (error) { 254 | console.log('error', JSON.stringify(error)); 255 | } 256 | }); 257 | 258 | return function previewProject(_x3, _x4) { 259 | return _ref2.apply(this, arguments); 260 | }; 261 | }(); 262 | /** 263 | * 最近上传版本的sourceMap 264 | * @param {ICreateProjectOptions} projectConfig 265 | * @param {GetDevSourceMapOption} sourceMapOption 266 | */ 267 | 268 | const getDevSourceMap = /*#__PURE__*/function () { 269 | var _ref3 = _asyncToGenerator(function* (projectConfig, sourceMapOption) { 270 | try { 271 | yield ci__default['default'].getDevSourceMap(_objectSpread2({ 272 | project: new ci__default['default'].Project(projectConfig) 273 | }, sourceMapOption)); 274 | console.log('getDevSourceMap 执行完~'); 275 | } catch (error) { 276 | console.log('error', JSON.stringify(error)); 277 | } 278 | }); 279 | 280 | return function getDevSourceMap(_x5, _x6) { 281 | return _ref3.apply(this, arguments); 282 | }; 283 | }(); 284 | /** 285 | * 上传云开发云函数 286 | * @param {ICreateProjectOptions} projectConfig 287 | * @param {UploadFunctionOptions} uploadFunctionOptions 288 | */ 289 | 290 | const uploadFunction = /*#__PURE__*/function () { 291 | var _ref4 = _asyncToGenerator(function* (projectConfig, uploadFunctionOptions) { 292 | try { 293 | yield ci__default['default'].cloud.uploadFunction(_objectSpread2({ 294 | project: new ci__default['default'].Project(projectConfig) 295 | }, uploadFunctionOptions)); 296 | console.log('getDevSourceMap 执行完~'); 297 | } catch (error) { 298 | console.log('error', JSON.stringify(error)); 299 | } 300 | }); 301 | 302 | return function uploadFunction(_x7, _x8) { 303 | return _ref4.apply(this, arguments); 304 | }; 305 | }(); 306 | /** 307 | * 上传云开发静态网站 308 | * @param {ICreateProjectOptions} projectConfig 309 | * @param {UploadStaticStorageOptions} uploadStaticStorageOptions 310 | */ 311 | 312 | const uploadStaticStorage = /*#__PURE__*/function () { 313 | var _ref5 = _asyncToGenerator(function* (projectConfig, uploadStaticStorageOptions) { 314 | try { 315 | yield ci__default['default'].cloud.uploadStaticStorage(_objectSpread2({ 316 | project: new ci__default['default'].Project(projectConfig) 317 | }, uploadStaticStorageOptions)); 318 | console.log('uploadStaticStorage 执行完~'); 319 | } catch (error) { 320 | console.log('error', JSON.stringify(error)); 321 | } 322 | }); 323 | 324 | return function uploadStaticStorage(_x9, _x10) { 325 | return _ref5.apply(this, arguments); 326 | }; 327 | }(); 328 | /** 329 | * 新建云开发云托管版本 330 | * @param {ICreateProjectOptions} projectConfig 331 | * @param {any} uploadContainer 332 | */ 333 | 334 | const uploadContainer = /*#__PURE__*/function () { 335 | var _ref7 = _asyncToGenerator(function* (projectConfig, _uploadContainer) { 336 | try { 337 | yield ci__default['default'].cloud.uploadContainer(_objectSpread2({ 338 | project: new ci__default['default'].Project(projectConfig) 339 | }, _uploadContainer)); 340 | console.log('uploadContainer 执行完~'); 341 | } catch (error) { 342 | console.log('error', JSON.stringify(error)); 343 | } 344 | }); 345 | 346 | return function uploadContainer(_x13, _x14) { 347 | return _ref7.apply(this, arguments); 348 | }; 349 | }(); 350 | 351 | const cli = cac.cac('mini'); 352 | cli.option('init', '初始化默认的配置文件').option('upload', '小程序上传').option('preview', '小程序预览').option('getDevSourceMap', '最近上传版本的sourceMap').option('uploadFunction', '上传云开发云函数').option('uploadStaticStorage', '上传云开发静态网站').option('uploadStorageOptions', '上传云存储').option('uploadContainer', '新建云开发云托管版本'); // 上传 353 | 354 | cli.command('[root]').alias('init').action( /*#__PURE__*/function () { 355 | var _ref = _asyncToGenerator(function* (root) { 356 | createTemplate(root); 357 | }); 358 | 359 | return function (_x) { 360 | return _ref.apply(this, arguments); 361 | }; 362 | }()); // 上传 363 | 364 | cli.command('[root]').alias('upload').action( /*#__PURE__*/function () { 365 | var _ref2 = _asyncToGenerator(function* (root) { 366 | const config = getConfig(root); 367 | 368 | if (config.upload) { 369 | yield uploadProject(config.project, config.upload); 370 | } else { 371 | console.log('upload字段缺少配置信息'); 372 | } 373 | }); 374 | 375 | return function (_x2) { 376 | return _ref2.apply(this, arguments); 377 | }; 378 | }()); // 预览 379 | 380 | cli.command('[root]').alias('preview').action( /*#__PURE__*/function () { 381 | var _ref3 = _asyncToGenerator(function* (root) { 382 | const config = getConfig(root); 383 | 384 | if (config.preview) { 385 | yield previewProject(config.project, config.preview); 386 | } else { 387 | console.log('preview字段缺少配置信息'); 388 | } 389 | }); 390 | 391 | return function (_x3) { 392 | return _ref3.apply(this, arguments); 393 | }; 394 | }()); // 最近上传版本的sourceMap 395 | 396 | cli.command('[root]').alias('getDevSourceMap').action( /*#__PURE__*/function () { 397 | var _ref4 = _asyncToGenerator(function* (root) { 398 | const config = getConfig(root); 399 | 400 | if (config.sourceMapOption) { 401 | yield getDevSourceMap(config.project, config.sourceMapOption); 402 | } else { 403 | console.log('sourceMapOption字段缺少配置信息'); 404 | } 405 | }); 406 | 407 | return function (_x4) { 408 | return _ref4.apply(this, arguments); 409 | }; 410 | }()); // 上传云开发云函数 411 | 412 | cli.command('[root]').alias('uploadFunction').action( /*#__PURE__*/function () { 413 | var _ref5 = _asyncToGenerator(function* (root) { 414 | const config = getConfig(root); 415 | 416 | if (config.uploadFunctionOptions) { 417 | yield uploadFunction(config.project, config.uploadFunctionOptions); 418 | } else { 419 | console.log('uploadFunction字段缺少配置信息'); 420 | } 421 | }); 422 | 423 | return function (_x5) { 424 | return _ref5.apply(this, arguments); 425 | }; 426 | }()); // 上传云开发静态网站 427 | 428 | cli.command('[root]').alias('uploadStaticStorage').action( /*#__PURE__*/function () { 429 | var _ref6 = _asyncToGenerator(function* (root) { 430 | const config = getConfig(root); 431 | 432 | if (config.uploadStaticStorageOptions) { 433 | yield uploadStaticStorage(config.project, config.uploadStaticStorageOptions); 434 | } else { 435 | console.log('uploadStaticStorage字段缺少配置信息'); 436 | } 437 | }); 438 | 439 | return function (_x6) { 440 | return _ref6.apply(this, arguments); 441 | }; 442 | }()); // 上传云存储 443 | 444 | cli.command('[root]').alias('uploadStorageOptions').action( /*#__PURE__*/function () { 445 | var _ref7 = _asyncToGenerator(function* (root) { 446 | const config = getConfig(root); 447 | 448 | if (config.uploadStorageOptions) { 449 | yield uploadStaticStorage(config.project, config.uploadStorageOptions); 450 | } else { 451 | console.log('uploadStorageOptions字段缺少配置信息'); 452 | } 453 | }); 454 | 455 | return function (_x7) { 456 | return _ref7.apply(this, arguments); 457 | }; 458 | }()); // 新建云开发云托管版本 459 | 460 | cli.command('[root]').alias('uploadContainer').action( /*#__PURE__*/function () { 461 | var _ref8 = _asyncToGenerator(function* (root) { 462 | const config = getConfig(root); 463 | 464 | if (config.uploadContainer) { 465 | yield uploadContainer(config.project, config.uploadContainer); 466 | } else { 467 | console.log('uploadContainer字段缺少配置信息'); 468 | } 469 | }); 470 | 471 | return function (_x8) { 472 | return _ref8.apply(this, arguments); 473 | }; 474 | }()); 475 | cli.help(); 476 | cli.version(require('../package.json').version); 477 | cli.parse(); 478 | -------------------------------------------------------------------------------- /dist/template.d.ts: -------------------------------------------------------------------------------- 1 | declare const getTemplate: () => string; 2 | export default getTemplate; 3 | -------------------------------------------------------------------------------- /dist/utils.d.ts: -------------------------------------------------------------------------------- 1 | import { IInnerUploadOptions } from 'miniprogram-ci/dist/@types/ci/upload'; 2 | import { ICreateProjectOptions } from 'miniprogram-ci/dist/@types/ci/project'; 3 | import { IGetDevSourceMapOption } from 'miniprogram-ci/dist/@types/ci/getDevSourceMap'; 4 | import { IUploadOptions } from 'miniprogram-ci/dist/@types'; 5 | export type { ICreateProjectOptions } from 'miniprogram-ci/dist/@types/ci/project'; 6 | export declare type UploadInfo = Omit; 7 | export declare type GetDevSourceMapOption = Omit; 8 | export declare type PreviewInfo = Omit; 9 | export declare type UploadStaticStorageOptions = Omit; 10 | /** 云开发上传配置 */ 11 | export interface UploadFunctionOptions { 12 | /** 云环境 ID */ 13 | env: string; 14 | /** 云函数名称 */ 15 | name: string; 16 | /** 云函数代码目录 */ 17 | path: string; 18 | /** 是否云端安装依赖 */ 19 | remoteNpmInstall: boolean; 20 | } 21 | /** 用户配置文件 */ 22 | export interface UserConfig { 23 | /** 项目相关配置 */ 24 | project: ICreateProjectOptions; 25 | /** 上传相关配置 */ 26 | upload?: UploadInfo; 27 | /** 预览相关配置 */ 28 | preview?: PreviewInfo; 29 | /** 最近上传版本的sourceMap配置 */ 30 | sourceMapOption?: GetDevSourceMapOption; 31 | /** 云开发上传配置 */ 32 | uploadFunctionOptions?: UploadFunctionOptions; 33 | /** 上传云开发静态网站配置 */ 34 | uploadStaticStorageOptions: UploadStaticStorageOptions; 35 | /** 上传云存储配置 */ 36 | uploadStorageOptions: UploadStaticStorageOptions; 37 | /** 新建云开发云托管版本配置 */ 38 | uploadContainer: any; 39 | } 40 | /** 41 | * 获取工程目录的配置文件 42 | * @param {string} root 43 | * @returns UserConfig 44 | */ 45 | export declare const getConfig: (root: string) => UserConfig; 46 | /** 47 | * 生成 mini.config.js 48 | * @param {string} root 49 | */ 50 | export declare const createTemplate: (root: string) => void; 51 | /** 52 | * 上传小程序 53 | * @param {ICreateProjectOptions} projectConfig 54 | * @param {UploadInfo} uploadInfo 55 | */ 56 | export declare const uploadProject: (projectConfig: ICreateProjectOptions, uploadInfo: UploadInfo) => Promise; 57 | /** 58 | * 预览小程序 59 | * @param {ICreateProjectOptions} projectConfig 60 | * @param {PreviewInfo} previewInfo 61 | */ 62 | export declare const previewProject: (projectConfig: ICreateProjectOptions, previewInfo: PreviewInfo) => Promise; 63 | /** 64 | * 最近上传版本的sourceMap 65 | * @param {ICreateProjectOptions} projectConfig 66 | * @param {GetDevSourceMapOption} sourceMapOption 67 | */ 68 | export declare const getDevSourceMap: (projectConfig: ICreateProjectOptions, sourceMapOption: GetDevSourceMapOption) => Promise; 69 | /** 70 | * 上传云开发云函数 71 | * @param {ICreateProjectOptions} projectConfig 72 | * @param {UploadFunctionOptions} uploadFunctionOptions 73 | */ 74 | export declare const uploadFunction: (projectConfig: ICreateProjectOptions, uploadFunctionOptions: UploadFunctionOptions) => Promise; 75 | /** 76 | * 上传云开发静态网站 77 | * @param {ICreateProjectOptions} projectConfig 78 | * @param {UploadStaticStorageOptions} uploadStaticStorageOptions 79 | */ 80 | export declare const uploadStaticStorage: (projectConfig: ICreateProjectOptions, uploadStaticStorageOptions: UploadStaticStorageOptions) => Promise; 81 | /** 82 | * 上传云存储 83 | * @param {ICreateProjectOptions} projectConfig 84 | * @param {UploadStaticStorageOptions} uploadStorageOptions 85 | */ 86 | export declare const uploadStorage: (projectConfig: ICreateProjectOptions, uploadStorageOptions: UploadStaticStorageOptions) => Promise; 87 | /** 88 | * 新建云开发云托管版本 89 | * @param {ICreateProjectOptions} projectConfig 90 | * @param {any} uploadContainer 91 | */ 92 | export declare const uploadContainer: (projectConfig: ICreateProjectOptions, uploadContainer: any) => Promise; 93 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tools-list/mini-ci", 3 | "version": "0.1.0", 4 | "description": "小程序 CI脚手架工具", 5 | "bin": { 6 | "mini": "bin/minici.js" 7 | }, 8 | "scripts": { 9 | "build": "father-build", 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "devDependencies": { 13 | "@tools-list/eslint-config-self": "0.0.3", 14 | "@types/node": "^16.11.1", 15 | "father-build": "^1.20.1" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/luoguoxiong/mini-ci.git" 20 | }, 21 | "author": "", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/luoguoxiong/mini-ci/issues" 25 | }, 26 | "homepage": "https://github.com/luoguoxiong/mini-ci#readme", 27 | "dependencies": { 28 | "cac": "^6.7.11", 29 | "miniprogram-ci": "^1.3.13" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { cac } from 'cac'; 2 | import { uploadProject, previewProject, getConfig, getDevSourceMap, uploadFunction, uploadStaticStorage, uploadContainer, createTemplate } from './utils'; 3 | const cli = cac('mini'); 4 | 5 | cli 6 | .option('init', '初始化默认的配置文件') 7 | .option('upload', '小程序上传') 8 | .option('preview', '小程序预览') 9 | .option('getDevSourceMap', '最近上传版本的sourceMap') 10 | .option('uploadFunction', '上传云开发云函数') 11 | .option('uploadStaticStorage', '上传云开发静态网站') 12 | .option('uploadStorageOptions', '上传云存储') 13 | .option('uploadContainer', '新建云开发云托管版本'); 14 | 15 | // 初始化默认的配置文件 16 | cli.command('[root]') 17 | .alias('init') 18 | .action(async(root:string) => { 19 | createTemplate(root); 20 | }); 21 | 22 | // 上传 23 | cli.command('[root]') 24 | .alias('upload') 25 | .action(async(root:string) => { 26 | const config = getConfig(root); 27 | if(config.upload){ 28 | await uploadProject(config.project, config.upload); 29 | }else{ 30 | console.log('upload字段缺少配置信息'); 31 | } 32 | }); 33 | 34 | // 预览 35 | cli.command('[root]') 36 | .alias('preview') 37 | .action(async(root:string) => { 38 | const config = getConfig(root); 39 | if(config.preview){ 40 | await previewProject(config.project, config.preview); 41 | }else{ 42 | console.log('preview字段缺少配置信息'); 43 | } 44 | }); 45 | 46 | // 最近上传版本的sourceMap 47 | cli.command('[root]') 48 | .alias('getDevSourceMap') 49 | .action(async(root:string) => { 50 | const config = getConfig(root); 51 | if(config.sourceMapOption){ 52 | await getDevSourceMap(config.project, config.sourceMapOption); 53 | }else{ 54 | console.log('sourceMapOption字段缺少配置信息'); 55 | } 56 | }); 57 | 58 | // 上传云开发云函数 59 | cli.command('[root]') 60 | .alias('uploadFunction') 61 | .action(async(root:string) => { 62 | const config = getConfig(root); 63 | if(config.uploadFunctionOptions){ 64 | await uploadFunction(config.project, config.uploadFunctionOptions); 65 | }else{ 66 | console.log('uploadFunction字段缺少配置信息'); 67 | } 68 | }); 69 | 70 | // 上传云开发静态网站 71 | cli.command('[root]') 72 | .alias('uploadStaticStorage') 73 | .action(async(root:string) => { 74 | const config = getConfig(root); 75 | if(config.uploadStaticStorageOptions){ 76 | await uploadStaticStorage(config.project, config.uploadStaticStorageOptions); 77 | }else{ 78 | console.log('uploadStaticStorage字段缺少配置信息'); 79 | } 80 | }); 81 | 82 | // 上传云存储 83 | cli.command('[root]') 84 | .alias('uploadStorage') 85 | .action(async(root:string) => { 86 | const config = getConfig(root); 87 | if(config.uploadStorageOptions){ 88 | await uploadStaticStorage(config.project, config.uploadStorageOptions); 89 | }else{ 90 | console.log('uploadStorageOptions字段缺少配置信息'); 91 | } 92 | }); 93 | 94 | // 新建云开发云托管版本 95 | cli.command('[root]') 96 | .alias('uploadContainer') 97 | .action(async(root:string) => { 98 | const config = getConfig(root); 99 | if(config.uploadContainer){ 100 | await uploadContainer(config.project, config.uploadContainer); 101 | }else{ 102 | console.log('uploadContainer字段缺少配置信息'); 103 | } 104 | }); 105 | 106 | cli.help(); 107 | 108 | cli.version(require('../package.json').version); 109 | 110 | cli.parse(); 111 | -------------------------------------------------------------------------------- /src/template.ts: -------------------------------------------------------------------------------- 1 | const getTemplate = () => `const path = require('path'); 2 | 3 | module.exports = { 4 | project: { 5 | appid: '小程序appid', 6 | type: 'miniProgram', 7 | projectPath: path.join(__dirname, './dist'), 8 | privateKeyPath: path.join(__dirname, './private.key'), 9 | }, 10 | upload: { 11 | version: '1.1.1', 12 | desc: 'upload', 13 | setting: { 14 | es6: true, 15 | }, 16 | }, 17 | preview: { 18 | version: '1.1.1', 19 | desc: 'preview', 20 | setting: { 21 | es6: true, 22 | }, 23 | qrcodeFormat: 'image', 24 | qrcodeOutputDest: \`\${path.join(__dirname)}/qrcode.jpg\`, 25 | }, 26 | sourceMapOption: { 27 | robot: 1, 28 | sourceMapSavePath: \`\${path.join(__dirname)}/sourceMap.zip\`, 29 | }, 30 | uploadFunctionOptions: { 31 | env: '云环境 ID', 32 | name: '云函数名称', 33 | path: '云函数代码目录', 34 | remoteNpmInstall: true, 35 | }, 36 | uploadStaticStorageOptions: { 37 | env: '云环境 ID', 38 | path: '本地文件目录', 39 | remotePath: '要上传到的远端文件目录', 40 | }, 41 | uploadStorageOptions: { 42 | env: '云环境 ID', 43 | path: '本地文件目录', 44 | remotePath: '要上传到的远端文件目录', 45 | }, 46 | uploadContainer: { 47 | env: '云环境 ID', 48 | version: { 49 | uploadType: 'package', 50 | flowRatio: 0, 51 | cpu: 0.25, 52 | mem: 0.5, 53 | minNum: 0, 54 | maxNum: 1, 55 | policyType: 'cpu', 56 | policyThreshold: 60, 57 | containerPort: 80, 58 | serverName: 'server', 59 | versionRemark: 'ci', 60 | envParams: '{}', 61 | buildDir: '', 62 | dockerfilePath: '', 63 | }, 64 | containerRoot: 'the/path/to/container', 65 | }, 66 | }; 67 | `; 68 | export default getTemplate; 69 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import ci from 'miniprogram-ci'; 4 | import { IInnerUploadOptions } from 'miniprogram-ci/dist/@types/ci/upload'; 5 | import { ICreateProjectOptions } from 'miniprogram-ci/dist/@types/ci/project'; 6 | import { IGetDevSourceMapOption } from 'miniprogram-ci/dist/@types/ci/getDevSourceMap'; 7 | import { IUploadOptions } from 'miniprogram-ci/dist/@types'; 8 | import getTemplate from './template'; 9 | 10 | export type { ICreateProjectOptions } from 'miniprogram-ci/dist/@types/ci/project'; 11 | 12 | export type UploadInfo = Omit 13 | 14 | export type GetDevSourceMapOption = Omit 15 | 16 | export type PreviewInfo = Omit 17 | 18 | export type UploadStaticStorageOptions = Omit 19 | 20 | /** 云开发上传配置 */ 21 | export interface UploadFunctionOptions { 22 | /** 云环境 ID */ 23 | env:string; 24 | /** 云函数名称 */ 25 | name:string; 26 | /** 云函数代码目录 */ 27 | path:string; 28 | /** 是否云端安装依赖 */ 29 | remoteNpmInstall:boolean; 30 | } 31 | 32 | /** 用户配置文件 */ 33 | export interface UserConfig { 34 | /** 项目相关配置 */ 35 | project:ICreateProjectOptions; 36 | /** 上传相关配置 */ 37 | upload?:UploadInfo; 38 | /** 预览相关配置 */ 39 | preview?:PreviewInfo; 40 | /** 最近上传版本的sourceMap配置 */ 41 | sourceMapOption?:GetDevSourceMapOption; 42 | /** 云开发上传配置 */ 43 | uploadFunctionOptions?:UploadFunctionOptions; 44 | /** 上传云开发静态网站配置 */ 45 | uploadStaticStorageOptions:UploadStaticStorageOptions; 46 | /** 上传云存储配置 */ 47 | uploadStorageOptions:UploadStaticStorageOptions; 48 | /** 新建云开发云托管版本配置 */ 49 | uploadContainer:any; 50 | } 51 | 52 | /** 53 | * 获取工程目录的配置文件 54 | * @param {string} root 55 | * @returns UserConfig 56 | */ 57 | export const getConfig = (root:string):UserConfig => { 58 | const resolvedPath = path.join(root || process.cwd(), 'mini.config.js'); 59 | try { 60 | let userConfig:UserConfig; 61 | if(fs.existsSync(resolvedPath)){ 62 | delete require.cache[require.resolve(resolvedPath)]; 63 | userConfig = require(resolvedPath); 64 | if(!('project' in userConfig)){ 65 | console.log('project config is no exit'); 66 | throw 'project config is no exit'; 67 | } 68 | return userConfig; 69 | }else{ 70 | throw `${resolvedPath} is no exit`; 71 | } 72 | } catch (e) { 73 | console.log(`failed to load config from ${resolvedPath}`); 74 | throw e; 75 | } 76 | }; 77 | /** 78 | * 生成 mini.config.js 79 | * @param {string} root 80 | */ 81 | export const createTemplate = (root:string) => { 82 | const resolvedPath = path.join(root || process.cwd(), 'mini.config.js'); 83 | if (fs.existsSync(resolvedPath)) { 84 | console.log( 85 | `\n[${resolvedPath}] 已生成!\n`, 86 | ); 87 | }else{ 88 | fs.writeFile(resolvedPath, getTemplate(), (err) => { 89 | if (err) throw err; 90 | console.log( 91 | `\n[${resolvedPath}] 已生成!\n`, 92 | ); 93 | }); 94 | } 95 | }; 96 | 97 | /** 98 | * 上传小程序 99 | * @param {ICreateProjectOptions} projectConfig 100 | * @param {UploadInfo} uploadInfo 101 | */ 102 | export const uploadProject = async(projectConfig:ICreateProjectOptions, uploadInfo:UploadInfo) => { 103 | try { 104 | await ci.upload({ 105 | project: new ci.Project(projectConfig), 106 | ...uploadInfo, 107 | }); 108 | console.log('已更新至微信小程序助手~'); 109 | } catch (error) { 110 | console.log(JSON.stringify(error)); 111 | } 112 | }; 113 | 114 | /** 115 | * 预览小程序 116 | * @param {ICreateProjectOptions} projectConfig 117 | * @param {PreviewInfo} previewInfo 118 | */ 119 | export const previewProject = async(projectConfig:ICreateProjectOptions, previewInfo:PreviewInfo) => { 120 | try { 121 | await ci.preview({ 122 | project: new ci.Project(projectConfig), 123 | ...previewInfo, 124 | }); 125 | console.log('已更新至微信小程序助手~'); 126 | } catch (error) { 127 | console.log('error', JSON.stringify(error)); 128 | } 129 | }; 130 | 131 | /** 132 | * 最近上传版本的sourceMap 133 | * @param {ICreateProjectOptions} projectConfig 134 | * @param {GetDevSourceMapOption} sourceMapOption 135 | */ 136 | export const getDevSourceMap = async(projectConfig:ICreateProjectOptions, sourceMapOption:GetDevSourceMapOption) => { 137 | try { 138 | await ci.getDevSourceMap({ 139 | project: new ci.Project(projectConfig), 140 | ...sourceMapOption, 141 | }); 142 | console.log('getDevSourceMap 执行完~'); 143 | } catch (error) { 144 | console.log('error', JSON.stringify(error)); 145 | } 146 | }; 147 | 148 | /** 149 | * 上传云开发云函数 150 | * @param {ICreateProjectOptions} projectConfig 151 | * @param {UploadFunctionOptions} uploadFunctionOptions 152 | */ 153 | export const uploadFunction = async(projectConfig:ICreateProjectOptions, uploadFunctionOptions:UploadFunctionOptions) => { 154 | try { 155 | await ci.cloud.uploadFunction({ 156 | project: new ci.Project(projectConfig), 157 | ...uploadFunctionOptions, 158 | }); 159 | console.log('getDevSourceMap 执行完~'); 160 | } catch (error) { 161 | console.log('error', JSON.stringify(error)); 162 | } 163 | }; 164 | 165 | /** 166 | * 上传云开发静态网站 167 | * @param {ICreateProjectOptions} projectConfig 168 | * @param {UploadStaticStorageOptions} uploadStaticStorageOptions 169 | */ 170 | export const uploadStaticStorage = async(projectConfig:ICreateProjectOptions, uploadStaticStorageOptions:UploadStaticStorageOptions) => { 171 | try { 172 | await ci.cloud.uploadStaticStorage({ 173 | project: new ci.Project(projectConfig), 174 | ...uploadStaticStorageOptions, 175 | }); 176 | console.log('uploadStaticStorage 执行完~'); 177 | } catch (error) { 178 | console.log('error', JSON.stringify(error)); 179 | } 180 | }; 181 | 182 | 183 | /** 184 | * 上传云存储 185 | * @param {ICreateProjectOptions} projectConfig 186 | * @param {UploadStaticStorageOptions} uploadStorageOptions 187 | */ 188 | export const uploadStorage = async(projectConfig:ICreateProjectOptions, uploadStorageOptions:UploadStaticStorageOptions) => { 189 | try { 190 | await ci.cloud.uploadStorage({ 191 | project: new ci.Project(projectConfig), 192 | ...uploadStorageOptions, 193 | }); 194 | console.log('uploadStorage 执行完~'); 195 | } catch (error) { 196 | console.log('error', JSON.stringify(error)); 197 | } 198 | }; 199 | 200 | /** 201 | * 新建云开发云托管版本 202 | * @param {ICreateProjectOptions} projectConfig 203 | * @param {any} uploadContainer 204 | */ 205 | export const uploadContainer = async(projectConfig:ICreateProjectOptions, uploadContainer:any) => { 206 | try { 207 | await ci.cloud.uploadContainer({ 208 | project: new ci.Project(projectConfig), 209 | ...uploadContainer, 210 | }); 211 | console.log('uploadContainer 执行完~'); 212 | } catch (error) { 213 | console.log('error', JSON.stringify(error)); 214 | } 215 | }; 216 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "moduleResolution": "node", 5 | "strict": true, 6 | "declaration": true, 7 | "noUnusedLocals": true, 8 | "esModuleInterop": true 9 | } 10 | } 11 | --------------------------------------------------------------------------------