UNPKG

47.4 kBJavaScriptView Raw
1"use strict";
2var __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};
13var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14 return new (P || (P = Promise))(function (resolve, reject) {
15 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
18 step((generator = generator.apply(thisArg, _arguments || [])).next());
19 });
20};
21var __generator = (this && this.__generator) || function (thisArg, body) {
22 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24 function verb(n) { return function (v) { return step([n, v]); }; }
25 function step(op) {
26 if (f) throw new TypeError("Generator is already executing.");
27 while (_) try {
28 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;
29 if (y = 0, t) op = [op[0] & 2, t.value];
30 switch (op[0]) {
31 case 0: case 1: t = op; break;
32 case 4: _.label++; return { value: op[1], done: false };
33 case 5: _.label++; y = op[1]; op = [0]; continue;
34 case 7: op = _.ops.pop(); _.trys.pop(); continue;
35 default:
36 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40 if (t[2]) _.ops.pop();
41 _.trys.pop(); continue;
42 }
43 op = body.call(thisArg, _);
44 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46 }
47};
48var __rest = (this && this.__rest) || function (s, e) {
49 var t = {};
50 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
51 t[p] = s[p];
52 if (s != null && typeof Object.getOwnPropertySymbols === "function")
53 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
54 t[p[i]] = s[p[i]];
55 return t;
56};
57var __read = (this && this.__read) || function (o, n) {
58 var m = typeof Symbol === "function" && o[Symbol.iterator];
59 if (!m) return o;
60 var i = m.call(o), r, ar = [], e;
61 try {
62 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
63 }
64 catch (error) { e = { error: error }; }
65 finally {
66 try {
67 if (r && !r.done && (m = i["return"])) m.call(i);
68 }
69 finally { if (e) throw e.error; }
70 }
71 return ar;
72};
73var __spread = (this && this.__spread) || function () {
74 for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
75 return ar;
76};
77var __importDefault = (this && this.__importDefault) || function (mod) {
78 return (mod && mod.__esModule) ? mod : { "default": mod };
79};
80var __importStar = (this && this.__importStar) || function (mod) {
81 if (mod && mod.__esModule) return mod;
82 var result = {};
83 if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
84 result["default"] = mod;
85 return result;
86};
87Object.defineProperty(exports, "__esModule", { value: true });
88var dotenv_1 = __importDefault(require("dotenv"));
89var env_ci_1 = __importDefault(require("env-ci"));
90var fs_1 = __importDefault(require("fs"));
91var path_1 = __importDefault(require("path"));
92var semver_1 = require("semver");
93var config_1 = __importDefault(require("./config"));
94var git_1 = __importDefault(require("./git"));
95var init_1 = __importDefault(require("./init"));
96var main_1 = require("./main");
97var release_1 = __importStar(require("./release"));
98var semver_2 = __importStar(require("./semver"));
99var github_token_1 = __importDefault(require("./utils/github-token"));
100var load_plugins_1 = __importDefault(require("./utils/load-plugins"));
101var logger_1 = __importDefault(require("./utils/logger"));
102var make_hooks_1 = require("./utils/make-hooks");
103var env = env_ci_1.default();
104var loadEnv = function () {
105 var envFile = path_1.default.resolve(process.cwd(), '.env');
106 if (!fs_1.default.existsSync(envFile)) {
107 return;
108 }
109 var envConfig = dotenv_1.default.parse(fs_1.default.readFileSync(envFile));
110 Object.entries(envConfig).forEach(function (_a) {
111 var _b = __read(_a, 2), key = _b[0], value = _b[1];
112 process.env[key] = value;
113 });
114};
115var Auto = /** @class */ (function () {
116 function Auto(args) {
117 var _this = this;
118 this.prefixRelease = function (release) {
119 if (!_this.release) {
120 throw _this.createErrorMessage();
121 }
122 return _this.release.options.noVersionPrefix || release.startsWith('v')
123 ? release
124 : "v" + release;
125 };
126 this.args = args;
127 this.baseBranch = args.baseBranch || 'master';
128 this.logger = logger_1.default(args.veryVerbose ? 'veryVerbose' : args.verbose ? 'verbose' : undefined);
129 this.hooks = make_hooks_1.makeHooks();
130 this.hooks.onCreateRelease.tap('Link onCreateChangelog', function (release) {
131 release.hooks.onCreateChangelog.tap('Link onCreateChangelog', function (changelog) {
132 _this.hooks.onCreateChangelog.call(changelog);
133 });
134 });
135 this.hooks.onCreateRelease.tap('Link onCreateLogParse', function (release) {
136 release.hooks.onCreateLogParse.tap('Link onCreateLogParse', function (logParse) {
137 _this.hooks.onCreateLogParse.call(logParse);
138 });
139 });
140 loadEnv();
141 }
142 /**
143 * Load the .autorc from the file system, set up defaults, combine with CLI args
144 * load the extends property, load the plugins and start the git remote interface.
145 */
146 Auto.prototype.loadConfig = function () {
147 return __awaiter(this, void 0, void 0, function () {
148 var configLoader, config, _a, _b, _c, repository, token, _d, githubOptions;
149 return __generator(this, function (_e) {
150 switch (_e.label) {
151 case 0:
152 configLoader = new config_1.default(this.logger);
153 _b = (_a = this.hooks.modifyConfig).call;
154 _c = [{}];
155 return [4 /*yield*/, configLoader.loadConfig(this.args)];
156 case 1:
157 config = _b.apply(_a, [__assign.apply(void 0, _c.concat([(_e.sent()), { baseBranch: this.baseBranch }]))]);
158 this.logger.verbose.success('Loaded `auto` with config:', config);
159 this.config = config;
160 this.labels = config.labels;
161 this.semVerLabels = release_1.getVersionMap(config.labels);
162 this.loadPlugins(config);
163 this.hooks.beforeRun.call(config);
164 return [4 /*yield*/, this.getRepo(config)];
165 case 2:
166 repository = _e.sent();
167 if (!(repository && repository.token)) return [3 /*break*/, 3];
168 _d = repository.token;
169 return [3 /*break*/, 5];
170 case 3: return [4 /*yield*/, github_token_1.default(config.githubApi)];
171 case 4:
172 _d = _e.sent();
173 _e.label = 5;
174 case 5:
175 token = _d;
176 githubOptions = __assign({ owner: config.owner, repo: config.repo }, repository, { token: token, baseUrl: config.githubApi || 'https://api.github.com', graphqlBaseUrl: config.githubGraphqlApi || config.githubApi || 'https://api.github.com' });
177 this.git = this.startGit(githubOptions);
178 this.release = new release_1.default(this.git, config, this.logger);
179 this.hooks.onCreateRelease.call(this.release);
180 return [2 /*return*/];
181 }
182 });
183 });
184 };
185 /**
186 * Interactive prompt for initializing an .autorc
187 */
188 Auto.prototype.init = function (options) {
189 if (options === void 0) { options = {}; }
190 return __awaiter(this, void 0, void 0, function () {
191 return __generator(this, function (_a) {
192 switch (_a.label) {
193 case 0: return [4 /*yield*/, init_1.default(options, this.logger)];
194 case 1:
195 _a.sent();
196 return [2 /*return*/];
197 }
198 });
199 });
200 };
201 /**
202 * Create all of the user's labels on the git remote if the don't already exist
203 *
204 * @param options Options for the createLabels functionality
205 */
206 Auto.prototype.createLabels = function (options) {
207 if (options === void 0) { options = {}; }
208 return __awaiter(this, void 0, void 0, function () {
209 return __generator(this, function (_a) {
210 switch (_a.label) {
211 case 0:
212 if (!this.release || !this.labels) {
213 throw this.createErrorMessage();
214 }
215 return [4 /*yield*/, this.release.addLabelsToProject(this.labels, options)];
216 case 1:
217 _a.sent();
218 return [2 /*return*/];
219 }
220 });
221 });
222 };
223 /**
224 * Get the labels on a specific PR. Defaults to the labels of the last merged PR
225 *
226 * @param options Options for the createLabels functionality
227 */
228 Auto.prototype.label = function (_a) {
229 var pr = (_a === void 0 ? {} : _a).pr;
230 return __awaiter(this, void 0, void 0, function () {
231 var labels, pulls, lastMerged;
232 return __generator(this, function (_b) {
233 switch (_b.label) {
234 case 0:
235 if (!this.git) {
236 throw this.createErrorMessage();
237 }
238 this.logger.verbose.info("Using command: 'label'");
239 labels = [];
240 if (!!pr) return [3 /*break*/, 2];
241 return [4 /*yield*/, this.git.getPullRequests({
242 state: 'closed'
243 })];
244 case 1:
245 pulls = _b.sent();
246 lastMerged = pulls
247 .sort(function (a, b) {
248 return new Date(b.merged_at).getTime() - new Date(a.merged_at).getTime();
249 })
250 .find(function (pull) { return !!pull.merged_at; });
251 if (lastMerged) {
252 labels = lastMerged.labels.map(function (label) { return label.name; });
253 }
254 return [3 /*break*/, 4];
255 case 2: return [4 /*yield*/, this.git.getLabels(pr)];
256 case 3:
257 labels = _b.sent();
258 _b.label = 4;
259 case 4:
260 if (labels.length) {
261 console.log(labels.join('\n'));
262 }
263 return [2 /*return*/];
264 }
265 });
266 });
267 };
268 /**
269 * Create a status on a PR.
270 *
271 * @param options Options for the pr status functionality
272 */
273 Auto.prototype.pr = function (_a) {
274 var dryRun = _a.dryRun, pr = _a.pr, url = _a.url, options = __rest(_a, ["dryRun", "pr", "url"]);
275 return __awaiter(this, void 0, void 0, function () {
276 var sha, prNumber, res, target_url, error_1;
277 return __generator(this, function (_b) {
278 switch (_b.label) {
279 case 0:
280 if (!this.git) {
281 throw this.createErrorMessage();
282 }
283 sha = options.sha;
284 try {
285 prNumber = this.getPrNumber('pr', pr);
286 }
287 catch (error) {
288 // default to sha if no PR found
289 }
290 this.logger.verbose.info("Using command: 'pr'");
291 if (!(!sha && prNumber)) return [3 /*break*/, 2];
292 this.logger.verbose.info('Getting commit SHA from PR.');
293 return [4 /*yield*/, this.git.getPullRequest(prNumber)];
294 case 1:
295 res = _b.sent();
296 sha = res.data.head.sha;
297 return [3 /*break*/, 4];
298 case 2:
299 if (!!sha) return [3 /*break*/, 4];
300 this.logger.verbose.info('No PR found, getting commit SHA from HEAD.');
301 return [4 /*yield*/, this.git.getSha()];
302 case 3:
303 sha = _b.sent();
304 _b.label = 4;
305 case 4:
306 this.logger.verbose.info('Found PR SHA:', sha);
307 target_url = url;
308 if (!!dryRun) return [3 /*break*/, 9];
309 _b.label = 5;
310 case 5:
311 _b.trys.push([5, 7, , 8]);
312 return [4 /*yield*/, this.git.createStatus(__assign({}, options, { sha: sha,
313 target_url: target_url }))];
314 case 6:
315 _b.sent();
316 return [3 /*break*/, 8];
317 case 7:
318 error_1 = _b.sent();
319 throw new Error("Failed to post status to Pull Request with error code " + error_1.status);
320 case 8:
321 this.logger.log.success('Posted status to Pull Request.');
322 return [3 /*break*/, 10];
323 case 9:
324 this.logger.verbose.info('`pr` dry run complete.');
325 _b.label = 10;
326 case 10:
327 this.logger.verbose.success('Finished `pr` command');
328 return [2 /*return*/];
329 }
330 });
331 });
332 };
333 /**
334 * Check that a PR has a SEMVER label. Set a success status on the PR.
335 *
336 * @param options Options for the pr check functionality
337 */
338 Auto.prototype.prCheck = function (_a) {
339 var dryRun = _a.dryRun, pr = _a.pr, url = _a.url, options = __rest(_a, ["dryRun", "pr", "url"]);
340 return __awaiter(this, void 0, void 0, function () {
341 var target_url, prNumber, msg, sha, res, labels, labelTexts_1, releaseTag, skipReleaseTag, semverTag, description, error_2, error_3;
342 var _this = this;
343 return __generator(this, function (_b) {
344 switch (_b.label) {
345 case 0:
346 if (!this.git || !this.release || !this.semVerLabels) {
347 throw this.createErrorMessage();
348 }
349 this.logger.verbose.info("Using command: 'pr-check' for '" + url + "'");
350 target_url = url;
351 prNumber = this.getPrNumber('prCheck', pr);
352 _b.label = 1;
353 case 1:
354 _b.trys.push([1, 4, , 5]);
355 return [4 /*yield*/, this.git.getPullRequest(prNumber)];
356 case 2:
357 res = _b.sent();
358 sha = res.data.head.sha;
359 return [4 /*yield*/, this.git.getLabels(prNumber)];
360 case 3:
361 labels = _b.sent();
362 labelTexts_1 = __spread(this.semVerLabels.values());
363 releaseTag = labels.find(function (l) { return l === 'release'; });
364 skipReleaseTag = labels.find(function (l) {
365 return !!_this.release && _this.release.options.skipReleaseLabels.includes(l);
366 });
367 semverTag = labels.find(function (l) {
368 return labelTexts_1.includes(l) &&
369 !!_this.release &&
370 !_this.release.options.skipReleaseLabels.includes(l) &&
371 l !== 'release';
372 });
373 if (semverTag === undefined && !skipReleaseTag) {
374 throw new Error('No semver label!');
375 }
376 this.logger.log.success("PR is using label: " + semverTag);
377 description = void 0;
378 if (skipReleaseTag) {
379 description = 'PR will not create a release';
380 }
381 else if (releaseTag) {
382 description = "PR will create release once merged - " + semverTag;
383 }
384 else {
385 description = "CI - " + semverTag;
386 }
387 msg = {
388 description: description,
389 state: 'success'
390 };
391 return [3 /*break*/, 5];
392 case 4:
393 error_2 = _b.sent();
394 msg = {
395 description: error_2.message,
396 state: 'error'
397 };
398 return [3 /*break*/, 5];
399 case 5:
400 this.logger.verbose.info('Posting status to GitHub\n', msg);
401 if (!!dryRun) return [3 /*break*/, 10];
402 _b.label = 6;
403 case 6:
404 _b.trys.push([6, 8, , 9]);
405 return [4 /*yield*/, this.git.createStatus(__assign({}, options, msg, { target_url: target_url,
406 sha: sha }))];
407 case 7:
408 _b.sent();
409 this.logger.log.success('Posted status to Pull Request.');
410 return [3 /*break*/, 9];
411 case 8:
412 error_3 = _b.sent();
413 throw new Error("Failed to post status to Pull Request with error code " + error_3.status);
414 case 9: return [3 /*break*/, 11];
415 case 10:
416 this.logger.verbose.info('`pr-check` dry run complete.');
417 _b.label = 11;
418 case 11:
419 this.logger.verbose.success('Finished `pr-check` command');
420 return [2 /*return*/];
421 }
422 });
423 });
424 };
425 /**
426 * Comment on a PR. Only one comment will be present on the PR, Older comments are removed.
427 * You can use the "context" option to multiple comments on a PR.
428 *
429 * @param options Options for the comment functionality
430 */
431 Auto.prototype.comment = function (_a) {
432 var message = _a.message, pr = _a.pr, _b = _a.context, context = _b === void 0 ? 'default' : _b, dryRun = _a.dryRun;
433 return __awaiter(this, void 0, void 0, function () {
434 var prNumber;
435 return __generator(this, function (_c) {
436 switch (_c.label) {
437 case 0:
438 if (!this.git) {
439 throw this.createErrorMessage();
440 }
441 this.logger.verbose.info("Using command: 'comment'");
442 if (!dryRun) return [3 /*break*/, 1];
443 this.logger.log.info("Would have commented on " + pr + " under \"" + context + "\" context:\n\n" + message);
444 return [3 /*break*/, 3];
445 case 1:
446 prNumber = this.getPrNumber('comment', pr);
447 return [4 /*yield*/, this.git.createComment(message, prNumber, context)];
448 case 2:
449 _c.sent();
450 this.logger.log.success("Commented on PR #" + pr);
451 _c.label = 3;
452 case 3: return [2 /*return*/];
453 }
454 });
455 });
456 };
457 /**
458 * Update the body of a PR with a message. Only one message will be present in the PR,
459 * Older messages are removed. You can use the "context" option to multiple message
460 * in a PR body.
461 *
462 * @param options Options
463 */
464 Auto.prototype.prBody = function (_a) {
465 var message = _a.message, pr = _a.pr, _b = _a.context, context = _b === void 0 ? 'default' : _b, dryRun = _a.dryRun;
466 return __awaiter(this, void 0, void 0, function () {
467 var prNumber;
468 return __generator(this, function (_c) {
469 switch (_c.label) {
470 case 0:
471 if (!this.git) {
472 throw this.createErrorMessage();
473 }
474 this.logger.verbose.info("Using command: 'pr-body'");
475 if (!dryRun) return [3 /*break*/, 1];
476 this.logger.log.info("Would have appended to PR body on " + pr + " under \"" + context + "\" context:\n\n" + message);
477 return [3 /*break*/, 3];
478 case 1:
479 prNumber = this.getPrNumber('pr-body', pr);
480 return [4 /*yield*/, this.git.addToPrBody(message, prNumber, context)];
481 case 2:
482 _c.sent();
483 this.logger.log.success("Updated body on PR #" + pr);
484 _c.label = 3;
485 case 3: return [2 /*return*/];
486 }
487 });
488 });
489 };
490 /**
491 * Calculate the version bump for the current state of the repository.
492 */
493 Auto.prototype.version = function () {
494 return __awaiter(this, void 0, void 0, function () {
495 var bump;
496 return __generator(this, function (_a) {
497 switch (_a.label) {
498 case 0:
499 this.logger.verbose.info("Using command: 'version'");
500 return [4 /*yield*/, this.getVersion()];
501 case 1:
502 bump = _a.sent();
503 console.log(bump);
504 return [2 /*return*/];
505 }
506 });
507 });
508 };
509 /**
510 * Calculate the the changelog and commit it.
511 */
512 Auto.prototype.changelog = function (options) {
513 return __awaiter(this, void 0, void 0, function () {
514 return __generator(this, function (_a) {
515 switch (_a.label) {
516 case 0:
517 this.logger.verbose.info("Using command: 'changelog'");
518 return [4 /*yield*/, this.makeChangelog(options)];
519 case 1:
520 _a.sent();
521 return [2 /*return*/];
522 }
523 });
524 });
525 };
526 /**
527 * Make a release to the git remote with the changes.
528 */
529 Auto.prototype.runRelease = function (options) {
530 return __awaiter(this, void 0, void 0, function () {
531 return __generator(this, function (_a) {
532 switch (_a.label) {
533 case 0:
534 this.logger.verbose.info("Using command: 'release'");
535 return [4 /*yield*/, this.makeRelease(options)];
536 case 1:
537 _a.sent();
538 return [2 /*return*/];
539 }
540 });
541 });
542 };
543 Auto.prototype.canary = function (options) {
544 if (options === void 0) { options = {}; }
545 return __awaiter(this, void 0, void 0, function () {
546 var preId, build, head, labels, version, canaryVersion, _a, newVersion, result, message, latestTag, commitsInRelease;
547 return __generator(this, function (_b) {
548 switch (_b.label) {
549 case 0:
550 if (!this.git || !this.release) {
551 throw this.createErrorMessage();
552 }
553 if ('pr' in env && 'build' in env) {
554 preId = env.pr;
555 (build = env.build);
556 }
557 else if ('pr' in env && 'commit' in env) {
558 preId = env.pr;
559 build = env.commit;
560 }
561 preId = options.pr ? String(options.pr) : preId;
562 build = options.build ? String(options.build) : build;
563 return [4 /*yield*/, this.release.getCommitsInRelease('HEAD^')];
564 case 1:
565 head = _b.sent();
566 labels = head.map(function (commit) { return commit.labels; });
567 version = semver_2.calculateSemVerBump(labels, this.semVerLabels, this.config) ||
568 semver_2.default.patch;
569 canaryVersion = '';
570 if (preId) {
571 canaryVersion = canaryVersion + "." + preId;
572 }
573 if (build) {
574 canaryVersion = canaryVersion + "." + build;
575 }
576 if (!!('isPr' in env)) return [3 /*break*/, 3];
577 _a = canaryVersion + ".";
578 return [4 /*yield*/, this.git.getSha(true)];
579 case 2:
580 canaryVersion = _a + (_b.sent());
581 _b.label = 3;
582 case 3:
583 newVersion = '';
584 if (!options.dryRun) return [3 /*break*/, 4];
585 this.logger.log.warn("Published canary identifier would be: \"-canary" + canaryVersion + "\"");
586 return [3 /*break*/, 6];
587 case 4:
588 this.logger.verbose.info('Calling canary hook');
589 return [4 /*yield*/, this.hooks.canary.promise(version, canaryVersion)];
590 case 5:
591 result = _b.sent();
592 if (typeof result === 'object') {
593 this.logger.log.error(result.error);
594 return [2 /*return*/];
595 }
596 newVersion = result;
597 message = options.message || 'Published PR with canary version: `%v`';
598 if (message !== 'false' && env.isCi) {
599 this.prBody({
600 message: message.replace('%v', newVersion),
601 context: 'canary-version'
602 });
603 }
604 this.logger.log.success("Published canary version" + (newVersion ? ": " + newVersion : ''));
605 _b.label = 6;
606 case 6: return [4 /*yield*/, this.git.getLatestTagInBranch()];
607 case 7:
608 latestTag = _b.sent();
609 return [4 /*yield*/, this.release.getCommits(latestTag)];
610 case 8:
611 commitsInRelease = _b.sent();
612 return [2 /*return*/, { newVersion: newVersion, commitsInRelease: commitsInRelease }];
613 }
614 });
615 });
616 };
617 /**
618 * Run the full workflow.
619 *
620 * 1. Calculate version
621 * 2. Make changelog
622 * 3. Publish code
623 * 4. Create a release
624 */
625 Auto.prototype.shipit = function (options) {
626 if (options === void 0) { options = {}; }
627 return __awaiter(this, void 0, void 0, function () {
628 var isPR, isBaseBranch, publishInfo, _a, newVersion, commitsInRelease;
629 return __generator(this, function (_b) {
630 switch (_b.label) {
631 case 0:
632 if (!this.git || !this.release) {
633 throw this.createErrorMessage();
634 }
635 this.logger.verbose.info("Using command: 'shipit'");
636 this.hooks.beforeShipIt.call();
637 isPR = 'isPr' in env && env.isPr;
638 isBaseBranch = !isPR && 'branch' in env && env.branch === this.baseBranch;
639 if (!isBaseBranch) return [3 /*break*/, 2];
640 return [4 /*yield*/, this.publishLatest(options)];
641 case 1:
642 _a = _b.sent();
643 return [3 /*break*/, 4];
644 case 2: return [4 /*yield*/, this.canary(options)];
645 case 3:
646 _a = _b.sent();
647 _b.label = 4;
648 case 4:
649 publishInfo = _a;
650 if (!publishInfo) {
651 return [2 /*return*/];
652 }
653 newVersion = publishInfo.newVersion, commitsInRelease = publishInfo.commitsInRelease;
654 return [4 /*yield*/, this.hooks.afterShipIt.promise(newVersion, commitsInRelease)];
655 case 5:
656 _b.sent();
657 return [2 /*return*/];
658 }
659 });
660 });
661 };
662 Auto.prototype.getCurrentVersion = function (lastRelease) {
663 return __awaiter(this, void 0, void 0, function () {
664 var lastVersion;
665 var _this = this;
666 return __generator(this, function (_a) {
667 switch (_a.label) {
668 case 0:
669 this.hooks.getPreviousVersion.tap('None', function () {
670 _this.logger.veryVerbose.info('No previous release found, using 0.0.0 as previous version.');
671 return _this.prefixRelease('0.0.0');
672 });
673 return [4 /*yield*/, this.hooks.getPreviousVersion.promise(this.prefixRelease)];
674 case 1:
675 lastVersion = _a.sent();
676 if (semver_1.parse(lastRelease) &&
677 semver_1.parse(lastVersion) &&
678 semver_1.gt(lastRelease, lastVersion)) {
679 this.logger.veryVerbose.info('Using latest release as previous version');
680 return [2 /*return*/, lastRelease];
681 }
682 return [2 /*return*/, lastVersion];
683 }
684 });
685 });
686 };
687 Auto.prototype.publishLatest = function (options) {
688 return __awaiter(this, void 0, void 0, function () {
689 var version, lastRelease, commitsInRelease, newVersion, current;
690 return __generator(this, function (_a) {
691 switch (_a.label) {
692 case 0:
693 if (!this.git || !this.release) {
694 throw this.createErrorMessage();
695 }
696 return [4 /*yield*/, this.getVersion()];
697 case 1:
698 version = _a.sent();
699 if (version === '') {
700 this.logger.log.info('No version published.');
701 return [2 /*return*/];
702 }
703 return [4 /*yield*/, this.git.getLatestRelease()];
704 case 2:
705 lastRelease = _a.sent();
706 return [4 /*yield*/, this.release.getCommitsInRelease(lastRelease)];
707 case 3:
708 commitsInRelease = _a.sent();
709 return [4 /*yield*/, this.makeChangelog(options)];
710 case 4:
711 _a.sent();
712 if (!!options.dryRun) return [3 /*break*/, 9];
713 this.logger.verbose.info('Calling version hook');
714 return [4 /*yield*/, this.hooks.version.promise(version)];
715 case 5:
716 _a.sent();
717 this.logger.verbose.info('Calling after version hook');
718 return [4 /*yield*/, this.hooks.afterVersion.promise()];
719 case 6:
720 _a.sent();
721 this.logger.verbose.info('Calling publish hook');
722 return [4 /*yield*/, this.hooks.publish.promise(version)];
723 case 7:
724 _a.sent();
725 this.logger.verbose.info('Calling after publish hook');
726 return [4 /*yield*/, this.hooks.afterPublish.promise()];
727 case 8:
728 _a.sent();
729 _a.label = 9;
730 case 9: return [4 /*yield*/, this.makeRelease(options)];
731 case 10:
732 newVersion = _a.sent();
733 if (!options.dryRun) return [3 /*break*/, 12];
734 this.logger.log.warn("The version reported in the line above hasn't been incremented during `dry-run`");
735 return [4 /*yield*/, this.getCurrentVersion(lastRelease)];
736 case 11:
737 current = _a.sent();
738 if (semver_1.parse(current)) {
739 this.logger.log.warn("Published version would be: " + semver_1.inc(current, version));
740 }
741 _a.label = 12;
742 case 12: return [2 /*return*/, { newVersion: newVersion, commitsInRelease: commitsInRelease }];
743 }
744 });
745 });
746 };
747 Auto.prototype.getPrNumber = function (command, pr) {
748 var envPr = 'pr' in env && Number(env.pr);
749 var prNumber = pr || envPr;
750 if (!prNumber) {
751 throw new Error("Could not detect PR number. " + command + " must be run from either a PR or have the PR number supllied via the --pr flag.");
752 }
753 return prNumber;
754 };
755 Auto.prototype.startGit = function (gitOptions) {
756 if (!gitOptions.owner || !gitOptions.repo || !gitOptions.token) {
757 throw new Error('Must set owner, repo, and GitHub token.');
758 }
759 this.logger.verbose.info('Options contain repo information.');
760 // So that --verbose can be used on public CIs
761 var tokenlessArgs = __assign({}, gitOptions, { token: "[Token starting with " + gitOptions.token.substring(0, 4) + "]" });
762 this.logger.verbose.info('Initializing GitHub API with:\n', tokenlessArgs);
763 return new git_1.default({
764 owner: gitOptions.owner,
765 repo: gitOptions.repo,
766 token: gitOptions.token,
767 baseUrl: gitOptions.baseUrl,
768 graphqlBaseUrl: gitOptions.graphqlBaseUrl
769 }, this.logger);
770 };
771 Auto.prototype.getVersion = function () {
772 return __awaiter(this, void 0, void 0, function () {
773 var lastRelease;
774 return __generator(this, function (_a) {
775 switch (_a.label) {
776 case 0:
777 if (!this.git || !this.release) {
778 throw this.createErrorMessage();
779 }
780 return [4 /*yield*/, this.git.getLatestRelease()];
781 case 1:
782 lastRelease = _a.sent();
783 return [2 /*return*/, this.release.getSemverBump(lastRelease)];
784 }
785 });
786 });
787 };
788 Auto.prototype.makeChangelog = function (_a) {
789 var _b = _a === void 0 ? {} : _a, dryRun = _b.dryRun, from = _b.from, to = _b.to, message = _b.message;
790 return __awaiter(this, void 0, void 0, function () {
791 var lastRelease, _c, releaseNotes, currentVersion;
792 return __generator(this, function (_d) {
793 switch (_d.label) {
794 case 0:
795 if (!this.release || !this.git) {
796 throw this.createErrorMessage();
797 }
798 return [4 /*yield*/, this.setGitUser()];
799 case 1:
800 _d.sent();
801 _c = from;
802 if (_c) return [3 /*break*/, 3];
803 return [4 /*yield*/, this.git.getLatestRelease()];
804 case 2:
805 _c = (_d.sent());
806 _d.label = 3;
807 case 3:
808 lastRelease = _c;
809 return [4 /*yield*/, this.release.generateReleaseNotes(lastRelease, to || undefined)];
810 case 4:
811 releaseNotes = _d.sent();
812 this.logger.log.info('New Release Notes\n', releaseNotes);
813 if (dryRun) {
814 this.logger.verbose.info('`changelog` dry run complete.');
815 return [2 /*return*/];
816 }
817 return [4 /*yield*/, this.getCurrentVersion(lastRelease)];
818 case 5:
819 currentVersion = _d.sent();
820 return [4 /*yield*/, this.release.addToChangelog(releaseNotes, lastRelease, currentVersion, message)];
821 case 6:
822 _d.sent();
823 return [2 /*return*/];
824 }
825 });
826 });
827 };
828 Auto.prototype.makeRelease = function (_a) {
829 var _b = _a === void 0 ? {} : _a, dryRun = _b.dryRun, useVersion = _b.useVersion, slack = _b.slack;
830 return __awaiter(this, void 0, void 0, function () {
831 var lastRelease, commitsInRelease, releaseNotes, rawVersion, _c, _d, version;
832 return __generator(this, function (_e) {
833 switch (_e.label) {
834 case 0:
835 if (!this.release || !this.git) {
836 throw this.createErrorMessage();
837 }
838 return [4 /*yield*/, this.git.getLatestRelease()];
839 case 1:
840 lastRelease = _e.sent();
841 // Find base commit or latest release to generate the changelog to HEAD (new tag)
842 this.logger.veryVerbose.info("Using " + lastRelease + " as previous release.");
843 if (lastRelease.match(/^\d+\.\d+\.\d+/)) {
844 lastRelease = this.prefixRelease(lastRelease);
845 }
846 this.logger.log.info('Last used release:', lastRelease);
847 return [4 /*yield*/, this.release.getCommitsInRelease(lastRelease)];
848 case 2:
849 commitsInRelease = _e.sent();
850 return [4 /*yield*/, this.release.generateReleaseNotes(lastRelease)];
851 case 3:
852 releaseNotes = _e.sent();
853 this.logger.log.info("Using release notes:\n" + releaseNotes);
854 _d = useVersion;
855 if (_d) return [3 /*break*/, 5];
856 return [4 /*yield*/, this.getCurrentVersion(lastRelease)];
857 case 4:
858 _d = (_e.sent());
859 _e.label = 5;
860 case 5:
861 _c = _d;
862 if (_c) return [3 /*break*/, 7];
863 return [4 /*yield*/, this.git.getLatestTagInBranch()];
864 case 6:
865 _c = (_e.sent());
866 _e.label = 7;
867 case 7:
868 rawVersion = _c;
869 if (!rawVersion) {
870 this.logger.log.error('Could not calculate next version from last tag.');
871 return [2 /*return*/];
872 }
873 version = semver_1.parse(rawVersion)
874 ? this.prefixRelease(rawVersion)
875 : rawVersion;
876 if (!!dryRun) return [3 /*break*/, 11];
877 this.logger.log.info("Releasing " + version + " to GitHub.");
878 return [4 /*yield*/, this.git.publish(releaseNotes, version)];
879 case 8:
880 _e.sent();
881 if (!(slack || (this.config && this.config.slack))) return [3 /*break*/, 10];
882 this.logger.log.info('Posting release to slack');
883 return [4 /*yield*/, this.release.postToSlack(releaseNotes, version)];
884 case 9:
885 _e.sent();
886 _e.label = 10;
887 case 10: return [3 /*break*/, 12];
888 case 11:
889 this.logger.log.info("Would have released: " + version);
890 _e.label = 12;
891 case 12: return [4 /*yield*/, this.hooks.afterRelease.promise(version, commitsInRelease)];
892 case 13:
893 _e.sent();
894 return [2 /*return*/, version];
895 }
896 });
897 });
898 };
899 Auto.prototype.createErrorMessage = function () {
900 return new Error("Auto is not initialized! Make sure the have run Auto.loadConfig");
901 };
902 /**
903 * Set the git user to make releases and commit with.
904 */
905 Auto.prototype.setGitUser = function () {
906 return __awaiter(this, void 0, void 0, function () {
907 var error_4, _a, email, name, packageAuthor;
908 return __generator(this, function (_b) {
909 switch (_b.label) {
910 case 0:
911 _b.trys.push([0, 3, , 9]);
912 // If these values are not set git config will exit with an error
913 return [4 /*yield*/, main_1.execPromise('git', ['config', 'user.email'])];
914 case 1:
915 // If these values are not set git config will exit with an error
916 _b.sent();
917 return [4 /*yield*/, main_1.execPromise('git', ['config', 'user.name'])];
918 case 2:
919 _b.sent();
920 return [3 /*break*/, 9];
921 case 3:
922 error_4 = _b.sent();
923 if (!env.isCi) {
924 this.logger.log.note("Detected local environment, will not set git user. This happens automatically in a CI environment.\n\nIf a command fails manually run:\n\n - git config user.email your@email.com\n - git config user.name \"Your Name\"");
925 return [2 /*return*/];
926 }
927 if (!this.release) {
928 return [2 /*return*/];
929 }
930 _a = this.release.options, email = _a.email, name = _a.name;
931 return [4 /*yield*/, this.hooks.getAuthor.promise()];
932 case 4:
933 packageAuthor = _b.sent();
934 email = packageAuthor ? packageAuthor.email : email;
935 name = packageAuthor ? packageAuthor.name : name;
936 if (!email) return [3 /*break*/, 6];
937 return [4 /*yield*/, main_1.execPromise('git', ['config', 'user.email', "\"" + email + "\""])];
938 case 5:
939 _b.sent();
940 _b.label = 6;
941 case 6:
942 if (!name) return [3 /*break*/, 8];
943 return [4 /*yield*/, main_1.execPromise('git', ['config', 'user.name', "\"" + name + "\""])];
944 case 7:
945 _b.sent();
946 _b.label = 8;
947 case 8: return [3 /*break*/, 9];
948 case 9: return [2 /*return*/];
949 }
950 });
951 });
952 };
953 Auto.prototype.getRepo = function (config) {
954 return __awaiter(this, void 0, void 0, function () {
955 return __generator(this, function (_a) {
956 if (config.owner && config.repo) {
957 return [2 /*return*/, config];
958 }
959 return [2 /*return*/, this.hooks.getRepository.promise()];
960 });
961 });
962 };
963 /**
964 * Apply all of the plugins in the config.
965 */
966 Auto.prototype.loadPlugins = function (config) {
967 var _this = this;
968 var pluginsPaths = config.plugins || ['npm'];
969 pluginsPaths
970 .map(function (plugin) {
971 return typeof plugin === 'string' ? [plugin, {}] : plugin;
972 })
973 .map(function (plugin) { return load_plugins_1.default(plugin, _this.logger); })
974 .filter(function (plugin) { return !!plugin; })
975 .forEach(function (plugin) {
976 _this.logger.verbose.info("Using " + plugin.name + " Plugin...");
977 plugin.apply(_this);
978 });
979 };
980 return Auto;
981}());
982exports.default = Auto;
983//# sourceMappingURL=auto.js.map
\No newline at end of file