@storm-software/git-tools
Version:
Tools for managing Git repositories within a Nx workspace.
492 lines (489 loc) โข 22.3 kB
text/typescript
import { ProjectGraph, ProjectsConfigurations } from '@nx/devkit';
import { NxReleaseVersionConfiguration, NxReleaseChangelogConfiguration, NxReleaseGitConfiguration, NxReleaseConventionalCommitsConfiguration } from 'nx/src/config/nx-json';
type DeepPartial<T> = T extends object ? {
[P in keyof T]?: DeepPartial<T[P]>;
} : T;
type CommitEnumItemProps = {
description: string;
title?: string;
emoji?: string;
hidden?: boolean;
};
type CommitTypeProps = CommitEnumItemProps & {
semverBump: "none" | "patch" | "minor" | "major";
changelog: {
title: string;
hidden: boolean;
};
};
declare const COMMIT_TYPES: {
readonly chore: {
readonly description: "Other changes that don't modify src or test files";
readonly title: "Chore";
readonly emoji: "โ๏ธ ";
readonly semverBump: "patch";
readonly changelog: {
readonly title: "Miscellaneous";
readonly hidden: false;
};
};
readonly fix: {
readonly description: "A change that resolves an issue previously identified with the package";
readonly title: "Bug Fix";
readonly emoji: "๐ชฒ ";
readonly semverBump: "patch";
readonly changelog: {
readonly title: "Bug Fixes";
readonly hidden: false;
};
};
readonly feat: {
readonly description: "A change that adds a new feature to the package";
readonly title: "Feature";
readonly emoji: "๐ ";
readonly semverBump: "minor";
readonly changelog: {
readonly title: "Features";
readonly hidden: false;
};
};
readonly ci: {
readonly description: "Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)";
readonly title: "Continuous Integration";
readonly emoji: "๐งฐ ";
readonly semverBump: "patch";
readonly changelog: {
readonly title: "Continuous Integration";
readonly hidden: false;
};
};
readonly refactor: {
readonly description: "A code change that neither fixes a bug nor adds a feature";
readonly title: "Code Refactoring";
readonly emoji: "๐งช ";
readonly semverBump: "patch";
readonly changelog: {
readonly title: "Source Code Improvements";
readonly hidden: false;
};
};
readonly style: {
readonly description: "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)";
readonly title: "Style Improvements";
readonly emoji: "๐ ";
readonly semverBump: "patch";
readonly changelog: {
readonly title: "Style Improvements";
readonly hidden: false;
};
};
readonly perf: {
readonly description: "A code change that improves performance";
readonly title: "Performance Improvement";
readonly emoji: "โฑ๏ธ ";
readonly semverBump: "patch";
readonly changelog: {
readonly title: "Performance Improvements";
readonly hidden: false;
};
};
readonly docs: {
readonly description: "A change that only includes documentation updates";
readonly title: "Documentation";
readonly emoji: "๐ ";
readonly semverBump: "none";
readonly changelog: {
readonly title: "Documentation";
readonly hidden: false;
};
};
readonly test: {
readonly description: "Adding missing tests or correcting existing tests";
readonly title: "Testing";
readonly emoji: "๐จ ";
readonly semverBump: "none";
readonly changelog: {
readonly title: "Testing";
readonly hidden: true;
};
};
readonly deps: {
readonly description: "Changes that add, update, or remove dependencies. This includes devDependencies and peerDependencies";
readonly title: "Dependencies";
readonly emoji: "๐ฆ ";
readonly hidden: true;
readonly semverBump: "patch";
readonly changelog: {
readonly title: "Dependency Upgrades";
readonly hidden: false;
};
};
readonly build: {
readonly description: "Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)";
readonly title: "Build";
readonly emoji: "๐ ";
readonly hidden: true;
readonly semverBump: "none";
readonly changelog: {
readonly title: "Build";
readonly hidden: true;
};
};
readonly release: {
readonly description: "Publishing a commit containing a newly released version";
readonly title: "Publish Release";
readonly emoji: "๐ ";
readonly hidden: true;
readonly semverBump: "none";
readonly changelog: {
readonly title: "Publish Release";
readonly hidden: true;
};
};
};
type DefaultCommitTypeKeys = keyof typeof COMMIT_TYPES;
type CommitTypesEnum<TCommitTypes extends DefaultCommitTypeKeys = DefaultCommitTypeKeys> = Record<TCommitTypes, CommitTypeProps>;
type CommitScopeProps = CommitEnumItemProps & {
projectRoot: string;
};
type CommitScopesEnum = Record<string, CommitScopeProps>;
type CommitQuestionTypeProp = "input" | "select" | "confirm";
type CommitQuestionProps = {
type?: CommitQuestionTypeProp;
title: string;
description: string;
enum?: Record<string, CommitEnumItemProps>;
defaultValue?: string | boolean;
maxLength?: number;
minLength?: number;
when?: (answers: Record<string, string>) => boolean;
};
declare const DEFAULT_COMMIT_QUESTIONS: {
readonly type: {
readonly type: "select";
readonly title: "Commit Type";
readonly description: "Select the commit type that best describes your changes";
readonly enum: CommitTypesEnum<"chore" | "fix" | "feat" | "ci" | "refactor" | "style" | "perf" | "docs" | "test" | "deps" | "build" | "release">;
readonly defaultValue: "chore";
readonly maxLength: 20;
readonly minLength: 3;
};
readonly scope: {
readonly type: "select";
readonly title: "Commit Scope";
readonly description: "Select the monorepo project that is primarily impacted by this change";
readonly enum: CommitScopesEnum;
readonly defaultValue: "monorepo";
readonly maxLength: 50;
readonly minLength: 1;
};
readonly subject: {
readonly type: "input";
readonly title: "Commit Subject";
readonly description: "Write a short, imperative tense description of the change";
readonly maxLength: 150;
readonly minLength: 3;
};
readonly body: {
readonly type: "input";
readonly title: "Commit Body";
readonly description: "Provide a longer description of the change";
readonly maxLength: 600;
};
readonly isBreaking: {
readonly type: "confirm";
readonly title: "Breaking Changes";
readonly description: "Are there any breaking changes as a result of this commit?";
readonly defaultValue: false;
};
readonly breakingBody: {
readonly type: "input";
readonly title: "Breaking Changes (Details)";
readonly description: "A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself";
readonly when: (answers: Record<string, any>) => boolean;
readonly maxLength: 600;
readonly minLength: 3;
};
readonly isIssueAffected: {
readonly type: "confirm";
readonly title: "Open Issue Affected";
readonly description: "Does this change impact any open issues?";
readonly defaultValue: false;
};
readonly issuesBody: {
readonly type: "input";
readonly title: "Open Issue Affected (Details)";
readonly description: "If issues are closed, the commit requires a body. Please enter a longer description of the commit itself";
readonly when: (answers: Record<string, any>) => boolean;
readonly maxLength: 600;
readonly minLength: 3;
};
};
type DefaultCommitQuestionKeys = keyof typeof DEFAULT_COMMIT_QUESTIONS;
type CommitQuestionEnum<TCommitQuestionKeys extends DefaultCommitQuestionKeys = DefaultCommitQuestionKeys, TCommitQuestionProps extends CommitQuestionProps = CommitQuestionProps> = Record<TCommitQuestionKeys, TCommitQuestionProps> & typeof DEFAULT_COMMIT_QUESTIONS;
declare const DEFAULT_COMMIT_PROMPT_MESSAGES: {
readonly skip: "press enter to skip";
readonly max: "must be %d chars at most";
readonly min: "must be %d chars at least";
readonly emptyWarning: "can not be empty";
readonly upperLimitWarning: "%s is %d characters longer than the upper limit";
readonly lowerLimitWarning: "%s is %d characters less than the lower limit";
readonly closedIssueMessage: "Closes: ";
};
type DefaultCommitPromptMessagesKeys = keyof typeof DEFAULT_COMMIT_PROMPT_MESSAGES;
type CommitPromptMessagesEnum<TCommitPromptMessagesKeys extends DefaultCommitPromptMessagesKeys = DefaultCommitPromptMessagesKeys> = Record<TCommitPromptMessagesKeys, string> & typeof DEFAULT_COMMIT_PROMPT_MESSAGES;
declare const DEFAULT_COMMIT_MESSAGE_FORMAT = "{type}({scope}): {emoji}{subject}";
declare const DEFAULT_COMMIT_SETTINGS: {
enableMultipleScopes: boolean;
disableEmoji: boolean;
breakingChangePrefix: string;
closedIssuePrefix: string;
format: string;
};
type CommitSettingsEnum = Record<string, any> & {
scopeEnumSeparator?: string;
enableMultipleScopes: boolean;
disableEmoji: boolean;
breakingChangePrefix?: string;
closedIssuePrefix?: string;
format: string;
};
type RuleConfigCondition = "always" | "never";
declare enum RuleConfigSeverity {
Disabled = 0,
Warning = 1,
Error = 2
}
type CommitRulesEnum = Record<string, [RuleConfigSeverity, RuleConfigCondition] | [RuleConfigSeverity, RuleConfigCondition, number] | [RuleConfigSeverity, RuleConfigCondition, string] | [RuleConfigSeverity, RuleConfigCondition, string[]] | [RuleConfigSeverity, RuleConfigCondition, any] | any>;
type DefaultCommitRulesEnum = {
"body-leading-blank": [RuleConfigSeverity, RuleConfigCondition];
"body-max-length": [RuleConfigSeverity, RuleConfigCondition, number];
"footer-leading-blank": [RuleConfigSeverity, RuleConfigCondition];
"footer-max-line-length": [RuleConfigSeverity, RuleConfigCondition, number];
"header-max-length": [RuleConfigSeverity, RuleConfigCondition, number];
"header-trim": [RuleConfigSeverity, RuleConfigCondition];
"subject-case": [RuleConfigSeverity, RuleConfigCondition, string[]];
"subject-empty": [RuleConfigSeverity, RuleConfigCondition];
"subject-full-stop": [RuleConfigSeverity, RuleConfigCondition, string];
"subject-max-length": [RuleConfigSeverity, RuleConfigCondition, number];
"subject-min-length": [RuleConfigSeverity, RuleConfigCondition, number];
"type-case": [RuleConfigSeverity, RuleConfigCondition, string];
"type-empty": [RuleConfigSeverity, RuleConfigCondition];
"type-enum": [RuleConfigSeverity, RuleConfigCondition, string[]];
"scope-empty": [RuleConfigSeverity, RuleConfigCondition];
"type-max-length": [RuleConfigSeverity, RuleConfigCondition, number];
"type-min-length": [RuleConfigSeverity, RuleConfigCondition, number];
"scope-case": [RuleConfigSeverity, RuleConfigCondition, string[]];
} & CommitRulesEnum;
type CommitConfig<TCommitQuestionEnum extends CommitQuestionEnum = CommitQuestionEnum, TCommitTypesEnum extends CommitTypesEnum = CommitTypesEnum, TCommitPromptMessagesEnum extends CommitPromptMessagesEnum = CommitPromptMessagesEnum, TCommitSettingsEnum extends CommitSettingsEnum = CommitSettingsEnum> = {
extends?: string[];
messages: TCommitPromptMessagesEnum;
settings: TCommitSettingsEnum;
types: TCommitTypesEnum;
questions: TCommitQuestionEnum;
};
type DefaultResolvedCommitRulesEnum = DefaultCommitRulesEnum & {
"scope-enum": (ctx: any) => Promise<[RuleConfigSeverity, RuleConfigCondition, string[]]>;
};
type CommitResolvedConfig<TCommitQuestionEnum extends CommitQuestionEnum<DefaultCommitQuestionKeys, CommitQuestionProps> = CommitQuestionEnum<DefaultCommitQuestionKeys, CommitQuestionProps>, TCommitPromptMessagesEnum extends CommitPromptMessagesEnum = CommitPromptMessagesEnum, TCommitSettingsEnum extends CommitSettingsEnum = CommitSettingsEnum> = {
utils: Record<string, any>;
parserPreset: string;
prompt: {
settings: TCommitSettingsEnum;
messages: TCommitPromptMessagesEnum;
questions: TCommitQuestionEnum;
};
};
type CommitQuestionAnswers<TCommitQuestionEnum extends CommitQuestionEnum = CommitQuestionEnum> = Record<keyof TCommitQuestionEnum | string, string | boolean>;
type CommitState<TCommitQuestionEnum extends CommitQuestionEnum = CommitQuestionEnum, TCommitPromptMessagesEnum extends CommitPromptMessagesEnum = CommitPromptMessagesEnum, TCommitSettingsEnum extends CommitSettingsEnum = CommitSettingsEnum> = {
answers: CommitQuestionAnswers<TCommitQuestionEnum>;
config: CommitResolvedConfig<TCommitQuestionEnum, TCommitPromptMessagesEnum, TCommitSettingsEnum>;
root: string;
};
interface CommitLintRuleOutcome {
/** If the commit is considered valid for the rule */
valid: boolean;
/** The "severity" of the rule (1 = warning, 2 = error) */
level: RuleConfigSeverity;
/** The name of the rule */
name: string;
/** The message returned from the rule, if invalid */
message: string;
}
interface CommitLintOutcome {
/** The linted commit, as string */
input: string;
/** If the linted commit is considered valid */
valid: boolean;
/** All errors, per rule, for the commit */
errors: CommitLintRuleOutcome[];
/** All warnings, per rule, for the commit */
warnings: CommitLintRuleOutcome[];
}
type ReleaseConfig = any & {
npm: boolean;
github: boolean;
githubOptions?: Record<string, unknown>;
buildTarget?: string;
changelog?: boolean;
changelogFile?: string;
outputPath?: string;
commitMessage?: string;
gitAssets?: string[];
packageJsonDir?: string;
parserOpts?: Record<string, unknown>;
writerOpts?: Record<string, unknown>;
linkCompare?: boolean;
linkReferences?: boolean;
releaseRules?: string | {
release: string | boolean;
[key: string]: unknown;
}[];
preset?: string;
presetConfig?: Record<string, unknown>;
plugins?: any[];
tagFormat?: string;
git: boolean;
branches: string[];
};
type ReleaseContext = ReleaseConfig & {
projectName: string;
workspaceDir: string;
projectGraph: ProjectGraph;
projectConfigs: ProjectsConfigurations;
};
interface ReadMeOptions {
templates: string;
project?: string;
output?: string;
clean: boolean;
prettier: boolean;
}
interface NxReleaseConfig {
/**
* Shorthand for amending the projects which will be included in the implicit default release group (all projects by default).
* @note Only one of `projects` or `groups` can be specified, the cannot be used together.
*/
projects?: string[] | string;
/**
* @note When no projects or groups are configured at all (the default), all projects in the workspace are treated as
* if they were in a release group together with a fixed relationship.
*/
groups?: Record<string, // group name
{
/**
* Whether to version and release projects within the group independently, or together in lock step ("fixed").
* If not set on the group, this will be informed by the projectsRelationship config at the top level.
*/
projectsRelationship?: "fixed" | "independent";
/**
* Required list of one or more projects to include in the release group. Any single project can
* only be used in a maximum of one release group.
*/
projects: string[] | string;
/**
* Optionally override version configuration for this group.
*
* NOTE: git configuration is not supported at the group level, only the root/command level
*/
version?: NxReleaseVersionConfiguration;
/**
* Project changelogs are disabled by default.
*
* Here you can optionally override project changelog configuration for this group.
* Notes about boolean values:
*
* - true = enable project level changelogs using default configuration
* - false = explicitly disable project level changelogs
*
* NOTE: git configuration is not supported at the group level, only the root/command level
*/
changelog?: NxReleaseChangelogConfiguration | boolean;
/**
* Optionally override the git/release tag pattern to use for this group.
*/
releaseTagPattern?: string;
}>;
/**
* Configures the default value for all groups that don't explicitly state their own projectsRelationship.
*
* By default, this is set to "fixed" which means all projects in the workspace will be versioned and
* released together in lock step.
*/
projectsRelationship?: "fixed" | "independent";
changelog?: {
/**
* Enable or override configuration for git operations as part of the changelog subcommand
*/
git?: NxReleaseGitConfiguration;
/**
* Workspace changelog is enabled by default. Notes about boolean values:
*
* - true = explicitly enable workspace changelog using default configuration
* - false = disable workspace changelog
*/
workspaceChangelog?: NxReleaseChangelogConfiguration | boolean;
/**
* Project changelogs are disabled by default. Notes about boolean values:
*
* - true = enable project level changelogs using default configuration
* - false = explicitly disable project level changelogs
*/
projectChangelogs?: NxReleaseChangelogConfiguration | boolean;
/**
* Whether or not to automatically look up the first commit for the workspace (or package, if versioning independently)
* and use that as the starting point for changelog generation. If this is not enabled, changelog generation will fail
* if there is no previous matching git tag to use as a starting point.
*/
automaticFromRef?: boolean;
};
/**
* If no version config is provided, we will assume that @nx/js:release-version
* is the desired generator implementation, allowing for terser config for the common case.
*/
version?: NxReleaseVersionConfiguration & {
/**
* Enable or override configuration for git operations as part of the version subcommand
*/
git?: NxReleaseGitConfiguration;
/**
* A command to run after validation of nx release configuration, but before versioning begins.
* Used for preparing build artifacts. If --dry-run is passed, the command is still executed, but
* with the NX_DRY_RUN environment variable set to 'true'.
*/
preVersionCommand?: string;
};
/**
* Optionally override the git/release tag pattern to use. This field is the source of truth
* for changelog generation and release tagging, as well as for conventional commits parsing.
*
* It supports interpolating the version as {version} and (if releasing independently or forcing
* project level version control system releases) the project name as {projectName} within the string.
*
* The default releaseTagPattern for fixed/unified releases is: "v{version}"
* The default releaseTagPattern for independent releases at the project level is: "{projectName}@{version}"
*/
releaseTagPattern?: string;
/**
* Enable and configure automatic git operations as part of the release
*/
git?: NxReleaseGitConfiguration;
conventionalCommits?: NxReleaseConventionalCommitsConfiguration;
}
type NxReleaseConventionalCommitsConfig = NonNullable<NxReleaseConfig["conventionalCommits"]>;
type NxReleaseProjectsConfig = NonNullable<NxReleaseConfig["projects"]>;
type NxReleaseGroupsConfig = NonNullable<NxReleaseConfig["groups"]>;
type NxReleaseVersionConfig = NonNullable<NxReleaseConfig["version"]>;
type NxReleaseGitConfig = NonNullable<NxReleaseConfig["git"]>;
type NxReleaseChangelogConfig = NonNullable<NxReleaseConfig["changelog"]>;
type NxReleaseGroupConfig = NxReleaseGroupsConfig[string];
type NxReleaseRequiredGitConfig = Required<{
commit?: boolean | undefined;
commitMessage?: string | undefined;
commitArgs?: string | undefined;
stageChanges?: boolean | undefined;
tag?: boolean | undefined;
tagMessage?: string | undefined;
tagArgs?: string | undefined;
}>;
export { COMMIT_TYPES, type CommitConfig, type CommitEnumItemProps, type CommitLintOutcome, type CommitLintRuleOutcome, type CommitPromptMessagesEnum, type CommitQuestionAnswers, type CommitQuestionEnum, type CommitQuestionProps, type CommitResolvedConfig, type CommitRulesEnum, type CommitScopeProps, type CommitScopesEnum, type CommitSettingsEnum, type CommitState, type CommitTypeProps, type CommitTypesEnum, DEFAULT_COMMIT_MESSAGE_FORMAT, DEFAULT_COMMIT_PROMPT_MESSAGES, DEFAULT_COMMIT_QUESTIONS, DEFAULT_COMMIT_SETTINGS, type DeepPartial, type DefaultCommitPromptMessagesKeys, type DefaultCommitQuestionKeys, type DefaultCommitRulesEnum, type DefaultCommitTypeKeys, type DefaultResolvedCommitRulesEnum, type NxReleaseChangelogConfig, type NxReleaseConfig, type NxReleaseConventionalCommitsConfig, type NxReleaseGitConfig, type NxReleaseGroupConfig, type NxReleaseGroupsConfig, type NxReleaseProjectsConfig, type NxReleaseRequiredGitConfig, type NxReleaseVersionConfig, type ReadMeOptions, type ReleaseConfig, type ReleaseContext, type RuleConfigCondition, RuleConfigSeverity };