From c8353fb105b2b6fcd950f545bd71e4b586abd168 Mon Sep 17 00:00:00 2001 From: Edie Lemoine Date: Tue, 7 Nov 2023 15:36:53 +0100 Subject: [PATCH] feat(app-builder): determine commit type based on upgraded versions --- apps/app-builder/package.json | 1 + .../__snapshots__/exports.spec.ts.snap | 1 + .../upgrade/createCommitMessage.spec.ts | 58 ++++++++++++++++++ .../commands/upgrade/createCommitMessage.ts | 10 ++-- .../commands/upgrade/getCommitType.spec.ts | 59 +++++++++++++++++++ .../src/commands/upgrade/getCommitType.ts | 22 +++++++ .../app-builder/src/commands/upgrade/types.ts | 11 +--- apps/app-builder/src/constants.ts | 2 + apps/app-builder/src/index.ts | 2 + apps/app-builder/src/run.ts | 3 +- apps/app-builder/src/types/config.ts | 6 ++ .../src/utils/mergeDefaultConfig.ts | 7 ++- yarn.lock | 1 + 13 files changed, 166 insertions(+), 17 deletions(-) create mode 100644 apps/app-builder/src/commands/upgrade/createCommitMessage.spec.ts create mode 100644 apps/app-builder/src/commands/upgrade/getCommitType.spec.ts create mode 100644 apps/app-builder/src/commands/upgrade/getCommitType.ts diff --git a/apps/app-builder/package.json b/apps/app-builder/package.json index df44c14c7..b4ef00f3c 100644 --- a/apps/app-builder/package.json +++ b/apps/app-builder/package.json @@ -42,6 +42,7 @@ "inquirer": "^9.1.4", "interpret": "^3.1.1", "liftoff": "^4.0.0", + "semver": "^7.5.4", "supports-color": "^9.3.1" }, "devDependencies": { diff --git a/apps/app-builder/src/__tests__/__snapshots__/exports.spec.ts.snap b/apps/app-builder/src/__tests__/__snapshots__/exports.spec.ts.snap index 6c408f5eb..97619db15 100644 --- a/apps/app-builder/src/__tests__/__snapshots__/exports.spec.ts.snap +++ b/apps/app-builder/src/__tests__/__snapshots__/exports.spec.ts.snap @@ -2,6 +2,7 @@ exports[`exports > exports from index.ts 1`] = ` [ + "COMMIT_TYPE_AUTO", "PdkPlatformName", "addPlatformToContext", "copyFile", diff --git a/apps/app-builder/src/commands/upgrade/createCommitMessage.spec.ts b/apps/app-builder/src/commands/upgrade/createCommitMessage.spec.ts new file mode 100644 index 000000000..c1318c016 --- /dev/null +++ b/apps/app-builder/src/commands/upgrade/createCommitMessage.spec.ts @@ -0,0 +1,58 @@ +import {describe, expect, it} from 'vitest'; +import {createTestContext} from '../../__tests__/createTestContext'; +import {type UpgradedEntry, UpgradeMode} from './types'; +import {createCommitMessage} from './createCommitMessage'; + +describe('createCommitMessage', () => { + it('creates commit message for a single node dependency', () => { + const upgradedVersions = [ + { + name: 'vue', + version: '3.3.0', + oldVersion: '3.2.0', + repository: 'https://github.com/vuejs/vue/', + }, + ] satisfies UpgradedEntry[]; + + const context = createTestContext(); + + const commitMessage = createCommitMessage(upgradedVersions, { + ...context, + mode: UpgradeMode.Node, + packageName: 'vue', + }); + + expect(commitMessage).toEqual(`feat(deps): upgrade vue to v3.3.0 + +Compare changes: +- https://github.com/vuejs/vue/compare/v3.2.0...v3.3.0`); + }); + + it('creates commit message for multiple node dependencies', () => { + const upgradedVersions = [ + { + name: '@myparcel-pdk/app-builder', + version: '1.1.5', + oldVersion: '1.1.1', + }, + { + name: '@myparcel-pdk/admin', + version: '1.1.2', + oldVersion: '1.1.1', + }, + ] satisfies UpgradedEntry[]; + + const context = createTestContext(); + + const commitMessage = createCommitMessage(upgradedVersions, { + ...context, + mode: UpgradeMode.Node, + packageName: '@myparcel-pdk/*', + }); + + expect(commitMessage).toEqual(`fix(deps): upgrade @myparcel-pdk/* + +- upgrade @myparcel-pdk/app-builder to v1.1.5 +- upgrade @myparcel-pdk/admin to v1.1.2`); + }); +}); diff --git a/apps/app-builder/src/commands/upgrade/createCommitMessage.ts b/apps/app-builder/src/commands/upgrade/createCommitMessage.ts index 792679424..43351e6c9 100644 --- a/apps/app-builder/src/commands/upgrade/createCommitMessage.ts +++ b/apps/app-builder/src/commands/upgrade/createCommitMessage.ts @@ -1,12 +1,12 @@ import {VerbosityLevel} from '../../constants'; import {type UpgradedEntry, type UpgradeSubContext} from './types'; +import {getCommitType} from './getCommitType'; + +export const createCommitMessage = (upgradedVersions: UpgradedEntry[], context: UpgradeSubContext): string => { + const {packageName, debug, args} = context; -export const createCommitMessage = ( - upgradedVersions: UpgradedEntry[], - {packageName, debug, args}: UpgradeSubContext, -): string => { const lines: string[] = []; - const commitType = args.commitType ?? 'chore'; + const commitType = getCommitType(context, upgradedVersions); if (upgradedVersions.length === 1) { lines.push(`${commitType}(deps): upgrade ${upgradedVersions[0].name} to v${upgradedVersions[0].version}`); diff --git a/apps/app-builder/src/commands/upgrade/getCommitType.spec.ts b/apps/app-builder/src/commands/upgrade/getCommitType.spec.ts new file mode 100644 index 000000000..27cc1bae2 --- /dev/null +++ b/apps/app-builder/src/commands/upgrade/getCommitType.spec.ts @@ -0,0 +1,59 @@ +import {describe, expect, it} from 'vitest'; +import {COMMIT_TYPE_AUTO} from '../../constants'; +import {createTestContext} from '../../__tests__/createTestContext'; +import {type UpgradedEntry} from './types'; +import {getCommitType} from './getCommitType'; + +type TestInput = { + commitType: string; + versions: UpgradedEntry[]; + result: string; +}; + +const createEntry = (newVersion: string, oldVersion?: string): UpgradedEntry => { + return {name: 'test', repository: '', oldVersion, version: newVersion}; +}; + +describe('getCommitType', () => { + it.each([ + { + commitType: 'chore', + versions: [createEntry('1.0.1', '1.0.0')], + result: 'chore', + }, + { + commitType: 'chore', + versions: [createEntry('1.1.0', '1.0.0')], + result: 'chore', + }, + { + commitType: COMMIT_TYPE_AUTO, + versions: [createEntry('1.0.1', '1.0.0'), createEntry('3.40.3', '3.40.0'), createEntry('4.14.3', '4.14.0')], + result: 'fix', + }, + { + commitType: COMMIT_TYPE_AUTO, + versions: [createEntry('1.1.0', '1.0.0')], + result: 'feat', + }, + { + commitType: COMMIT_TYPE_AUTO, + versions: [createEntry('1.1.0', '1.0.0'), createEntry('3.0.0', '2.0.0'), createEntry('4.14.3', '4.14.0')], + result: 'feat', + }, + { + commitType: COMMIT_TYPE_AUTO, + versions: [createEntry('1.1.0'), createEntry('3.0.1', '3.0.0')], + result: 'feat', + }, + { + commitType: COMMIT_TYPE_AUTO, + versions: [createEntry('1.0.0-alpha.62', '1.0.0-alpha.60')], + result: 'feat', + }, + ] satisfies TestInput[])('returns string', ({commitType, versions, result}) => { + const context = createTestContext({config: {commitType}}); + + expect(getCommitType(context, versions)).toBe(result); + }); +}); diff --git a/apps/app-builder/src/commands/upgrade/getCommitType.ts b/apps/app-builder/src/commands/upgrade/getCommitType.ts new file mode 100644 index 000000000..7ccdc01ce --- /dev/null +++ b/apps/app-builder/src/commands/upgrade/getCommitType.ts @@ -0,0 +1,22 @@ +import diff from 'semver/functions/diff'; +import {type PdkBuilderContext} from '../../types'; +import {COMMIT_TYPE_AUTO} from '../../constants'; +import {type UpgradedEntry} from './types'; + +export const getCommitType = (context: PdkBuilderContext, upgradedVersions: UpgradedEntry[]): string => { + if (context.config.commitType === COMMIT_TYPE_AUTO) { + const isPatchUpgrade = upgradedVersions.every((updatedVersion) => { + if (!updatedVersion.oldVersion) { + return false; + } + + const difference = diff(updatedVersion.oldVersion, updatedVersion.version); + + return difference === 'patch'; + }); + + return isPatchUpgrade ? 'fix' : 'feat'; + } + + return context.config.commitType; +}; diff --git a/apps/app-builder/src/commands/upgrade/types.ts b/apps/app-builder/src/commands/upgrade/types.ts index c7757f9c7..de3b6aa2b 100644 --- a/apps/app-builder/src/commands/upgrade/types.ts +++ b/apps/app-builder/src/commands/upgrade/types.ts @@ -1,6 +1,5 @@ -import {type LiftoffEnv} from 'liftoff'; import {type MakeOptional, type PromiseOr} from '@myparcel/ts-utils'; -import {type CommandArgs, type PdkDebugger, type ResolvedPdkBuilderConfig} from '../../types'; +import {type CommandArgs, type PdkBuilderContext} from '../../types'; export interface ParsedEntry { name: string; @@ -10,7 +9,7 @@ export interface ParsedEntry { export interface UpgradedEntry extends ParsedEntry { oldVersion: string | undefined; - repository: string | undefined; + repository?: string | undefined; } export type UpgradeCommandArgs = CommandArgs & { @@ -25,11 +24,7 @@ export type InputUpgradeCommandArgs = MakeOptional< 'composerCommand' | 'yarnCommand' | 'rootCommand' >; -export interface UpgradeSubContext { - args: UpgradeCommandArgs; - config: ResolvedPdkBuilderConfig; - debug: PdkDebugger; - env: LiftoffEnv; +export interface UpgradeSubContext extends PdkBuilderContext { mode: UpgradeMode; packageName: string; } diff --git a/apps/app-builder/src/constants.ts b/apps/app-builder/src/constants.ts index f76353325..afb8f8402 100644 --- a/apps/app-builder/src/constants.ts +++ b/apps/app-builder/src/constants.ts @@ -62,3 +62,5 @@ export const PLATFORM_SHEET_ID_MAP = { // eslint-disable-next-line @typescript-eslint/no-magic-numbers [PdkPlatformName.MyParcelNl]: 1550017884, } satisfies Record; + +export const COMMIT_TYPE_AUTO = 'auto'; diff --git a/apps/app-builder/src/index.ts b/apps/app-builder/src/index.ts index f0af24062..afe21ae56 100644 --- a/apps/app-builder/src/index.ts +++ b/apps/app-builder/src/index.ts @@ -6,6 +6,8 @@ export type {PdkBuilderCommand, StringGenerator} from './types'; export type {PdkBuilderConfig}; +export {COMMIT_TYPE_AUTO} from './constants'; + export {PdkPlatformName} from './types'; export { diff --git a/apps/app-builder/src/run.ts b/apps/app-builder/src/run.ts index 8bf837255..a013e2d7d 100644 --- a/apps/app-builder/src/run.ts +++ b/apps/app-builder/src/run.ts @@ -16,6 +16,7 @@ import { COMMAND_TRANSLATIONS_NAME, COMMAND_UPGRADE_NAME, COMMAND_ZIP_NAME, + COMMIT_TYPE_AUTO, TITLE, } from './constants'; @@ -108,7 +109,7 @@ const COMMAND_UPGRADE: CommandDefinition = { OPTION_QUIET, OPTION_DRY_RUN, ['-l, --lockfile ', 'Provide an alternative path to a lockfile.'], - ['--commit-type ', 'Commit type', 'chore'], + ['--commit-type ', 'Commit type', COMMIT_TYPE_AUTO], ['--no-check', 'Skip checking whether the lockfile is modified.'], ['--no-commit', 'Skip creating a commit.'], ], diff --git a/apps/app-builder/src/types/config.ts b/apps/app-builder/src/types/config.ts index cda9c7589..4534f43bc 100644 --- a/apps/app-builder/src/types/config.ts +++ b/apps/app-builder/src/types/config.ts @@ -187,6 +187,12 @@ export type PdkBuilderConfig = { vendorOutDir?: string; }; + /** + * Commit type to use when running the `upgrade` command. Set to auto to compute the commit type based on the + * upgraded versions. + */ + commitType?: string | 'auto' | 'chore' | 'feat' | 'fix'; + additionalCommands?: CommandDefinition[]; hooks?: CommandHooksObject; diff --git a/apps/app-builder/src/utils/mergeDefaultConfig.ts b/apps/app-builder/src/utils/mergeDefaultConfig.ts index 26e081190..996a5a53c 100644 --- a/apps/app-builder/src/utils/mergeDefaultConfig.ts +++ b/apps/app-builder/src/utils/mergeDefaultConfig.ts @@ -1,11 +1,12 @@ import {type PdkBuilderConfig, type ResolvedPdkBuilderConfig} from '../types'; -import {DEFAULT_JSON_SPACES} from '../constants'; +import {COMMIT_TYPE_AUTO, DEFAULT_JSON_SPACES} from '../constants'; import {NodePackageManager} from '../commands/upgrade/types'; export const mergeDefaultConfig = (config: PdkBuilderConfig): ResolvedPdkBuilderConfig => { const resolvedConfig = { additionalCommands: [], archiveFilename: '{{platform}}-{{name}}-{{version}}.zip', + commitType: COMMIT_TYPE_AUTO, composerCommand: 'composer', debug: false, jsonSpaces: DEFAULT_JSON_SPACES, @@ -35,12 +36,12 @@ export const mergeDefaultConfig = (config: PdkBuilderConfig): ResolvedPdkBuilder sheetId: 0, ...config.translations, }, - }; + } satisfies PdkBuilderConfig; return { ...resolvedConfig, yarnCommand: resolvedConfig.yarnCommand ?? 'yarn', nodePackageManagerCommand: resolvedConfig.nodePackageManagerCommand ?? resolvedConfig.yarnCommand ?? resolvedConfig.nodePackageManager, - }; + } satisfies ResolvedPdkBuilderConfig; }; diff --git a/yarn.lock b/yarn.lock index 435e6a8d1..7703c4469 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1967,6 +1967,7 @@ __metadata: inquirer: ^9.1.4 interpret: ^3.1.1 liftoff: ^4.0.0 + semver: ^7.5.4 supports-color: ^9.3.1 tsup: ^7.1.0 bin: