@clickview/ship-it 0.0.7 → 0.0.9

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.
package/README.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Ship It
2
2
 
3
+ ## Introduction
4
+
5
+ "Ship It" is a CLI tool that was created to automate aspects of our release workflow.
6
+
7
+ ### How To Manage A Release
8
+
9
+ If you are here to learn how to manage a release, please see [this document](https://clickview.quip.com/DbEyAaVK8sqB/Release-Manager-Checklist) instead.
10
+
11
+ ### How To Contribute
12
+
13
+ If you are here instead of learn about or contribute to this project, then you're in the right place! Keep reading :)
14
+
3
15
  ## Prerequisites
4
16
 
5
17
  * NodeJS (and npm)
@@ -14,26 +26,23 @@ cd ship-it
14
26
  npm install
15
27
  ```
16
28
 
17
- After installation, you can run `npm run start -- help` for a list of Shit Commands.
18
-
19
- ## Commands
29
+ After installation, you can run `npm run start -- help` to see the full list of commands.
20
30
 
21
- The available commands are listed below. If you run into issues check that you have met all the [prerequisites](#prerequisites) first.
31
+ ## Contributing
22
32
 
23
- Note down the numeric project id from your project's homepage on GitLab - this will be useful for running some of the commands below.
33
+ ### Open Issues
24
34
 
25
- ### Status
35
+ All bugs / feature requests are tracked in the [issues](https://gitlab.cvinternal.net/clickview/front-end/ship-it/-/issues) section of this project.
26
36
 
27
- * Command: `npm run start -- status -m milestone [-p projectId]`
28
- * Example: `npm run start -- status -m T3 -p 887`
37
+ Anyone is free to pick up an issue and work on it at will! Don't be afraid, the TypeScript won't bite.
29
38
 
30
- Get the status of all MRs in a milestone. You can run this command at any time to check whether a miletone is ready for release. You can also limit the status check to a particular project.
39
+ ### Project Architecture
31
40
 
32
- ### Create Notes
41
+ Each CLI command is defined in the `startup/SetupCommands.ts` file.
33
42
 
34
- * Command: `npm run start -- create-notes -m milestone [-p projectId]`
35
- * Example: `npm run start -- create-notes -m U3 -p 887`
43
+ Each command maps to a particular TypeScript class in the `commands` directory.
44
+ These command classes typically just sequentially run a set of "tasks", where each "task" can be shared across different commands.
45
+ Each task also exists as a TypeScript class under the `tasks` directory.
36
46
 
37
- Generate release notes for all projects targeting a particular milestone. You can also pass in a `projectId` to generate notes for a single project only.
47
+ All code written in this project is intended to be highly reusable! If you are contributing a new command or updating an existing one, be sure to see if the code you're looking for already exists.
38
48
 
39
- The notes will be saved in a `dist` folder in markdown format.
@@ -155,6 +155,7 @@ var GitLabApiClient = /** @class */ (function () {
155
155
  id: projectId,
156
156
  name: release.name,
157
157
  tag_name: release.tag,
158
+ tag_message: release.milestones,
158
159
  description: release.description,
159
160
  ref: release.ref
160
161
  })];
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ var __generator = (this && this.__generator) || function (thisArg, body) {
24
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
25
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
26
+ function verb(n) { return function (v) { return step([n, v]); }; }
27
+ function step(op) {
28
+ if (f) throw new TypeError("Generator is already executing.");
29
+ while (_) try {
30
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
31
+ if (y = 0, t) op = [op[0] & 2, t.value];
32
+ switch (op[0]) {
33
+ case 0: case 1: t = op; break;
34
+ case 4: _.label++; return { value: op[1], done: false };
35
+ case 5: _.label++; y = op[1]; op = [0]; continue;
36
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
37
+ default:
38
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
39
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
40
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
41
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
42
+ if (t[2]) _.ops.pop();
43
+ _.trys.pop(); continue;
44
+ }
45
+ op = body.call(thisArg, _);
46
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
47
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
48
+ }
49
+ };
50
+ Object.defineProperty(exports, "__esModule", { value: true });
51
+ exports.ListProjectsCommand = void 0;
52
+ require("reflect-metadata");
53
+ var inversify_1 = require("inversify");
54
+ var types_1 = require("../types");
55
+ var ListProjectsCommand = /** @class */ (function () {
56
+ function ListProjectsCommand(listProjectsTask) {
57
+ this.listProjectsTask = listProjectsTask;
58
+ }
59
+ ListProjectsCommand.prototype.run = function () {
60
+ return __awaiter(this, void 0, void 0, function () {
61
+ return __generator(this, function (_a) {
62
+ switch (_a.label) {
63
+ case 0: return [4 /*yield*/, this.listProjectsTask.run()];
64
+ case 1: return [2 /*return*/, _a.sent()];
65
+ }
66
+ });
67
+ });
68
+ };
69
+ ListProjectsCommand = __decorate([
70
+ (0, inversify_1.injectable)(),
71
+ __param(0, (0, inversify_1.inject)(types_1.TASKS.ListProjectsTask)),
72
+ __metadata("design:paramtypes", [Object])
73
+ ], ListProjectsCommand);
74
+ return ListProjectsCommand;
75
+ }());
76
+ exports.ListProjectsCommand = ListProjectsCommand;
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./BumpPackagesCommand"), exports);
18
18
  __exportStar(require("./CreateBranchCommand"), exports);
19
19
  __exportStar(require("./CreateMergeRequestCommand"), exports);
20
+ __exportStar(require("./ListProjectsCommand"), exports);
20
21
  __exportStar(require("./CreateReleaseNotesCommand"), exports);
21
22
  __exportStar(require("./InstallPackagesCommand"), exports);
22
23
  __exportStar(require("./ReleaseCommand"), exports);
@@ -13,5 +13,6 @@ exports.CommandTypeMapping = {
13
13
  'bump-packages': types_1.COMMANDS.BumpPackagesCommand,
14
14
  'validate-mr': types_1.COMMANDS.ValidateMergeRequestCommand,
15
15
  'start-consuming-project-builds': types_1.COMMANDS.StartConsumingProjectBuildsCommand,
16
- 'tag-master': types_1.COMMANDS.TagMasterCommand
16
+ 'tag-master': types_1.COMMANDS.TagMasterCommand,
17
+ 'list-projects': types_1.COMMANDS.ListProjectsCommand
17
18
  };
@@ -31,14 +31,30 @@ exports.PROJECT_NAMES = {
31
31
  search: '936',
32
32
  videoviews: '835',
33
33
  domain: '108',
34
+ batch: '981',
35
+ discover: '934',
36
+ library: '1033',
37
+ krakend: '920',
38
+ webplayer: '262',
39
+ player: '917',
40
+ autocaptions: '852',
41
+ subject: '725',
42
+ subjects: '725',
43
+ filegen: '713',
44
+ filegenerator: '713',
45
+ object: '915',
46
+ objects: '915',
34
47
  classroom: '921',
35
48
  classrooms: '921',
36
49
  user: '914',
37
50
  users: '914',
38
51
  tvweb: '161',
39
52
  cloud247web: '161',
53
+ clients: '897',
54
+ goodstuff: '1002'
40
55
  },
41
56
  mobile: {
42
- android: '887'
57
+ android: '887',
58
+ interactiveforios: '395'
43
59
  }
44
60
  };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -23,3 +23,4 @@ __exportStar(require("./MergeRequestState"), exports);
23
23
  __exportStar(require("./ShipItCommand"), exports);
24
24
  __exportStar(require("./ShipItTask"), exports);
25
25
  __exportStar(require("./VersionType"), exports);
26
+ __exportStar(require("./ProjectNames"), exports);
@@ -41,6 +41,7 @@ function createContainer(config) {
41
41
  container.bind(types_1.TASKS.ValidateMergeRequestTask).to(tasks_1.ValidateMergeRequestTask);
42
42
  container.bind(types_1.TASKS.StartMonorepoBuildTask).to(tasks_1.StartMonorepoBuildTask);
43
43
  container.bind(types_1.TASKS.TagMasterTask).to(tasks_1.TagMasterTask);
44
+ container.bind(types_1.TASKS.ListProjectsTask).to(tasks_1.ListProjectsTask);
44
45
  container.bind(types_1.TASKS.StartConsumingProjectBuildsTask)
45
46
  .to(tasks_1.StartConsumingProjectBuildsTask);
46
47
  /**
@@ -56,6 +57,7 @@ function createContainer(config) {
56
57
  container.bind(types_1.COMMANDS.BumpPackagesCommand).to(commands_1.BumpPackagesCommand);
57
58
  container.bind(types_1.COMMANDS.ValidateMergeRequestCommand).to(commands_1.ValidateMergeRequestCommand);
58
59
  container.bind(types_1.COMMANDS.TagMasterCommand).to(commands_1.TagMasterCommand);
60
+ container.bind(types_1.COMMANDS.ListProjectsCommand).to(commands_1.ListProjectsCommand);
59
61
  container.bind(types_1.COMMANDS.StartConsumingProjectBuildsCommand)
60
62
  .to(commands_1.StartConsumingProjectBuildsCommand);
61
63
  return container;
@@ -205,19 +205,20 @@ var GitLabService = /** @class */ (function () {
205
205
  };
206
206
  GitLabService.prototype.getDevCommitsSince = function (projectId, sinceSha) {
207
207
  return __awaiter(this, void 0, void 0, function () {
208
- var commits, lastDevCommit, title;
208
+ var commits, mergeCommitIndex;
209
209
  return __generator(this, function (_a) {
210
210
  switch (_a.label) {
211
211
  case 0: return [4 /*yield*/, this.apiClient.getCommitsSince(projectId, 'dev', sinceSha)];
212
212
  case 1:
213
213
  commits = _a.sent();
214
- lastDevCommit = lodash_1.default.last(commits);
215
- title = lastDevCommit === null || lastDevCommit === void 0 ? void 0 : lastDevCommit.title.toLowerCase();
216
- if ((title === null || title === void 0 ? void 0 : title.includes('merge')) &&
217
- (title === null || title === void 0 ? void 0 : title.includes('master')) &&
218
- (title === null || title === void 0 ? void 0 : title.includes('dev'))) {
219
- commits.pop();
220
- }
214
+ mergeCommitIndex = commits.findIndex(function (commit) {
215
+ var title = commit.title.toLowerCase();
216
+ return title.includes('merge') &&
217
+ title.includes('master') &&
218
+ title.includes('dev');
219
+ });
220
+ if (mergeCommitIndex > -1)
221
+ commits.splice(mergeCommitIndex, 1);
221
222
  /**
222
223
  * This is commented out right now because of a problem with the logic of this approach of validating MRs.
223
224
  * We need to find a way to fetch all commits that will be included in this release. Leaving this commented
@@ -119,5 +119,8 @@ function setupCommands(program, container) {
119
119
  }
120
120
  });
121
121
  }); });
122
+ program.command('list-projects')
123
+ .description('Displays a list of all project names that can be used with the -p argument')
124
+ .action(getAction('list-projects'));
122
125
  }
123
126
  exports.setupCommands = setupCommands;
@@ -54,6 +54,7 @@ var inversify_1 = require("inversify");
54
54
  var Logger_1 = require("../utils/Logger");
55
55
  var types_1 = require("../types");
56
56
  var services_1 = require("../services");
57
+ var constants_1 = require("../constants");
57
58
  var BumpVersionTxtTask = /** @class */ (function () {
58
59
  function BumpVersionTxtTask(service) {
59
60
  this.service = service;
@@ -73,6 +74,8 @@ var BumpVersionTxtTask = /** @class */ (function () {
73
74
  case 2:
74
75
  if (!(_i < projects_1.length)) return [3 /*break*/, 6];
75
76
  project = projects_1[_i];
77
+ if (this.skip(project.id))
78
+ return [2 /*return*/, false];
76
79
  return [4 /*yield*/, this.service.getNextBranchInfo(project.id, options.version)];
77
80
  case 3:
78
81
  _a = _b.sent(), nextVersion = _a.nextVersion, branchName = _a.branchName;
@@ -92,6 +95,11 @@ var BumpVersionTxtTask = /** @class */ (function () {
92
95
  });
93
96
  });
94
97
  };
98
+ BumpVersionTxtTask.prototype.skip = function (projectId) {
99
+ // These projects need to be bumped after master merge back to dev. So we skip them here.
100
+ var skipProjectIds = [constants_1.PROJECT_NAMES.backend.clients, constants_1.PROJECT_NAMES.backend.goodstuff];
101
+ return (skipProjectIds.some(function (id) { return id === projectId.toString(); }));
102
+ };
95
103
  BumpVersionTxtTask = __decorate([
96
104
  (0, inversify_1.injectable)(),
97
105
  __param(0, (0, inversify_1.inject)(types_1.SERVICES.GitLabService)),
@@ -74,7 +74,6 @@ var CreateReleaseNotesTask = /** @class */ (function () {
74
74
  case 1:
75
75
  projects = _a.sent();
76
76
  combinedDescription = '';
77
- utils_1.Logger.logMessage('Created files');
78
77
  _i = 0, projects_1 = projects;
79
78
  _a.label = 2;
80
79
  case 2:
@@ -94,7 +93,6 @@ var CreateReleaseNotesTask = /** @class */ (function () {
94
93
  return [4 /*yield*/, fs_extra_1.default.outputFile(path_1.default.resolve(outputPath_1), description)];
95
94
  case 3:
96
95
  _a.sent();
97
- utils_1.Logger.logInfo('- ' + outputPath_1);
98
96
  _a.label = 4;
99
97
  case 4:
100
98
  _i++;
@@ -104,7 +102,8 @@ var CreateReleaseNotesTask = /** @class */ (function () {
104
102
  return [4 /*yield*/, fs_extra_1.default.outputFile(path_1.default.resolve(outputPath), combinedDescription)];
105
103
  case 6:
106
104
  _a.sent();
107
- utils_1.Logger.logInfo('- ' + outputPath);
105
+ utils_1.Logger.logMessage('Created file');
106
+ utils_1.Logger.logInfo("".concat(path_1.default.resolve(outputPath), "\n"));
108
107
  return [2 /*return*/, true];
109
108
  }
110
109
  });
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ var __generator = (this && this.__generator) || function (thisArg, body) {
18
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
19
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
20
+ function verb(n) { return function (v) { return step([n, v]); }; }
21
+ function step(op) {
22
+ if (f) throw new TypeError("Generator is already executing.");
23
+ while (_) try {
24
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
25
+ if (y = 0, t) op = [op[0] & 2, t.value];
26
+ switch (op[0]) {
27
+ case 0: case 1: t = op; break;
28
+ case 4: _.label++; return { value: op[1], done: false };
29
+ case 5: _.label++; y = op[1]; op = [0]; continue;
30
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
31
+ default:
32
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
33
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
34
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
35
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
36
+ if (t[2]) _.ops.pop();
37
+ _.trys.pop(); continue;
38
+ }
39
+ op = body.call(thisArg, _);
40
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
41
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
42
+ }
43
+ };
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.ListProjectsTask = void 0;
49
+ var lodash_1 = __importDefault(require("lodash"));
50
+ require("reflect-metadata");
51
+ var inversify_1 = require("inversify");
52
+ var utils_1 = require("../utils");
53
+ var constants_1 = require("../constants");
54
+ var ListProjectsTask = /** @class */ (function () {
55
+ function ListProjectsTask() {
56
+ }
57
+ ListProjectsTask.prototype.run = function () {
58
+ return __awaiter(this, void 0, void 0, function () {
59
+ return __generator(this, function (_a) {
60
+ utils_1.Logger.logTask('Listing projects');
61
+ this.logAvailableProjects(constants_1.PROJECT_NAMES);
62
+ utils_1.Logger.logSuccess("Available project names are listed above to be used for -p arg\n");
63
+ return [2 /*return*/, true];
64
+ });
65
+ });
66
+ };
67
+ ListProjectsTask.prototype.logAvailableProjects = function (projectNames) {
68
+ for (var _i = 0, _a = Object.keys(projectNames); _i < _a.length; _i++) {
69
+ var key = _a[_i];
70
+ var groupTitle = "".concat(lodash_1.default.capitalize(key), " project names:");
71
+ this.logProjectsByGroup(groupTitle, projectNames[key]);
72
+ }
73
+ };
74
+ ListProjectsTask.prototype.logProjectsByGroup = function (groupName, projectInfo) {
75
+ utils_1.Logger.logMessage(groupName);
76
+ for (var _i = 0, _a = Object.keys(projectInfo); _i < _a.length; _i++) {
77
+ var key = _a[_i];
78
+ utils_1.Logger.logInfo(key);
79
+ }
80
+ utils_1.Logger.logInfo('');
81
+ };
82
+ ListProjectsTask = __decorate([
83
+ (0, inversify_1.injectable)()
84
+ ], ListProjectsTask);
85
+ return ListProjectsTask;
86
+ }());
87
+ exports.ListProjectsTask = ListProjectsTask;
@@ -24,6 +24,7 @@ __exportStar(require("./InstallPackagesTask"), exports);
24
24
  __exportStar(require("./StartConsumingProjectBuildsTask"), exports);
25
25
  __exportStar(require("./StartMonorepoBuildTask"), exports);
26
26
  __exportStar(require("./TagMasterTask"), exports);
27
+ __exportStar(require("./ListProjectsTask"), exports);
27
28
  __exportStar(require("./ValidateCommitsTask"), exports);
28
29
  __exportStar(require("./ValidateDescriptionsTask"), exports);
29
30
  __exportStar(require("./ValidateMergeRequestTask"), exports);
package/lib/src/types.js CHANGED
@@ -28,7 +28,8 @@ exports.TASKS = {
28
28
  ValidateMergeRequestTask: Symbol.for('ValidateMergeRequestTask'),
29
29
  StartMonorepoBuildTask: Symbol.for('StartMonorepoBuildTask'),
30
30
  StartConsumingProjectBuildsTask: Symbol.for('StartConsumingProjectBuildsTask'),
31
- TagMasterTask: Symbol.for('TagMasterTask')
31
+ TagMasterTask: Symbol.for('TagMasterTask'),
32
+ ListProjectsTask: Symbol.for('ListProjectsTask')
32
33
  };
33
34
  exports.COMMANDS = {
34
35
  StatusCommand: Symbol.for('StatusCommand'),
@@ -41,5 +42,6 @@ exports.COMMANDS = {
41
42
  BumpPackagesCommand: Symbol.for('BumpPackagesCommand'),
42
43
  ValidateMergeRequestCommand: Symbol.for('ValidateMergeRequestCommand'),
43
44
  StartConsumingProjectBuildsCommand: Symbol.for('StartConsumingProjectBuildsCommand'),
44
- TagMasterCommand: Symbol.for('TagMasterCommand')
45
+ TagMasterCommand: Symbol.for('TagMasterCommand'),
46
+ ListProjectsCommand: Symbol.for('ListProjectsCommand')
45
47
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clickview/ship-it",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Release Manager",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {