@clickview/ship-it 0.0.9 → 0.0.11

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.
Files changed (57) hide show
  1. package/config.json +1 -1
  2. package/dist/X2/Analytics Web.md +11 -0
  3. package/dist/X2/Batch.Api.md +11 -0
  4. package/dist/X2/ClickView Online.md +43 -0
  5. package/dist/X2/ClickView.Cloud247.SpliceService.md +12 -0
  6. package/dist/X2/ClickView.Cron.md +10 -0
  7. package/dist/X2/ClickView.Curator.md +22 -0
  8. package/dist/X2/ClickView.OnlineApi.md +14 -0
  9. package/dist/X2/Curriculum.App.md +9 -0
  10. package/dist/X2/CurriculumIngestion.Api.md +8 -0
  11. package/dist/X2/Discover.Api.md +35 -0
  12. package/dist/X2/Domain.Api.md +11 -0
  13. package/dist/X2/FileGenerator.md +11 -0
  14. package/dist/X2/Hydration.App.md +9 -0
  15. package/dist/X2/Integrations.Api.md +8 -0
  16. package/dist/X2/Krakend.md +18 -0
  17. package/dist/X2/LTI.md +11 -0
  18. package/dist/X2/Library Editor.md +11 -0
  19. package/dist/X2/Library.Api.md +13 -0
  20. package/dist/X2/Lite.md +21 -0
  21. package/dist/X2/Master.Api.md +21 -0
  22. package/dist/X2/Master.Auth.md +22 -0
  23. package/dist/X2/Objects.Api.md +30 -0
  24. package/dist/X2/Permissions.Api.md +34 -0
  25. package/dist/X2/Release Notes.md +932 -0
  26. package/dist/X2/Share.Api.md +8 -0
  27. package/dist/X2/Subjects.API.md +21 -0
  28. package/dist/X2/TvProgramMonitor.App.md +8 -0
  29. package/dist/X2/Users.Api.md +25 -0
  30. package/dist/X2/VideoProcessorService.md +12 -0
  31. package/dist/X2/X2 Release Notes.md +932 -0
  32. package/dist/X2/X2 Testing Notes.csv +1200 -0
  33. package/dist/X2/X2 Testing Notes_old.csv +2060 -0
  34. package/dist/X2/clickview.md +314 -0
  35. package/dist/X2/index.app.md +8 -0
  36. package/dist/X2/notification-service.md +48 -0
  37. package/dist/Y2/Y2 Testing Notes.csv +1057 -0
  38. package/lib/config.json +1 -1
  39. package/lib/src/api-clients/git-lab/GitLabApiClient.js +0 -1
  40. package/lib/src/commands/CreateTestingNotesCommand.js +84 -0
  41. package/lib/src/commands/index.js +1 -0
  42. package/lib/src/constants/CommandTypeMapping.js +1 -0
  43. package/lib/src/interfaces/models/ProjectConfig.js +9 -0
  44. package/lib/src/inversify.config.js +2 -0
  45. package/lib/src/services/GitLabService.js +33 -0
  46. package/lib/src/startup/SetupCommands.js +1 -0
  47. package/lib/src/tasks/CreateMergeRequestTask.js +12 -9
  48. package/lib/src/tasks/CreateReleaseNotesTask.js +11 -8
  49. package/lib/src/tasks/CreateTestingNotesTask.js +135 -0
  50. package/lib/src/tasks/TagMasterTask.js +1 -2
  51. package/lib/src/tasks/ValidateDescriptionsTask.js +63 -33
  52. package/lib/src/tasks/ValidateMergeRequestTask.js +5 -4
  53. package/lib/src/tasks/index.js +1 -0
  54. package/lib/src/types.js +2 -0
  55. package/lib/src/utils/Csv.js +54 -0
  56. package/lib/src/utils/Descriptions.js +120 -103
  57. package/package.json +3 -2
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.CsvFile = void 0;
18
+ var format_1 = require("@fast-csv/format");
19
+ var fs_extra_1 = __importDefault(require("fs-extra"));
20
+ var CsvFile = /** @class */ (function () {
21
+ function CsvFile(opts) {
22
+ this.headers = opts.headers;
23
+ this.path = opts.path;
24
+ this.writeOpts = { headers: this.headers, includeEndRowDelimiter: true };
25
+ }
26
+ CsvFile.write = function (stream, rows, options) {
27
+ return new Promise(function (res, rej) {
28
+ (0, format_1.writeToStream)(stream, rows, options)
29
+ .on('error', function (err) { return rej(err); })
30
+ .on('finish', function () { return res(); });
31
+ });
32
+ };
33
+ CsvFile.prototype.create = function (rows) {
34
+ return CsvFile.write(fs_extra_1.default.createWriteStream(this.path), rows, __assign({}, this.writeOpts));
35
+ };
36
+ CsvFile.prototype.append = function (rows) {
37
+ return CsvFile.write(fs_extra_1.default.createWriteStream(this.path, { flags: 'a' }), rows, __assign(__assign({}, this.writeOpts), {
38
+ // dont write the headers when appending
39
+ writeHeaders: false }));
40
+ };
41
+ CsvFile.prototype.read = function () {
42
+ var _this = this;
43
+ return new Promise(function (res, rej) {
44
+ fs_extra_1.default.readFile(_this.path, function (err, contents) {
45
+ if (err) {
46
+ return rej(err);
47
+ }
48
+ return res(contents);
49
+ });
50
+ });
51
+ };
52
+ return CsvFile;
53
+ }());
54
+ exports.CsvFile = CsvFile;
@@ -1,67 +1,46 @@
1
1
  "use strict";
2
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
- if (ar || !(i in from)) {
5
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
- ar[i] = from[i];
7
- }
8
- }
9
- return to.concat(ar || Array.prototype.slice.call(from));
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.Descriptions = void 0;
13
- var VALID_HEADINGS = {
14
- 'dependencies': true,
15
- 'before release': true,
16
- 'customer changes': true,
17
- 'code changes': true,
18
- 'testing': true,
19
- 'notes': true,
20
- 'other': true
21
- };
22
- var VALID_MONOREPO_HEADINGS = {
23
- 'common': true,
24
- 'curator': true,
25
- 'library editor': true,
26
- 'lite': true,
27
- 'online': true,
28
- 'shared': true,
29
- 'styles': true,
30
- 'player': true,
31
- 'reports': true,
32
- 'analytics': true,
33
- 'tooling': true,
34
- 'testing': true,
35
- 'dependencies': true,
36
- 'notes': true,
37
- 'monorepo': true,
38
- 'before release': true
4
+ var Headings = {
5
+ BeforeRelease: 'Before release',
6
+ Dependencies: 'Dependencies',
7
+ CodeChanges: 'Code changes',
8
+ CustomerChanges: 'Customer changes',
9
+ Testing: 'Testing',
10
+ Notes: 'Notes'
39
11
  };
40
- /**
41
- * Most of the ordering here doesn't matter, BUT "before release" and "dependencies" should always be
42
- * at the top so that they're more visible to whoever is managing the release.
43
- */
12
+ var BASE_VALID_HEADINGS = [
13
+ Headings.BeforeRelease,
14
+ Headings.Dependencies,
15
+ Headings.Testing,
16
+ Headings.Notes
17
+ ];
18
+ var PROJECT_VALID_HEADINGS = BASE_VALID_HEADINGS.concat([
19
+ Headings.CustomerChanges,
20
+ Headings.CodeChanges
21
+ ]);
22
+ var PROJECT_REQUIRED_HEADINGS = [
23
+ Headings.Testing
24
+ ];
44
25
  var HEADING_ORDER = [
45
- 'before release',
46
- 'dependencies',
47
- 'notes',
48
- 'other',
49
- 'customer changes',
50
- 'code changes',
51
- 'lite',
52
- 'library editor',
53
- 'online',
54
- 'reports',
55
- 'curator',
56
- 'player',
57
- 'shared',
58
- 'analytics',
59
- 'styles',
60
- 'common',
61
- 'monorepo',
62
- 'tooling',
63
- 'testing'
26
+ Headings.BeforeRelease,
27
+ Headings.Dependencies,
28
+ Headings.CustomerChanges,
29
+ Headings.CodeChanges,
30
+ '*',
31
+ Headings.Testing,
32
+ Headings.Notes,
64
33
  ];
34
+ function headingTransformer(heading) {
35
+ // Fix casing of known headings
36
+ var lowerHeading = heading.toLowerCase();
37
+ for (var i = 0; i < PROJECT_VALID_HEADINGS.length; i++) {
38
+ if (PROJECT_VALID_HEADINGS[i].toLowerCase() === lowerHeading)
39
+ return PROJECT_VALID_HEADINGS[i];
40
+ }
41
+ // No transform
42
+ return heading;
43
+ }
65
44
  function toObject(lines, headingPrefix) {
66
45
  var obj = {};
67
46
  var currentHeading = 'other';
@@ -72,7 +51,7 @@ function toObject(lines, headingPrefix) {
72
51
  continue;
73
52
  if (line.startsWith(headingPrefix + ' ')) {
74
53
  // TODO: Potentially add heading transforms to capture multiple variants
75
- currentHeading = line.toLowerCase().replace(headingPrefix, '').trim();
54
+ currentHeading = headingTransformer(line.replace(headingPrefix, '').trim());
76
55
  continue;
77
56
  }
78
57
  if (!obj[currentHeading])
@@ -95,47 +74,85 @@ function toObject(lines, headingPrefix) {
95
74
  * - Josh
96
75
  */
97
76
  function orderDescriptionHeadings(headings) {
98
- var orderForIndexVals = __spreadArray([], HEADING_ORDER, true).reverse();
77
+ // Get the index of our wildcard where we put all the other headings into
78
+ var starIndex = HEADING_ORDER.indexOf('*');
79
+ if (starIndex === -1)
80
+ starIndex = HEADING_ORDER.length;
99
81
  return headings.sort(function (a, b) {
100
- var aIndex = -orderForIndexVals.indexOf(a);
101
- var bIndex = -orderForIndexVals.indexOf(b);
82
+ var aIndex = HEADING_ORDER.indexOf(a);
83
+ var bIndex = HEADING_ORDER.indexOf(b);
84
+ // Do normal sort logic if both are missing from heading order
85
+ if (aIndex === -1 && bIndex === -1) {
86
+ if (a < b)
87
+ return -1;
88
+ if (a > b)
89
+ return 1;
90
+ return 0;
91
+ }
92
+ if (aIndex === -1)
93
+ aIndex = starIndex;
94
+ if (bIndex === -1)
95
+ bIndex = starIndex;
102
96
  return aIndex - bIndex;
103
97
  });
104
98
  }
105
99
  exports.Descriptions = {
106
- isDescriptionValid: function (description, headingPrefix, checkForTesting) {
107
- if (headingPrefix === void 0) { headingPrefix = '#'; }
108
- if (checkForTesting === void 0) { checkForTesting = true; }
109
- if (!description.trim())
110
- return false;
111
- var obj = toObject(description.split('\n'), headingPrefix);
112
- var keys = Object.keys(obj);
113
- if (!(keys === null || keys === void 0 ? void 0 : keys.length))
114
- return false;
115
- if (keys.some(function (k) { return !VALID_HEADINGS[k]; }))
116
- return false;
117
- if (checkForTesting && obj['testing'] === undefined)
118
- return false;
119
- return true;
120
- },
121
- isMonorepoDescriptionValid: function (description) {
122
- if (!description.trim())
123
- return false;
100
+ validate: function (description, projectConfig) {
101
+ var validHeadings;
102
+ // If we are a monorepo, add in the valid sub project headings
103
+ if (projectConfig.monorepo.enabled) {
104
+ var subProjects = projectConfig.monorepo.validSubProjects;
105
+ validHeadings = BASE_VALID_HEADINGS.concat(subProjects);
106
+ }
107
+ else {
108
+ validHeadings = PROJECT_VALID_HEADINGS;
109
+ }
110
+ // Parse description
124
111
  var obj = toObject(description.split('\n'), '#');
125
- var keys = Object.keys(obj);
126
- if (!(keys === null || keys === void 0 ? void 0 : keys.length))
127
- return false;
128
- if (keys.some(function (k) { return !VALID_MONOREPO_HEADINGS[k]; }))
129
- return false;
130
- if (obj['testing'] === undefined)
131
- return false;
132
- var isValid = Object.keys(obj).every(function (key) {
133
- if (key === 'dependencies' || key === 'testing')
134
- return true;
135
- var subValid = exports.Descriptions.isDescriptionValid(obj[key], '##', false);
136
- return subValid;
112
+ var errors = this.validateProject(obj, {
113
+ validSections: validHeadings,
114
+ requiredSections: PROJECT_REQUIRED_HEADINGS
137
115
  });
138
- return isValid;
116
+ if (!projectConfig.monorepo.enabled)
117
+ return errors;
118
+ var _loop_1 = function (subProject) {
119
+ // Ignore known headings
120
+ if (PROJECT_VALID_HEADINGS.indexOf(subProject) !== -1)
121
+ return "continue";
122
+ var subObj = toObject(obj[subProject].split('\n'), '##');
123
+ var subErrors = this_1.validateProject(subObj, {
124
+ validSections: PROJECT_VALID_HEADINGS,
125
+ requiredSections: []
126
+ });
127
+ errors = errors.concat(subErrors.map(function (x) { return "[".concat(subProject, "] ") + x; }));
128
+ };
129
+ var this_1 = this;
130
+ // If monorepo we need to check the sub projects are valid
131
+ for (var subProject in obj) {
132
+ _loop_1(subProject);
133
+ }
134
+ return errors;
135
+ },
136
+ validateProject: function (parsedDescription, options) {
137
+ // Parse description
138
+ var headings = Object.keys(parsedDescription);
139
+ // Must have at least one heading
140
+ if (headings.length < 1)
141
+ return ['Must have at least one section'];
142
+ var errors = [];
143
+ // Ensure all the headings are valid
144
+ for (var _i = 0, headings_1 = headings; _i < headings_1.length; _i++) {
145
+ var heading = headings_1[_i];
146
+ if (options.validSections.indexOf(heading) === -1)
147
+ errors.push("Invalid section: ".concat(heading));
148
+ }
149
+ // Ensure we have all required headings
150
+ for (var _a = 0, _b = options.requiredSections; _a < _b.length; _a++) {
151
+ var requiredSection = _b[_a];
152
+ if (parsedDescription[requiredSection] === undefined)
153
+ errors.push("Missing section: ".concat(requiredSection));
154
+ }
155
+ return errors;
139
156
  },
140
157
  getCombinedDescription: function (mergeRequests, headingPrefix) {
141
158
  if (headingPrefix === void 0) { headingPrefix = '#'; }
@@ -143,7 +160,7 @@ exports.Descriptions = {
143
160
  .filter(function (mr) { return mr.status === 'merged'; })
144
161
  .map(function (mr) { return toObject(mr.description.split('\n'), headingPrefix); });
145
162
  var obj = {};
146
- var _loop_1 = function (descriptionObj) {
163
+ var _loop_2 = function (descriptionObj) {
147
164
  Object.keys(descriptionObj).forEach(function (key) {
148
165
  if (!obj[key])
149
166
  obj[key] = '';
@@ -152,16 +169,16 @@ exports.Descriptions = {
152
169
  };
153
170
  for (var _i = 0, descriptionObjs_1 = descriptionObjs; _i < descriptionObjs_1.length; _i++) {
154
171
  var descriptionObj = descriptionObjs_1[_i];
155
- _loop_1(descriptionObj);
172
+ _loop_2(descriptionObj);
156
173
  }
157
174
  var description = '';
158
175
  var orderedHeadings = orderDescriptionHeadings(Object.keys(obj));
159
176
  orderedHeadings.forEach(function (key) {
160
- if (key === 'notes')
177
+ if (key === Headings.Notes)
161
178
  return;
162
179
  if (!obj[key])
163
180
  return;
164
- description += '\n' + headingPrefix + ' ' + key.charAt(0).toUpperCase() + key.slice(1) + '\n';
181
+ description += '\n' + headingPrefix + ' ' + key + '\n';
165
182
  description += obj[key];
166
183
  });
167
184
  return description;
@@ -173,7 +190,7 @@ exports.Descriptions = {
173
190
  .filter(function (mr) { return mr.status === 'merged'; })
174
191
  .map(function (mr) { return toObject(mr.description.split('\n'), '#'); });
175
192
  var combinedObj = {};
176
- var _loop_2 = function (descriptionObj) {
193
+ var _loop_3 = function (descriptionObj) {
177
194
  Object.keys(descriptionObj).forEach(function (key) {
178
195
  if (!combinedObj[key])
179
196
  combinedObj[key] = {};
@@ -189,18 +206,18 @@ exports.Descriptions = {
189
206
  // For each property in each MR object, calculate it's H2 heading objects
190
207
  for (var _i = 0, descriptionObjs_2 = descriptionObjs; _i < descriptionObjs_2.length; _i++) {
191
208
  var descriptionObj = descriptionObjs_2[_i];
192
- _loop_2(descriptionObj);
209
+ _loop_3(descriptionObj);
193
210
  }
194
211
  var orderedHeadings = orderDescriptionHeadings(Object.keys(combinedObj));
195
212
  // Build our description
196
213
  var description = '';
197
214
  orderedHeadings.forEach(function (key) {
198
- if (key === 'notes')
215
+ if (key === Headings.Notes)
199
216
  return;
200
- description += '\n# ' + key.charAt(0).toUpperCase() + key.slice(1) + '\n';
217
+ description += '\n# ' + key + '\n';
201
218
  Object.keys(combinedObj[key]).forEach(function (subKey) {
202
- if (key !== 'dependencies' && key !== 'testing')
203
- description += '\n## ' + subKey.charAt(0).toUpperCase() + subKey.slice(1) + '\n';
219
+ if (key !== Headings.Dependencies && key !== Headings.Testing)
220
+ description += '\n## ' + subKey + '\n';
204
221
  description += combinedObj[key][subKey];
205
222
  });
206
223
  });
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@clickview/ship-it",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "Release Manager",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
7
7
  "ship-it": "./lib/src/index.js"
8
8
  },
9
9
  "scripts": {
10
- "start": "npm run lint && ts-node --files src/index.ts",
10
+ "start": "npm run lint && ts-node --files src/index.ts",
11
11
  "build": "npm run lint && tsc -p . && tsc-alias -p tsconfig.json",
12
12
  "lint": "eslint . --ext .ts"
13
13
  },
@@ -21,6 +21,7 @@
21
21
  "@gitbeaker/node": "35.6.0",
22
22
  "chalk": "4.1.2",
23
23
  "commander": "9.1.0",
24
+ "fast-csv": "4.3.6",
24
25
  "fs-extra": "10.0.1",
25
26
  "inversify": "6.0.1",
26
27
  "lodash": "4.17.21",