rigjs 2.0.0-alpha.0 → 2.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,45 @@
1
1
  import fsHelper from '../utils/fsHelper';
2
- import CICD from '@/classes/cicd/CICD';
2
+ import CICD, {Define} from '@/classes/cicd/CICD';
3
3
  import CICDCmd from '@/classes/cicd/CICDCmd';
4
4
  import shell from 'shelljs';
5
-
5
+ import path from 'path';
6
+ import fs from 'fs';
7
+ const replaceDefine = (target:string,defines?:Define)=>{
8
+ const dirs = fs.readdirSync(target);
9
+ for (let dir of dirs){
10
+ const stat = fs.statSync(path.join(target, dir));
11
+ if (stat.isDirectory()){
12
+ replaceDefine(path.join(target, dir),defines);
13
+ }else{
14
+ if (defines){
15
+ const namePieces = dir.split('.');
16
+ const fileType = namePieces[namePieces.length - 1];
17
+ if (['js','ts'].indexOf(fileType)>=0){
18
+ let file = fs.readFileSync(path.join(target, dir)).toString();
19
+ const replaceArr = Object.keys(defines);
20
+ for (let replace of replaceArr){
21
+ file = file.replace(new RegExp(replace,'g'),defines[replace] as string);
22
+ }
23
+ fs.writeFileSync(path.join(target, dir),file);
24
+ }
25
+ }
26
+ }
27
+ }
28
+ }
6
29
  export default async (cmd: any) => {
7
30
  //create cicd object
8
31
  const cicd = CICD.createByDefault(cmd);
9
32
  //construct cmd object
10
33
  const cicdCmd = new CICDCmd(cmd, cicd);
34
+ console.log(cicd)
11
35
  //build by cicdCmd and cicdConfig
12
36
  console.log(cicdCmd.endpoints);
37
+
13
38
  for (let i = 0; i < cicdCmd.endpoints.length; i++) {
14
39
  const ep = cicdCmd.endpoints[i];
15
- shell.exec(ep.build);
40
+ const cmdStr = `cross-env PUBLIC_PATH=${path.join('/',ep.deployDir)} ${ep.build}`;
41
+ console.log(cmdStr);
42
+ shell.exec(cmdStr);
43
+ replaceDefine(path.join(cicd.source.root_path, ep.dir), ep.defines);
16
44
  }
17
45
  }
@@ -1,9 +1,6 @@
1
1
  import DirLevel from '@/classes/cicd/DirLevel';
2
2
  import Endpoint, { EndpointDict} from '@/classes/cicd/Endpoint';
3
3
  import fs from 'fs';
4
- import {Dir} from 'fs';
5
- import fsHelper from '@/utils/fsHelper';
6
- import CICDCmd from '@/classes/cicd/CICDCmd';
7
4
 
8
5
  const JSON5 = require('json5');
9
6
  import qs from 'querystring';
@@ -21,13 +18,18 @@ interface DeploySource {
21
18
  /**
22
19
  * Deploy target
23
20
  */
24
- interface DeployTarget {
21
+ export interface DeployTarget {
25
22
  id: string;
26
23
  type: CloudType;
27
24
  bucket: string;
25
+ region: string;
28
26
  access_key: string;
29
27
  access_secret: string;
30
28
  root_path: '/';
29
+ uri_rewrite: {
30
+ original: string;
31
+ final?: string;
32
+ };
31
33
  }
32
34
 
33
35
  /**
@@ -0,0 +1,50 @@
1
+ import aliOSS from "ali-oss";
2
+ import fs from "fs";
3
+ import { DeployTarget } from "../CICD";
4
+ class AliOSS {
5
+ ossClient: aliOSS;
6
+ constructor(target: DeployTarget) {
7
+ this.ossClient = new aliOSS({
8
+ region: target.region,
9
+ accessKeyId: target.access_key,
10
+ accessKeySecret: target.access_secret,
11
+ bucket: target.bucket,
12
+ timeout: 600000,
13
+ });
14
+ }
15
+
16
+ private async progress(p: number, filePath: string, ossPath: string) {
17
+ // 上传进度。
18
+ process.stdout.clearLine(1);
19
+ process.stdout.cursorTo(0);
20
+ process.stdout.write(
21
+ `progress: ${p.toFixed(2)}%, Upload '${filePath}' To OSS_PATH:${ossPath}`
22
+ );
23
+ }
24
+
25
+ public async putStreamFiles(
26
+ filesList: string[],
27
+ ossBasePath: string,
28
+ dir: string
29
+ ) {
30
+ for (let i = 0; i < filesList.length; i++) {
31
+ const filePath = filesList[i].split("dist\\")[1];
32
+ const ossPath =
33
+ ossBasePath + filePath.replace(/\\/g, "/").replace(dir, "");
34
+ const fileResult = await this.ossClient.putStream(
35
+ ossPath,
36
+ fs.createReadStream(filesList[i])
37
+ );
38
+ if (fileResult.res.status !== 200) {
39
+ throw new Error('Upload OSS Error')
40
+ }
41
+ // if (fileResult.res.status === 200) {
42
+ // const p = ((i + 1) * 100) / filesList.length;
43
+ // this.progress(p, filesList[i], ossPath);
44
+ // }
45
+ }
46
+ console.log("\n");
47
+ }
48
+ }
49
+
50
+ export default AliOSS;
@@ -0,0 +1,189 @@
1
+ import moment from 'dayjs';
2
+ import qs from 'qs';
3
+ import crypto from 'crypto';
4
+ import axios from 'axios';
5
+ import * as uuid from 'uuid';
6
+ import { DeployTarget } from '../CICD';
7
+
8
+ type TFlag = 'break' | 'enhance_break' | null;
9
+
10
+ class CDN {
11
+ AccessKeySecret: string;
12
+ AccessKeyId: string;
13
+ constructor(target: DeployTarget) {
14
+ this.AccessKeyId = target.access_key;
15
+ this.AccessKeySecret = target.access_secret;
16
+ }
17
+ /**
18
+ * 访问CDN通用接口
19
+ * @param {接口名称} actionName
20
+ * @param {各接口定制化参数} paramObj
21
+ * @returns
22
+ */
23
+ private async getCdnData(actionName: string, paramObj: Object) {
24
+ let config = {
25
+ Action: actionName,
26
+ Format: 'JSON',
27
+ Version: '2018-05-10',
28
+ AccessKeyId: this.AccessKeyId,
29
+ SignatureMethod: 'HMAC-SHA1',
30
+ Timestamp: moment().toDate().toISOString(),
31
+ SignatureVersion: '1.0',
32
+ SignatureNonce: uuid.v1(),
33
+ };
34
+ config = Object.assign(config, paramObj);
35
+ let paramConfig = qs.stringify(config, {
36
+ sort: (a: any, b: any) => {
37
+ return a < b ? -1 : 1;
38
+ },
39
+ charset: 'utf-8',
40
+ });
41
+
42
+ const strSign = `GET&%2F&${encodeURIComponent(paramConfig)}`;
43
+ // console.log(`strSign: ${strSign}\n`);
44
+ const hmacSha1 = crypto.createHmac('sha1', `${this.AccessKeySecret}&`);
45
+ hmacSha1.update(strSign);
46
+ const signature = hmacSha1.digest('base64');
47
+ config = Object.assign(config, {
48
+ Signature: signature,
49
+ });
50
+ paramConfig = qs.stringify(config, {
51
+ sort: (a, b) => {
52
+ return a < b ? -1 : 1;
53
+ },
54
+ charset: 'utf-8',
55
+ format: 'RFC3986',
56
+ });
57
+
58
+ const url = `http://cdn.aliyuncs.com?${paramConfig}`;
59
+
60
+ const res = await axios.create().get(url);
61
+ return res.data;
62
+ }
63
+
64
+ /**
65
+ * 改写回源URI接口
66
+ * @param {加速域名} domainName
67
+ * @param {需要重写的url 数组} sourceUrls
68
+ * @param {重写目标url 数组} targetUrls
69
+ * @param {改写操作执行规则 数组 值为null、break或enhance_break} flags
70
+ * @returns
71
+ */
72
+ public async setRWriteUri(
73
+ domainName: string,
74
+ sourceUrls: string[],
75
+ targetUrls: string[],
76
+ flags: TFlag[]
77
+ ) {
78
+ try {
79
+ if (sourceUrls.length !== targetUrls.length) {
80
+ throw new Error(`sourceUrls's length not equal targetUrls's length`);
81
+ }
82
+ const Functions: Object[] = [];
83
+ sourceUrls.forEach((item, index) => {
84
+ Functions.push({
85
+ functionArgs: [
86
+ {
87
+ argName: 'source_url',
88
+ argValue: item,
89
+ },
90
+ {
91
+ argName: 'target_url',
92
+ argValue: targetUrls[index],
93
+ },
94
+ {
95
+ argName: 'flag',
96
+ argValue: flags[index],
97
+ },
98
+ ],
99
+ functionName: 'back_to_origin_url_rewrite',
100
+ });
101
+ });
102
+
103
+ const data = await this.getCdnData('BatchSetCdnDomainConfig', {
104
+ DomainNames: domainName,
105
+ Functions: JSON.stringify(Functions),
106
+ });
107
+ return data;
108
+ } catch (e) {
109
+ console.error(
110
+ `Error: ${e.response ? JSON.stringify(e.response.data.Message) : e}`
111
+ );
112
+ throw new Error(e.response.data.Message);
113
+ }
114
+ }
115
+
116
+ /**
117
+ * 刷新节点上的文件内容
118
+ * @param {刷新URL, 格式为加速域名或刷新的文件或目录。多个URL之间使用换行符(\n)或(\r\n)分隔} objectPath
119
+ * @param {刷新的类型 File: 文件; Directory: 目录} objectType
120
+ */
121
+ public async refreshCache(objectPath: string, objectType?: string) {
122
+ try {
123
+ let param = {
124
+ ObjectPath: objectPath,
125
+ };
126
+ if (objectType) {
127
+ param = Object.assign(param, { ObjectType: objectType });
128
+ }
129
+ const data = await this.getCdnData('RefreshObjectCaches', param);
130
+ return data;
131
+ } catch (e) {
132
+ console.error('Error:');
133
+ console.error(e.response.data.Message);
134
+ throw new Error(e.response.data.Message);
135
+ }
136
+ }
137
+
138
+ /**
139
+ * 预热源站内容到缓存节点
140
+ * @param {预热URL,格式为加速域名或预热的文件 多个URL之间使用换行符(\n)或(\r\n)分隔 单条长度最长为1024个字符} objectPath
141
+ * @returns
142
+ */
143
+ async pushCache(objectPath: string) {
144
+ const data = await this.getCdnData('PushObjectCache', {
145
+ ObjectPath: objectPath,
146
+ });
147
+ return data;
148
+ }
149
+
150
+ /**
151
+ * 通过任务编号查询刷新预热任务信息
152
+ * @param {支持同时传入多个任务ID,多个任务ID之间用英文逗号(,)分隔,最多支持同时传入10个任务ID} taskIds
153
+ * @returns
154
+ */
155
+ async describeRefreshTaskById(taskIds: string) {
156
+ try {
157
+ const data = await this.getCdnData('DescribeRefreshTaskById', {
158
+ TaskId: taskIds,
159
+ });
160
+ return data;
161
+ } catch (e) {
162
+ console.error('Error:');
163
+ console.error(e.response.data.Message);
164
+ throw new Error(e.response.data.Message);
165
+ }
166
+ }
167
+
168
+ /**
169
+ * 刷新CDN节点
170
+ * @param {加速域名} domainName
171
+ * @param {功能配置ID} configId
172
+ * @returns
173
+ */
174
+ async describeCdnDomainConfigs(domainName: string, configId?: string) {
175
+ try {
176
+ const data = await this.getCdnData('DescribeCdnDomainConfigs', {
177
+ DomainName: domainName,
178
+ ConfigId: configId,
179
+ });
180
+ return data;
181
+ } catch (e) {
182
+ console.error('Error:');
183
+ console.error(e.response.data.Message);
184
+ throw new Error(e.response.data.Message);
185
+ }
186
+ }
187
+ }
188
+
189
+ export default CDN;
@@ -1,4 +1,4 @@
1
- import {CICDConfig, DefineDict, DirGroup} from './CICD';
1
+ import {CICDConfig, Define, DefineDict, DeployTarget, DirGroup} from './CICD';
2
2
  import {mkdirSync} from 'fs';
3
3
  import DirLevel from '@/classes/cicd/DirLevel';
4
4
 
@@ -6,7 +6,7 @@ interface EndpointInfo {
6
6
  build: string;
7
7
  target: string;
8
8
  domain: string;
9
- define: DefineDict;
9
+ defines: Define;
10
10
  }
11
11
 
12
12
  export interface EndpointDict {
@@ -21,7 +21,7 @@ class Endpoint {
21
21
  build: string;
22
22
  domain: string;
23
23
  deployDir: string;
24
- define: DefineDict;
24
+ defines: Define;
25
25
 
26
26
 
27
27
  constructor(dir: string, info: EndpointInfo, schema: DirLevel[]) {
@@ -32,7 +32,7 @@ class Endpoint {
32
32
  this.target = info.target;
33
33
  this.build = info.build;
34
34
  this.domain = info.domain;
35
- this.define = info.define;
35
+ this.defines = info.defines;
36
36
  }
37
37
 
38
38
  static createEndpointArr(cicdConfig: CICDConfig, schema: DirLevel[]) {
@@ -13,7 +13,7 @@ const replaceDefine = (target:string,define?:Define)=>{
13
13
  if (define){
14
14
  const namePieces = dir.split('.');
15
15
  const fileType = namePieces[namePieces.length - 1];
16
- if (['js','json','json5','yml','ts'].indexOf(fileType)>=0){
16
+ if (['js','ts'].indexOf(fileType)>=0){
17
17
  let file = fs.readFileSync(path.join(target, dir)).toString();
18
18
  const replaceArr = Object.keys(define);
19
19
  for (let replace of replaceArr){
@@ -1,41 +1,56 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import aliOSS from "ali-oss";
4
- import fsHelper from "../utils/fsHelper";
5
- import CICD from "@/classes/cicd/CICD";
6
- import CICDCmd from "@/classes/cicd/CICDCmd";
7
- //
8
- // const progress = (p: number, filePath: string, ossPath: string) => {
9
- // // 上传进度。
10
- // process.stdout.clearLine(-1);
11
- // process.stdout.cursorTo(0);
12
- // process.stdout.write(
13
- // `progress: ${p.toFixed(2)}%, Upload '${filePath}' To OSS_PATH:${ossPath}`
14
- // );
15
- // };
16
- //
17
- // let filesList: string[] = [];
18
- // const traverseFolder = (url: string) => {
19
- // if (fs.existsSync(url)) {
20
- // const files = fs.readdirSync(url);
21
- // files.forEach((file) => {
22
- // const curPath = path.join(url, file);
23
- // if (fs.statSync(curPath).isDirectory()) {
24
- // traverseFolder(curPath);
25
- // } else {
26
- // filesList.push(curPath);
27
- // }
28
- // });
29
- // }
30
- // };
31
- //
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import CICD from '@/classes/cicd/CICD';
4
+ import CICDCmd from '@/classes/cicd/CICDCmd';
5
+ import AliOSS from '@/classes/cicd/Deploy/AliDeploy';
6
+ import CDN from '@/classes/cicd/Deploy/CDN';
7
+
8
+ let filesList: string[] = [];
9
+ const traverseFolder = (url: string) => {
10
+ if (fs.existsSync(url)) {
11
+ const files = fs.readdirSync(url);
12
+ files.forEach((file) => {
13
+ const curPath = path.join(url, file);
14
+ if (fs.statSync(curPath).isDirectory()) {
15
+ traverseFolder(curPath);
16
+ } else {
17
+ filesList.push(curPath);
18
+ }
19
+ });
20
+ }
21
+ };
22
+
32
23
  export default async (cmd: any) => {
33
- try {
34
- //create cicd object
35
- const cicd = CICD.createByDefault(cmd);
36
- //construct cmd object
37
- const cicdCmd = new CICDCmd(cmd, cicd);
38
- }catch (e) {
39
- throw e;
40
- }
41
- }
24
+ try {
25
+ console.log('Start Deploy-----');
26
+ //create cicd object
27
+ const cicd = CICD.createByDefault(cmd);
28
+ //construct cmd object
29
+ const cicdCmd = new CICDCmd(cmd, cicd);
30
+
31
+ const target = Array.isArray(cicdCmd.cicd.target)
32
+ ? cicdCmd.cicd.target[0]
33
+ : cicdCmd.cicd.target;
34
+
35
+ const aliOss = new AliOSS(target);
36
+ console.log('Please Wait for Upload OSS...');
37
+ for (let i = 0; i < cicdCmd.endpoints.length; i++) {
38
+ const distPath = path.join(
39
+ process.cwd(),
40
+ cicd.source.root_path,
41
+ cicdCmd.endpoints[i].dir
42
+ );
43
+ traverseFolder(distPath);
44
+ await aliOss.putStreamFiles(
45
+ filesList,
46
+ cicdCmd.endpoints[i].deployDir.replace(/\\/g, '/'),
47
+ cicdCmd.endpoints[i].dir
48
+ );
49
+ filesList = [];
50
+ }
51
+ console.log('Upload OSS Done');
52
+ console.log('Deploy Done-----');
53
+ } catch (e) {
54
+ throw e;
55
+ }
56
+ };
@@ -0,0 +1,84 @@
1
+ import fsHelper from '../utils/fsHelper';
2
+ import CICD from '@/classes/cicd/CICD';
3
+ import CICDCmd from '@/classes/cicd/CICDCmd';
4
+ import shell from 'shelljs';
5
+ import path from 'path';
6
+ import CDN from '@/classes/cicd/Deploy/CDN';
7
+
8
+ const setRWriteUri = async (
9
+ domain: string,
10
+ original: string,
11
+ deployDir: string,
12
+ cdn: CDN
13
+ ) => {
14
+ const rwriteResult = await cdn.setRWriteUri(
15
+ domain,
16
+ [original],
17
+ [deployDir],
18
+ ['enhance_break']
19
+ );
20
+
21
+ const configId = rwriteResult?.DomainConfigList.DomainConfigModel[0].ConfigId;
22
+ console.log('Please Wait For Set RWrite URI...');
23
+ while (true) {
24
+ const configInfo = await cdn.describeCdnDomainConfigs(domain, configId);
25
+ if (configInfo.DomainConfigs.DomainConfig[0].Status === 'success') {
26
+ break;
27
+ }
28
+ if (configInfo.DomainConfigs.DomainConfig[0].Status === 'failed') {
29
+ throw new Error('cdn rewrite fail');
30
+ }
31
+ }
32
+ console.log('Set RWrite URI Done');
33
+ };
34
+
35
+ const refreshCache = async (urls: string[], cdn: CDN) => {
36
+ const refreshResult = await cdn.refreshCache(urls.join('\n'));
37
+ console.log('Please Wait For RefreshCache...');
38
+ while (true) {
39
+ const desResult = await cdn.describeRefreshTaskById(
40
+ refreshResult.RefreshTaskId
41
+ );
42
+ let successCount = 0;
43
+ for (const item of desResult.Tasks) {
44
+ if (item.Status === 'Complete') {
45
+ successCount++;
46
+ } else if (item.Status === 'Failed') {
47
+ throw new Error('RefreshCache Failed');
48
+ }
49
+ }
50
+ if (successCount === desResult.Tasks.length) {
51
+ break;
52
+ }
53
+ }
54
+ console.log('RefreshCache Done');
55
+ };
56
+
57
+ export default async (cmd: any) => {
58
+ //create cicd object
59
+ const cicd = CICD.createByDefault(cmd);
60
+ //construct cmd object
61
+ const cicdCmd = new CICDCmd(cmd, cicd);
62
+
63
+ console.log('Start Publish-----');
64
+ const target = Array.isArray(cicdCmd.cicd.target)
65
+ ? cicdCmd.cicd.target[0]
66
+ : cicdCmd.cicd.target;
67
+
68
+ const cdn = new CDN(target);
69
+ const urls: string[] = [];
70
+ for (const endpoint of cicdCmd.endpoints) {
71
+ // 目前只支持set一个original
72
+ await setRWriteUri(
73
+ endpoint.domain,
74
+ `/${target.uri_rewrite.original}`,
75
+ `/${endpoint.deployDir.replace(/\\/g, '/')}/index.html`,
76
+ cdn
77
+ );
78
+ urls.push(`https://${endpoint.domain}/${target.uri_rewrite.original}`);
79
+ }
80
+
81
+ //刷新cdn
82
+ await refreshCache(urls, cdn);
83
+ console.log('Start Publish-----');
84
+ };
package/lib/rig/index.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import {Command} from 'commander';
2
2
 
3
3
  const program = new Command();
4
- console.log('Hello rigjs');
4
+ console.log('Hello');
5
+
5
6
  import check from '../check';
6
7
 
7
8
  program.command('check').action(check.load);
@@ -41,6 +42,14 @@ program.command('deploy')
41
42
  .option('-s, --schema <schema>', 'specify params in tree_schema')
42
43
  .option('-p , --params <params>', 'replace words in cicd.rig.json5, only words in ${} are replacable')
43
44
  .action(deploy);
45
+
46
+ import publish from '../publish';
47
+
48
+ program.command('publish')
49
+ .option('-s, --schema <schema>', 'specify params in tree_schema')
50
+ .option('-p , --params <params>', 'replace words in cicd.rig.json5, only words in ${} are replacable')
51
+ .action(publish);
52
+
44
53
  import env from '../env';
45
54
 
46
55
  program.option('-e, --env <env>', 'specify env').action(env.load);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rigjs",
3
- "version": "2.0.0-alpha.0",
3
+ "version": "2.0.0-alpha.3",
4
4
  "description": "A multi-repos dev tool based on yarn and git.Rig is inspired by cocoapods. Not like those monorepo solutions,rig is a tool for organizing multi-repos.",
5
5
  "keywords": [
6
6
  "modular",
@@ -29,19 +29,25 @@
29
29
  "envmake": "cd demo && node ../lib/rig/index.js --env prod_view_zhs",
30
30
  "t": "node lib/rig/index.js tag",
31
31
  "deliver": "npm publish --registry=https://registry.npmjs.org",
32
+ "deliver:alpha": "npm publish --registry=https://registry.npmjs.org --tag alpha",
32
33
  "build": "esbuild lib/rig/index.ts --platform=node --bundle --minify --outfile=built/index.js --external:shelljs"
33
34
  },
34
35
  "dependencies": {
35
36
  "@types/ali-oss": "^6.16.3",
36
37
  "@types/json5": "^2.2.0",
38
+ "@types/qs": "^6.9.7",
37
39
  "@types/shelljs": "^0.8.11",
40
+ "@types/uuid": "^8.3.4",
38
41
  "ali-oss": "^6.17.1",
42
+ "axios": "^0.26.1",
39
43
  "chalk": "^4.1.0",
40
44
  "commander": "6.1.0",
45
+ "dayjs": "^1.11.0",
41
46
  "inquirer": "7.3.3",
42
47
  "json5": "2.1.3",
43
48
  "ora": "^5.1.0",
44
- "shelljs": "^0.8.4"
49
+ "shelljs": "^0.8.4",
50
+ "uuid": "^8.3.2"
45
51
  },
46
52
  "devDependencies": {
47
53
  "@types/node": "^17.0.21"
@@ -1,14 +0,0 @@
1
- /**
2
- * @ignore
3
- * @Description nothing
4
- * @author Wang Bo (ralwayne@163.com)
5
- * @date 2020/10/9 6:14 PM
6
- */
7
- //加载命令控制器
8
- const load = (program) => {
9
-
10
- }
11
- module.exports = {
12
- name:'publish',
13
- load
14
- }