1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const fs = tslib_1.__importStar(require("fs"));
|
5 | const path = tslib_1.__importStar(require("path"));
|
6 | const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
7 | const command_line_application_1 = require("command-line-application");
|
8 | const dedent_1 = tslib_1.__importDefault(require("dedent"));
|
9 | const p = chalk_1.default.hex('#870048');
|
10 | const y = chalk_1.default.hex('#F1A60E');
|
11 | const r = chalk_1.default.hex('#C5000B');
|
12 | const g = chalk_1.default.hex('#888888');
|
13 |
|
14 | const logo = `
|
15 | ${y('_________')}
|
16 | ${p('/')}${y('\\ /')}${r('\\')} _______ _ _ _______ _____
|
17 | ${p('/')} ${y('\\_____/')} ${r('\\')} |_____| | | | | |
|
18 | ${p('/ /')} ${r('\\ \\')} | | |_____| | |_____|
|
19 | ${p('/___/')} \\▔▔\\ ${r(' \\___\\')}
|
20 | ${g('\\ \\')} \\_/ ${g('/ /')} ______ _______ _______ _______ _______ _______
|
21 | ${g('\\ \\')} ${g('/ /')} |_____/ |______ | |______ |_____| |______ |______
|
22 | ${g('\\ ▔▔▔▔▔ /')} | \\_ |______ |_____ |______ | | ______| |______
|
23 | ${g('\\ /')}
|
24 | ${g('▔▔▔▔▔▔▔▔▔ ')}
|
25 | `.replace(/\\/g, '\\\\');
|
26 | const version = {
|
27 | name: 'version',
|
28 | alias: 'V',
|
29 | type: Boolean,
|
30 | description: "Display auto's version",
|
31 | group: 'global'
|
32 | };
|
33 | const defaultOptions = [
|
34 | {
|
35 | name: 'verbose',
|
36 | alias: 'v',
|
37 | type: Boolean,
|
38 | description: 'Show some more logs',
|
39 | group: 'global'
|
40 | },
|
41 | {
|
42 | name: 'very-verbose',
|
43 | alias: 'w',
|
44 | type: Boolean,
|
45 | description: 'Show a lot more logs',
|
46 | group: 'global'
|
47 | },
|
48 | {
|
49 | name: 'repo',
|
50 | type: String,
|
51 | description: 'The repo to set the status on. Defaults to looking in the package definition for the platform',
|
52 | group: 'global'
|
53 | },
|
54 | {
|
55 | name: 'owner',
|
56 | type: String,
|
57 | description: 'The owner of the GitHub repo. Defaults to reading from the package definition for the platform',
|
58 | group: 'global'
|
59 | },
|
60 | {
|
61 | name: 'github-api',
|
62 | type: String,
|
63 | description: 'GitHub API to use',
|
64 | group: 'global'
|
65 | },
|
66 | {
|
67 | name: 'plugins',
|
68 | type: String,
|
69 | multiple: true,
|
70 | description: 'Plugins to load auto with. (defaults to just npm)',
|
71 | group: 'global'
|
72 | }
|
73 | ];
|
74 | const baseBranch = {
|
75 | name: 'base-branch',
|
76 | type: String,
|
77 | description: 'Branch to treat as the "master" branch',
|
78 | group: 'global'
|
79 | };
|
80 | const pr = {
|
81 | name: 'pr',
|
82 | type: Number,
|
83 | description: 'The pull request the command should use. Detects PR number in CI',
|
84 | group: 'main'
|
85 | };
|
86 | const dryRun = {
|
87 | name: 'dry-run',
|
88 | alias: 'd',
|
89 | type: Boolean,
|
90 | description: 'Report what command will do but do not actually do anything',
|
91 | group: 'main'
|
92 | };
|
93 | const url = {
|
94 | name: 'url',
|
95 | type: String,
|
96 | description: 'URL to associate with this status',
|
97 | group: 'main'
|
98 | };
|
99 | const noVersionPrefix = {
|
100 | name: 'no-version-prefix',
|
101 | type: Boolean,
|
102 | description: "Use the version as the tag without the 'v' prefix",
|
103 | group: 'main'
|
104 | };
|
105 | const name = {
|
106 | name: 'name',
|
107 | type: String,
|
108 | description: 'Git name to commit and release with. Defaults to package definition for the platform',
|
109 | group: 'main'
|
110 | };
|
111 | const email = {
|
112 | name: 'email',
|
113 | type: String,
|
114 | description: 'Git email to commit with. Defaults to package definition for the platform',
|
115 | group: 'main'
|
116 | };
|
117 | const context = {
|
118 | name: 'context',
|
119 | type: String,
|
120 | description: 'A string label to differentiate this status from others',
|
121 | group: 'main'
|
122 | };
|
123 | const message = {
|
124 | name: 'message',
|
125 | group: 'main',
|
126 | type: String,
|
127 | alias: 'm'
|
128 | };
|
129 | const skipReleaseLabels = {
|
130 | name: 'skip-release-labels',
|
131 | type: String,
|
132 | group: 'main',
|
133 | multiple: true,
|
134 | description: "Labels that will not create a release. Defaults to just 'skip-release'"
|
135 | };
|
136 | const deleteFlag = {
|
137 | name: 'delete',
|
138 | type: Boolean,
|
139 | group: 'main'
|
140 | };
|
141 | exports.commands = [
|
142 | {
|
143 | name: 'init',
|
144 | group: 'Setup Command',
|
145 | description: 'Interactive setup for most configurable options',
|
146 | examples: ['{green $} auto init'],
|
147 | options: [
|
148 | {
|
149 | name: 'only-labels',
|
150 | type: Boolean,
|
151 | group: 'main',
|
152 | description: 'Only run init for the labels. As most other options are for advanced users'
|
153 | },
|
154 | dryRun
|
155 | ]
|
156 | },
|
157 | {
|
158 | name: 'create-labels',
|
159 | group: 'Setup Command',
|
160 | description: "Create your project's labels on github. If labels exist it will update them.",
|
161 | examples: ['{green $} auto create-labels'],
|
162 | options: [dryRun]
|
163 | },
|
164 | {
|
165 | name: 'label',
|
166 | group: 'Pull Request Interaction Commands',
|
167 | description: "Get the labels for a pull request. Doesn't do much, but the return value lets you write you own scripts based off of the PR labels!",
|
168 | options: [
|
169 | Object.assign(Object.assign({}, pr), { description: `${pr.description} (defaults to last merged PR)` })
|
170 | ],
|
171 | examples: ['{green $} auto label --pr 123']
|
172 | },
|
173 | {
|
174 | name: 'comment',
|
175 | group: 'Pull Request Interaction Commands',
|
176 | description: 'Comment on a pull request with a markdown message. Each comment has a context, and each context only has one comment.',
|
177 | require: [['message', 'delete']],
|
178 | options: [
|
179 | pr,
|
180 | context,
|
181 | {
|
182 | name: 'edit',
|
183 | type: Boolean,
|
184 | alias: 'e',
|
185 | group: 'main',
|
186 | description: 'Edit old comment'
|
187 | },
|
188 | Object.assign(Object.assign({}, deleteFlag), { description: 'Delete old comment' }),
|
189 | Object.assign(Object.assign({}, message), { description: 'Message to post to comment' }),
|
190 | dryRun
|
191 | ],
|
192 | examples: [
|
193 | '{green $} auto comment --delete',
|
194 | '{green $} auto comment --pr 123 --message "# Why you\'re wrong..."',
|
195 | '{green $} auto comment --pr 123 --edit --message "This smells..." --context code-smell'
|
196 | ]
|
197 | },
|
198 | {
|
199 | name: 'pr-check',
|
200 | group: 'Pull Request Interaction Commands',
|
201 | description: 'Check that a pull request has a SemVer label',
|
202 | require: ['url'],
|
203 | options: [
|
204 | pr,
|
205 | url,
|
206 | dryRun,
|
207 | Object.assign(Object.assign({}, context), { defaultValue: 'ci/pr-check' }),
|
208 | skipReleaseLabels
|
209 | ],
|
210 | examples: ['{green $} auto pr-check --url http://your-ci.com/build/123']
|
211 | },
|
212 | {
|
213 | name: 'pr-status',
|
214 | group: 'Pull Request Interaction Commands',
|
215 | description: 'Set the status on a PR commit',
|
216 | require: ['state', 'url', 'description', 'context'],
|
217 | options: [
|
218 | {
|
219 | name: 'sha',
|
220 | type: String,
|
221 | group: 'main',
|
222 | description: 'Specify a custom git sha. Defaults to the HEAD for a git repo in the current repository'
|
223 | },
|
224 | Object.assign(Object.assign({}, pr), { description: 'PR to set the status on. Detects PR number in CI' }),
|
225 | url,
|
226 | {
|
227 | name: 'state',
|
228 | type: String,
|
229 | group: 'main',
|
230 | description: "State of the PR. ['pending', 'success', 'error', 'failure']"
|
231 | },
|
232 | {
|
233 | name: 'description',
|
234 | type: String,
|
235 | group: 'main',
|
236 | description: 'A description of the status'
|
237 | },
|
238 | {
|
239 | name: 'context',
|
240 | type: String,
|
241 | group: 'main',
|
242 | description: 'A string label to differentiate this status from others'
|
243 | },
|
244 | dryRun
|
245 | ],
|
246 | examples: [
|
247 | `{green $} auto pr \\\\ \n --state pending \\\\ \n --description "Build still running..." \\\\ \n --context build-check`
|
248 | ]
|
249 | },
|
250 | {
|
251 | name: 'pr-body',
|
252 | group: 'Pull Request Interaction Commands',
|
253 | description: 'Update the body of a PR with a message. Appends to PR and will not overwrite user content. Each comment has a context, and each context only has one comment.',
|
254 | require: [['message', 'delete']],
|
255 | options: [
|
256 | pr,
|
257 | context,
|
258 | Object.assign(Object.assign({}, deleteFlag), { description: 'Delete old PR body update' }),
|
259 | Object.assign(Object.assign({}, message), { description: 'Message to post to PR body' }),
|
260 | dryRun
|
261 | ],
|
262 | examples: [
|
263 | '{green $} auto pr-body --delete',
|
264 | '{green $} auto pr-body --pr 123 --comment "The new version is: 1.2.3"'
|
265 | ]
|
266 | },
|
267 | {
|
268 | name: 'version',
|
269 | group: 'Release Commands',
|
270 | description: 'Get the semantic version bump for the given changes. Requires all PRs to have labels for the change type. If a PR does not have a label associated with it, it will default to `patch`.',
|
271 | options: [
|
272 | {
|
273 | name: 'only-publish-with-release-label',
|
274 | type: Boolean,
|
275 | description: "Only bump version if 'release' label is on pull request",
|
276 | group: 'main'
|
277 | },
|
278 | skipReleaseLabels,
|
279 | {
|
280 | name: 'from',
|
281 | type: String,
|
282 | group: 'main',
|
283 | description: 'Git revision (tag, commit sha, ...) to calculate version bump from. Defaults to latest github release'
|
284 | }
|
285 | ],
|
286 | examples: [
|
287 | {
|
288 | desc: 'Get the new version using the last release to head',
|
289 | example: '{green $} auto version'
|
290 | },
|
291 | {
|
292 | desc: 'Skip releases with multiple labels',
|
293 | example: '{green $} auto version --skip-release-labels documentation CI'
|
294 | }
|
295 | ]
|
296 | },
|
297 | {
|
298 | name: 'changelog',
|
299 | group: 'Release Commands',
|
300 | description: "Prepend release notes to `CHANGELOG.md`, create one if it doesn't exist, and commit the changes.",
|
301 | options: [
|
302 | dryRun,
|
303 | noVersionPrefix,
|
304 | name,
|
305 | email,
|
306 | {
|
307 | name: 'from',
|
308 | type: String,
|
309 | group: 'main',
|
310 | description: 'Tag to start changelog generation on. Defaults to latest tag.'
|
311 | },
|
312 | {
|
313 | name: 'to',
|
314 | type: String,
|
315 | group: 'main',
|
316 | description: 'Tag to end changelog generation on. Defaults to HEAD.'
|
317 | },
|
318 | Object.assign(Object.assign({}, message), { description: "Message to commit the changelog with. Defaults to 'Update CHANGELOG.md [skip ci]'" }),
|
319 | baseBranch
|
320 | ],
|
321 | examples: [
|
322 | {
|
323 | desc: 'Generate a changelog from the last release to head',
|
324 | example: '{green $} auto changelog'
|
325 | },
|
326 | {
|
327 | desc: 'Generate a changelog across specific versions',
|
328 | example: '{green $} auto changelog --from v0.20.1 --to v0.21.0'
|
329 | }
|
330 | ]
|
331 | },
|
332 | {
|
333 | name: 'release',
|
334 | group: 'Release Commands',
|
335 | description: 'Auto-generate a github release',
|
336 | options: [
|
337 | dryRun,
|
338 | noVersionPrefix,
|
339 | name,
|
340 | email,
|
341 | {
|
342 | name: 'from',
|
343 | type: String,
|
344 | group: 'main',
|
345 | description: 'Git revision (tag, commit sha, ...) to start release notes from. Defaults to latest tag.'
|
346 | },
|
347 | {
|
348 | name: 'use-version',
|
349 | type: String,
|
350 | group: 'main',
|
351 | description: 'Version number to publish as. Defaults to reading from the package definition for the platform.'
|
352 | },
|
353 | baseBranch
|
354 | ],
|
355 | examples: [
|
356 | '{green $} auto release',
|
357 | '{green $} auto release --from v0.20.1 --use-version v0.21.0'
|
358 | ]
|
359 | },
|
360 | {
|
361 | name: 'shipit',
|
362 | group: 'Release Commands',
|
363 | description: dedent_1.default `
|
364 | Run the full \`auto\` release pipeline. Detects if in a lerna project.
|
365 |
|
366 | 1. call from base branch -> latest version released
|
367 | 2. call from PR in CI -> canary version released
|
368 | 3. call locally when not on base branch -> canary version released
|
369 | `,
|
370 | examples: ['{green $} auto shipit'],
|
371 | options: [baseBranch, dryRun]
|
372 | },
|
373 | {
|
374 | name: 'canary',
|
375 | group: 'Release Commands',
|
376 | description: dedent_1.default `
|
377 | Make a canary release of the project. Useful on PRs. If ran locally, \`canary\` will release a canary version for your current git HEAD.
|
378 |
|
379 | 1. In PR: 1.2.3-canary.123.0 + add version to PR body
|
380 | 2. Locally: 1.2.3-canary.1810cfd
|
381 | `,
|
382 | examples: [
|
383 | '{green $} auto canary',
|
384 | '{green $} auto canary --pr 123 --build 5',
|
385 | '{green $} auto canary --message "Install PR version: `yarn add -D my-project@%v`"',
|
386 | '{green $} auto canary --message false'
|
387 | ],
|
388 | options: [
|
389 | dryRun,
|
390 | Object.assign(Object.assign({}, pr), { description: 'PR number to use to create the canary version. Detected in CI env' }),
|
391 | {
|
392 | name: 'build',
|
393 | type: String,
|
394 | group: 'main',
|
395 | description: 'Build number to use to create the canary version. Detected in CI env'
|
396 | },
|
397 | Object.assign(Object.assign({}, message), { description: "Message to comment on PR with. Defaults to 'Published PR with canary version: %v'. Pass false to disable the comment" })
|
398 | ]
|
399 | }
|
400 | ];
|
401 |
|
402 | function printVersion() {
|
403 | const packagePath = path.join(__dirname, '../package.json');
|
404 | const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
405 | console.log(`v${packageJson.version}`);
|
406 | }
|
407 |
|
408 | function parseArgs(testArgs) {
|
409 | const mainOptions = command_line_application_1.app({
|
410 | name: 'auto',
|
411 | logo,
|
412 | description: 'Generate releases based on semantic version labels on pull requests, and other pull request automation tools.',
|
413 | commands: exports.commands,
|
414 | options: [version, ...defaultOptions]
|
415 | }, {
|
416 | argv: testArgs
|
417 | });
|
418 | if (!mainOptions) {
|
419 | return [];
|
420 | }
|
421 | if (!mainOptions._command) {
|
422 | if (mainOptions.version) {
|
423 | printVersion();
|
424 | }
|
425 | return [];
|
426 | }
|
427 | return [mainOptions._command, mainOptions];
|
428 | }
|
429 | exports.default = parseArgs;
|
430 |
|
\ | No newline at end of file |