@auto-canary/auto
Version:
CLI tools to help facilitate semantic versioning based on GitHub PR labels
439 lines (435 loc) • 15.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const fs = tslib_1.__importStar(require("fs"));
const path = tslib_1.__importStar(require("path"));
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const command_line_application_1 = require("command-line-application");
const endent_1 = tslib_1.__importDefault(require("endent"));
const p = chalk_1.default.hex('#870048');
const y = chalk_1.default.hex('#F1A60E');
const r = chalk_1.default.hex('#C5000B');
const g = chalk_1.default.hex('#888888');
// prettier-ignore
const logo = `
${y('_________')}
${p('/')}${y('\\ /')}${r('\\')} _______ _ _ _______ _____
${p('/')} ${y('\\_____/')} ${r('\\')} |_____| | | | | |
${p('/ /')} ${r('\\ \\')} | | |_____| | |_____|
${p('/___/')} \\▔▔\\ ${r(' \\___\\')}
${g('\\ \\')} \\_/ ${g('/ /')} ______ _______ _______ _______ _______ _______
${g('\\ \\')} ${g('/ /')} |_____/ |______ | |______ |_____| |______ |______
${g('\\ ▔▔▔▔▔ /')} | \\_ |______ |_____ |______ | | ______| |______
${g('\\ /')}
${g('▔▔▔▔▔▔▔▔▔ ')}
`.replace(/\\/g, '\\\\');
const version = {
name: 'version',
alias: 'V',
type: Boolean,
description: "Display auto's version",
group: 'global'
};
const defaultOptions = [
{
name: 'verbose',
alias: 'v',
type: Boolean,
description: 'Show some more logs. Pass -vv for very verbose logs.',
group: 'global',
multiple: true
},
{
name: 'repo',
type: String,
description: 'The repo to set the status on. Defaults to looking in the package definition for the platform',
group: 'global'
},
{
name: 'owner',
type: String,
description: 'The owner of the GitHub repo. Defaults to reading from the package definition for the platform',
group: 'global'
},
{
name: 'github-api',
type: String,
description: 'GitHub API to use',
group: 'global'
},
{
name: 'plugins',
type: String,
multiple: true,
description: 'Plugins to load auto with. (defaults to just npm)',
group: 'global'
}
];
const baseBranch = {
name: 'base-branch',
type: String,
description: 'Branch to treat as the "master" branch',
group: 'global'
};
const pr = {
name: 'pr',
type: Number,
description: 'The pull request the command should use. Detects PR number in CI',
group: 'main'
};
const dryRun = {
name: 'dry-run',
alias: 'd',
type: Boolean,
description: 'Report what command will do but do not actually do anything',
group: 'main'
};
const url = {
name: 'url',
type: String,
description: 'URL to associate with this status',
group: 'main'
};
const noVersionPrefix = {
name: 'no-version-prefix',
type: Boolean,
description: "Use the version as the tag without the 'v' prefix",
group: 'main'
};
const name = {
name: 'name',
type: String,
description: 'Git name to commit and release with. Defaults to package definition for the platform',
group: 'main'
};
const email = {
name: 'email',
type: String,
description: 'Git email to commit with. Defaults to package definition for the platform',
group: 'main'
};
const context = {
name: 'context',
type: String,
description: 'A string label to differentiate this status from others',
group: 'main'
};
const message = {
name: 'message',
group: 'main',
type: String,
alias: 'm'
};
const deleteFlag = {
name: 'delete',
type: Boolean,
group: 'main'
};
exports.commands = [
{
name: 'init',
group: 'Setup Command',
description: 'Interactive setup for most configurable options',
examples: ['{green $} auto init'],
options: [
{
name: 'only-labels',
type: Boolean,
group: 'main',
description: 'Only run init for the labels. As most other options are for advanced users'
},
dryRun
]
},
{
name: 'create-labels',
group: 'Setup Command',
description: "Create your project's labels on github. If labels exist it will update them.",
examples: ['{green $} auto create-labels'],
options: [dryRun]
},
{
name: 'label',
group: 'Pull Request Interaction Commands',
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!",
options: [
Object.assign(Object.assign({}, pr), { description: `${pr.description} (defaults to last merged PR)` })
],
examples: ['{green $} auto label --pr 123']
},
{
name: 'comment',
group: 'Pull Request Interaction Commands',
description: 'Comment on a pull request with a markdown message. Each comment has a context, and each context only has one comment.',
require: [['message', 'delete']],
options: [
pr,
context,
{
name: 'edit',
type: Boolean,
alias: 'e',
group: 'main',
description: 'Edit old comment'
},
Object.assign(Object.assign({}, deleteFlag), { description: 'Delete old comment' }),
Object.assign(Object.assign({}, message), { description: 'Message to post to comment' }),
dryRun
],
examples: [
'{green $} auto comment --delete',
'{green $} auto comment --pr 123 --message "# Why you\'re wrong..."',
'{green $} auto comment --pr 123 --edit --message "This smells..." --context code-smell'
]
},
{
name: 'pr-check',
group: 'Pull Request Interaction Commands',
description: 'Check that a pull request has a SemVer label',
require: ['url'],
options: [
pr,
url,
dryRun,
Object.assign(Object.assign({}, context), { defaultValue: 'ci/pr-check' })
],
examples: ['{green $} auto pr-check --url http://your-ci.com/build/123']
},
{
name: 'pr-status',
group: 'Pull Request Interaction Commands',
description: 'Set the status on a PR commit',
require: ['state', 'url', 'description', 'context'],
options: [
{
name: 'sha',
type: String,
group: 'main',
description: 'Specify a custom git sha. Defaults to the HEAD for a git repo in the current repository'
},
Object.assign(Object.assign({}, pr), { description: 'PR to set the status on. Detects PR number in CI' }),
url,
{
name: 'state',
type: String,
group: 'main',
description: "State of the PR. ['pending', 'success', 'error', 'failure']"
},
{
name: 'description',
type: String,
group: 'main',
description: 'A description of the status'
},
{
name: 'context',
type: String,
group: 'main',
description: 'A string label to differentiate this status from others'
},
dryRun
],
examples: [
`{green $} auto pr \\\\ \n --state pending \\\\ \n --description "Build still running..." \\\\ \n --context build-check`
]
},
{
name: 'pr-body',
group: 'Pull Request Interaction Commands',
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.',
require: [['message', 'delete']],
options: [
pr,
context,
Object.assign(Object.assign({}, deleteFlag), { description: 'Delete old PR body update' }),
Object.assign(Object.assign({}, message), { description: 'Message to post to PR body' }),
dryRun
],
examples: [
'{green $} auto pr-body --delete',
'{green $} auto pr-body --pr 123 --comment "The new version is: 1.2.3"'
]
},
{
name: 'version',
group: 'Release Commands',
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`.',
options: [
{
name: 'only-publish-with-release-label',
type: Boolean,
description: "Only bump version if 'release' label is on pull request",
group: 'main'
},
{
name: 'from',
type: String,
group: 'main',
description: 'Git revision (tag, commit sha, ...) to calculate version bump from. Defaults to latest github release'
}
],
examples: [
{
desc: 'Get the new version using the last release to head',
example: '{green $} auto version'
}
]
},
{
name: 'changelog',
group: 'Release Commands',
description: "Prepend release notes to `CHANGELOG.md`, create one if it doesn't exist, and commit the changes.",
options: [
dryRun,
noVersionPrefix,
name,
email,
{
name: 'from',
type: String,
group: 'main',
description: 'Tag to start changelog generation on. Defaults to latest tag.'
},
{
name: 'to',
type: String,
group: 'main',
description: 'Tag to end changelog generation on. Defaults to HEAD.'
},
Object.assign(Object.assign({}, message), { description: "Message to commit the changelog with. Defaults to 'Update CHANGELOG.md [skip ci]'" }),
baseBranch
],
examples: [
{
desc: 'Generate a changelog from the last release to head',
example: '{green $} auto changelog'
},
{
desc: 'Generate a changelog across specific versions',
example: '{green $} auto changelog --from v0.20.1 --to v0.21.0'
}
]
},
{
name: 'release',
group: 'Release Commands',
description: 'Auto-generate a github release',
options: [
dryRun,
noVersionPrefix,
name,
email,
{
name: 'from',
type: String,
group: 'main',
description: 'Git revision (tag, commit sha, ...) to start release notes from. Defaults to latest tag.'
},
{
name: 'use-version',
type: String,
group: 'main',
description: 'Version number to publish as. Defaults to reading from the package definition for the platform.'
},
baseBranch
],
examples: [
'{green $} auto release',
'{green $} auto release --from v0.20.1 --use-version v0.21.0'
]
},
{
name: 'shipit',
group: 'Release Commands',
description: endent_1.default `
Run the full \`auto\` release pipeline. Detects if in a lerna project.
1. call from base branch -> latest version released (LATEST)
2. call from prerelease branch -> prerelease version released (NEXT)
3. call from PR in CI -> canary version released (CANARY)
4. call locally when not on base/prerelease branch -> canary version released (CANARY)
`,
examples: ['{green $} auto shipit'],
options: [
baseBranch,
dryRun,
{
name: 'only-graduate-with-release-label',
type: Boolean,
defaultValue: false,
group: 'main',
description: 'Make auto publish prerelease versions when merging to master. Only PRs merged with "release" label will generate a "latest" release. Only use this flag if you do not want to maintain a prerelease branch, and instead only want to use master.'
}
]
},
{
name: 'canary',
group: 'Release Commands',
description: endent_1.default `
Make a canary release of the project. Useful on PRs. If ran locally, \`canary\` will release a canary version for your current git HEAD. This is ran automatically from "shipit".
1. In PR: 1.2.3-canary.123.0 + add version to PR body
2. Locally: 1.2.3-canary.1810cfd
`,
examples: [
'{green $} auto canary',
'{green $} auto canary --pr 123 --build 5',
'{green $} auto canary --message "Install PR version: `yarn add -D my-project@%v`"',
'{green $} auto canary --message false'
],
options: [
dryRun,
Object.assign(Object.assign({}, pr), { description: 'PR number to use to create the canary version. Detected in CI env' }),
{
name: 'build',
type: String,
group: 'main',
description: 'Build number to use to create the canary version. Detected in CI env'
},
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" })
]
},
{
name: 'next',
group: 'Release Commands',
description: endent_1.default `
Make a release for your "prerelease" release line. This is ran automatically from "shipit".
1. Creates a prerelease on package management platform
2. Creates a "Pre Release" on GitHub releases page.
Calling the \`next\` command from a prerelease branch will publish a prerelease, otherwise it will publish to the default prerelease branch.
`,
examples: ['{green $} auto next'],
options: [
dryRun,
Object.assign(Object.assign({}, message), { description: 'The message used when attaching the prerelease version to a PR' })
]
}
];
/** Print the current version of "auto" */
function printVersion() {
const packagePath = path.join(__dirname, '../package.json');
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
console.log(`v${packageJson.version}`);
}
/** Parse the CLI args and return command + options provided. */
function parseArgs(testArgs) {
const mainOptions = command_line_application_1.app({
name: 'auto',
logo,
description: 'Generate releases based on semantic version labels on pull requests, and other pull request automation tools.',
commands: exports.commands,
options: [version, ...defaultOptions]
}, {
argv: testArgs
});
if (!mainOptions) {
return [];
}
if (!mainOptions._command) {
if (mainOptions.version) {
printVersion();
}
return [];
}
return [mainOptions._command, mainOptions];
}
exports.default = parseArgs;
//# sourceMappingURL=parse-args.js.map