UNPKG

@qlover/fe-release

Version:

A tool for releasing front-end projects, supporting multiple release modes and configurations, simplifying the release process and improving efficiency.

562 lines (542 loc) 15.2 kB
import { FeScriptContextOptions, Shell, FeReleaseConfig, FeScriptContext } from '@qlover/scripts-context'; import { AsyncExecutor, ExecutorContext, ExecutorPlugin } from '@qlover/fe-corekit'; import { LoggerInterface } from '@qlover/logger'; import { Env } from '@qlover/env-loader'; import { CommitField } from 'gitlog'; import { OptionValues } from 'commander'; declare class ReleaseTask { private executor; private defaultTuples; protected context: ReleaseContext; constructor(options?: ReleaseContextOptions, executor?: AsyncExecutor, defaultTuples?: PluginTuple<PluginClass>[]); getContext(): ReleaseContext; usePlugins(externalTuples?: PluginTuple<PluginClass>[]): Promise<Plugin[]>; run(): Promise<unknown>; exec(externalTuples?: PluginTuple<PluginClass>[]): Promise<unknown>; } interface WorkspacesProps { /** * Whether to skip workspaces * * @default `false` */ skip?: boolean; /** * Whether to skip checking the package.json file * * @default `false` */ skipCheckPackage?: boolean; /** * The workspace to publish */ workspace?: WorkspaceValue; /** * The workspaces to publish * @private */ workspaces?: WorkspaceValue[]; /** * The change labels * * from `changePackagesLabel` */ changeLabels?: string[]; /** * The changed paths * @private */ changedPaths?: string[]; /** * The packages * @private */ packages?: string[]; /** * All project packages mapping * @private */ projectWorkspaces?: WorkspaceValue[]; } interface WorkspaceValue { name: string; version: string; /** * The relative path of the workspace */ path: string; /** * The absolute path of the workspace */ root: string; /** * The package.json of the workspace */ packageJson: PackageJson; /** * The tag name of the workspace * @private */ tagName?: string; /** * The last tag name of the workspace * @private */ lastTag?: string; /** * The changelog of the workspace * @private */ changelog?: string; } type ReleaseParamsConfig = { /** * Max number of workspaces to include in the release name * * @default 3 */ maxWorkspace?: number; /** * Multi-workspace separator * * @default '_' */ multiWorkspaceSeparator?: string; /** * Workspace version separator * * @default '@' */ workspaceVersionSeparator?: string; /** * The branch name for batch release * * @default `batch-${releaseName}-${length}-packages-${timestamp}` */ batchBranchName?: string; /** * The tag name for batch release * * @default `batch-${length}-packages-${timestamp}` */ batchTagName?: string; /** * The PR title for batch release * * default from feConfig.release.PRTitle * * @default `Release ${env} ${pkgName} ${tagName}` */ PRTitle?: string; /** * The PR body for batch release * * default from feConfig.release.PRBody */ PRBody?: string; }; interface GitBaseProps { /** * The token for the GitHub API * * @default `GITHUB_TOKEN` */ tokenRef?: string; /** * The timeout for the GitHub API */ timeout?: number; } interface GithubPRProps extends ReleaseParamsConfig, GitBaseProps { /** * Whether to dry run the creation of the pull request * * - create pr * - changeset publish * * @default `false` */ dryRunCreatePR?: boolean; /** * Whether to skip the release * * @default `false` */ skip?: boolean; /** * Whether to publish a PR * * @default `false` */ releasePR?: boolean; /** * The commit message of the release * * support WorkspaceValue * * @default 'chore(tag): {{name}} v${version}' */ commitMessage?: string; /** * The commit args of the release * * @default [] */ commitArgs?: string[]; /** * The release name of the release * * @default 'Release ${name} v${version}' */ releaseName?: string; /** * Whether to create a draft release * * @default false */ draft?: boolean; /** * Whether to create a pre-release * * @default false */ preRelease?: boolean; /** * Whether to auto-generate the release notes * * @default false */ autoGenerate?: boolean; /** * Whether to make the latest release * * @default true */ makeLatest?: boolean | 'true' | 'false' | 'legacy'; /** * The release notes of the release * * @default undefined */ releaseNotes?: string; /** * The discussion category name of the release * * @default undefined */ discussionCategoryName?: string; /** * Whether to push the changed labels to the release PR * * @default false */ pushChangeLabels?: boolean; } interface ExecutorReleaseContext extends ExecutorContext<ReleaseContext> { returnValue: ReleaseReturnValue; } type ReleaseReturnValue = { githubToken?: string; [key: string]: unknown; }; type DeepPartial<T> = { [P in keyof T]?: DeepPartial<T[P]>; }; interface ReleaseConfig { githubPR?: GithubPRProps; workspaces?: WorkspacesProps; } interface ReleaseContextOptions<T extends ReleaseConfig = ReleaseConfig> extends Omit<FeScriptContextOptions<T>, 'constructor'> { shared?: SharedReleaseOptions; } type StepOption<T> = { label: string; enabled?: boolean; task: () => Promise<T>; }; type PackageJson = Record<string, unknown>; interface TemplateContext extends SharedReleaseOptions, WorkspaceValue { publishPath: string; /** * @deprecated use `releaseEnv` from `shared` */ env: string; /** * @deprecated use `sourceBranch` from `shared` */ branch: string; } declare abstract class Plugin<Props = unknown> implements ExecutorPlugin<ReleaseContext> { protected context: ReleaseContext; readonly pluginName: string; protected props: Props; readonly onlyOne = true; constructor(context: ReleaseContext, pluginName: string, props?: Props); getInitialProps(props?: Props): Props; get logger(): LoggerInterface; get shell(): Shell; get options(): Props; getEnv(key: string, defaultValue?: string): string | undefined; enabled(_name: string, _context: ExecutorReleaseContext): boolean; getConfig<T>(keys?: string | string[], defaultValue?: T): T; setConfig(config: DeepPartial<Props>): void; onBefore?(_context: ExecutorReleaseContext): void | Promise<void>; onExec?(_context: ExecutorReleaseContext): void | Promise<void>; onSuccess?(_context: ExecutorReleaseContext): void | Promise<void>; onError?(_context: ExecutorReleaseContext): void | Promise<void>; /** * run a step * * this will log the step and return the result of the task * * @param label - the label of the step * @param task - the task to run * @returns the result of the task */ step<T>({ label, task }: StepOption<T>): Promise<T>; } /** * Represents a class that extends Plugin. */ type PluginClass<T extends unknown[] = any[]> = new (...args: T) => Plugin; /** * Represents the constructor parameters for a specific Plugin class, excluding the first parameter. * This assumes that the constructor parameters are known and can be inferred. */ type PluginConstructorParams<T extends PluginClass> = T extends new (first: any, ...args: infer P) => unknown ? P : never; type PluginTuple<T extends PluginClass> = [ T | string, ...PluginConstructorParams<T> ]; declare function tuple<T extends PluginClass>(plugin: T | string, ...args: PluginConstructorParams<T>): PluginTuple<T>; /** * This is the shared options for the release. * * extends `FeReleaseConfig` */ interface SharedReleaseOptions extends FeReleaseConfig { /** * The source branch of the project * * default: * - first, get from `FE_RELEASE_SOURCE_BRANCH` * - second, get from `FE_RELEASE_BRANCH` * - `master` * */ sourceBranch?: string; /** * The environment of the project * * default: * - first, get from `FE_RELEASE_ENV` * - second, get from `NODE_ENV` * - `development` */ releaseEnv?: string; /** * The root path of the project * * @default `process.cwd()` */ rootPath?: string; /** * Plugins */ plugins?: PluginTuple<PluginClass<unknown[]>>[]; /** * The name of the repository */ repoName?: string; /** * The name of the author */ authorName?: string; /** * The current branch of the project */ currentBranch?: string; } declare class ReleaseContext<T extends ReleaseConfig = ReleaseConfig> extends FeScriptContext<T> { protected readonly _env: Env; /** * Shared Config */ shared: SharedReleaseOptions; constructor(context: ReleaseContextOptions<T>); private getDefaultShreadOptions; get rootPath(): string; get sourceBranch(): string; get releaseEnv(): string; get env(): Env; get workspaces(): WorkspaceValue[] | undefined; get workspace(): WorkspaceValue | undefined; setWorkspaces(workspaces: WorkspaceValue[]): void; setConfig(config: DeepPartial<ReleaseConfig>): void; getConfig<T = unknown>(key: string | string[], defaultValue?: T): T; setShared(shared: Partial<SharedReleaseOptions>): void; getPkg<T>(key?: string, defaultValue?: T): T; getTemplateContext(): TemplateContext; runChangesetsCli(name: string, args?: string[]): Promise<string>; } type ReleaseLabelCompare = (changedFilePath: string, packagePath: string) => boolean; interface ReleaseLabelOptions { /** * The change packages label */ changePackagesLabel: string; /** * The packages directories */ packagesDirectories: string[]; compare?: ReleaseLabelCompare; } declare class ReleaseLabel { private readonly options; constructor(options: ReleaseLabelOptions); compare(changedFilePath: string, packagePath: string): boolean; toChangeLabel(packagePath: string, label?: string): string; toChangeLabels(packages: string[], label?: string): string[]; pick(changedFiles: Array<string> | Set<string>, packages?: string[]): string[]; } type BaseCommit = { [key in CommitField]: string | undefined; }; interface GitChangelogOptions { /** * start tag */ from?: string; /** * end tag */ to?: string; /** * log directory */ directory?: string; /** * gitlog default fields * @default ["abbrevHash", "hash", "subject", "authorName", "authorDate"] */ fileds?: CommitField[]; /** * not include merge commit * @default true */ noMerges?: boolean; /** * custom commit type */ types?: { type: string; section?: string; hidden?: boolean; }[]; /** * custom commit format * * - support `CommitValue` properties * - add scopeHeader, commitLink, prLink * * @default '\n- ${scopeHeader} ${commitlint.message} ${commitLink} ${prLink}' */ formatTemplate?: string; /** * whether to include commit body * @since 2.3.0 * @default false */ commitBody?: boolean; } interface Commitlint { type?: string; scope?: string; message: string; /** * commit body, remove repeat title * @since 2.3.0 */ body?: string; } interface CommitValue { /** * git log base info */ base: BaseCommit; /** * parsed commitlint info */ commitlint: Commitlint; /** * parsed commitlint info */ commits: CommitValue[]; /** * pr number */ prNumber?: string; } interface ChangelogFormatter { format<Opt extends GitChangelogOptions>(commits: unknown[], options?: Opt): string[]; } interface ChangeLogInterface { getCommits(options?: GitChangelogOptions): Promise<CommitValue[]>; } declare const CHANGELOG_ALL_FIELDS: CommitField[]; interface GitChangelogProps extends GitChangelogOptions { shell: Shell; logger: LoggerInterface; } declare class GitChangelog implements ChangeLogInterface { protected options: GitChangelogProps; constructor(options: GitChangelogProps); /** * Get the git log * * @param options * @returns */ getGitLog(options?: GitChangelogOptions): Promise<BaseCommit[]>; getCommits(options?: GitChangelogOptions): Promise<CommitValue[]>; protected createBaseCommit(message: string, target?: Partial<BaseCommit>): BaseCommit; /** * Tabify the body * * @since 2.3.2 * @param body * @param size * @returns */ tabify(body: string, size?: number): string; parseCommitlint(subject: string, rawBody?: string): Commitlint; toCommitValue(hash: string, message: string): CommitValue; protected resolveTag(tag?: string, fallback?: string): Promise<string>; } interface Options extends GitChangelogOptions { repoUrl?: string; } declare class GitChangelogFormatter implements ChangelogFormatter { protected options: Options & { shell: Shell; }; constructor(options: Options & { shell: Shell; }); format(commits: CommitValue[], options?: Options): string[]; formatCommit(commit: CommitValue, options?: Options): string; foramtLink(target: string, url?: string): string; formatCommitLink(target: string, url?: string): string; formatScope(scope: string): string; } interface GithubChangelogProps extends GitChangelogProps { mergePRcommit?: boolean; githubRootPath?: string; } declare function load<T>(pluginName: string): Promise<[string, T]>; declare function loaderPluginsFromPluginTuples<T extends Plugin<unknown>>(context: ReleaseContext, pluginsTuples: PluginTuple<PluginClass>[], maxLimit?: number): Promise<T[]>; type ConstructorType<T, Args extends unknown[]> = (new (...args: Args) => T) | ((...args: Args) => T); declare function factory<T, Args extends unknown[]>(Constructor: ConstructorType<T, Args>, ...args: Args): T; declare function reduceOptions(opts: OptionValues, commonKey?: string): OptionValues; export { CHANGELOG_ALL_FIELDS, GitChangelog, GitChangelogFormatter, Plugin, ReleaseContext, ReleaseLabel, ReleaseTask, factory, load, loaderPluginsFromPluginTuples, reduceOptions, tuple }; export type { ConstructorType, DeepPartial, ExecutorReleaseContext, GitChangelogProps, GithubChangelogProps, Options, PackageJson, PluginClass, PluginConstructorParams, PluginTuple, ReleaseConfig, ReleaseContextOptions, ReleaseLabelCompare, ReleaseLabelOptions, ReleaseReturnValue, StepOption, TemplateContext };