Skip to content

Commit a88a703

Browse files
committed
feat: add automated dependency bump checker and changelog validator
Introduces a new tool to automatically detect dependency version changes and validate/update changelog entries accordingly. Features: - Detects dependency bumps from git diffs in package.json files - Validates changelog entries with exact version matching - Automatically updates changelogs with missing or outdated entries - Smart PR reference concatenation when updating existing entries - Dynamically reads repository URLs and package names - Validates by default with optional --fix flag for updates Usage: yarn check-dependency-bumps # Validate changelogs yarn check-dependency-bumps --fix # Auto-update changelogs yarn check-dependency-bumps --fix --pr 1234 # With PR number
1 parent 7ba6cd2 commit a88a703

9 files changed

+4901
-335
lines changed

src/changelog-validator.test.ts

Lines changed: 1372 additions & 0 deletions
Large diffs are not rendered by default.

src/changelog-validator.ts

Lines changed: 448 additions & 0 deletions
Large diffs are not rendered by default.

src/check-dependency-bumps.test.ts

Lines changed: 1962 additions & 0 deletions
Large diffs are not rendered by default.

src/check-dependency-bumps.ts

Lines changed: 460 additions & 0 deletions
Large diffs are not rendered by default.

src/command-line-arguments.ts

Lines changed: 128 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
import yargs from 'yargs/yargs';
22
import { hideBin } from 'yargs/helpers';
33

4-
export type CommandLineArguments = {
4+
export type ReleaseCommandArguments = {
5+
_: string[];
6+
command: 'release';
57
projectDirectory: string;
6-
tempDirectory: string | undefined;
8+
tempDirectory?: string;
79
reset: boolean;
810
backport: boolean;
911
defaultBranch: string;
1012
interactive: boolean;
1113
port: number;
1214
};
1315

16+
export type CheckDepsCommandArguments = {
17+
_: string[];
18+
command: 'check-deps';
19+
fromRef?: string;
20+
toRef?: string;
21+
defaultBranch: string;
22+
fix?: boolean;
23+
pr?: string;
24+
};
25+
26+
export type CommandLineArguments =
27+
| ReleaseCommandArguments
28+
| CheckDepsCommandArguments;
29+
1430
/**
1531
* Parses the arguments provided on the command line using `yargs`.
1632
*
@@ -21,52 +37,118 @@ export type CommandLineArguments = {
2137
export async function readCommandLineArguments(
2238
argv: string[],
2339
): Promise<CommandLineArguments> {
24-
return await yargs(hideBin(argv))
25-
.usage(
26-
'This tool prepares your project for a new release by bumping versions and updating changelogs.',
40+
const args = await yargs(hideBin(argv))
41+
.scriptName('create-release-branch')
42+
.usage('$0 <command> [options]')
43+
.command(
44+
['release', '$0'],
45+
'Prepare your project for a new release by bumping versions and updating changelogs',
46+
(commandYargs) =>
47+
commandYargs
48+
.option('project-directory', {
49+
alias: 'd',
50+
describe: 'The directory that holds your project.',
51+
default: '.',
52+
})
53+
.option('temp-directory', {
54+
describe:
55+
'The directory that is used to hold temporary files, such as the release spec template.',
56+
type: 'string',
57+
})
58+
.option('reset', {
59+
describe:
60+
'Removes any cached files from a previous run that may have been created.',
61+
type: 'boolean',
62+
default: false,
63+
})
64+
.option('backport', {
65+
describe:
66+
'Instructs the tool to bump the second part of the version rather than the first for a backport release.',
67+
type: 'boolean',
68+
default: false,
69+
})
70+
.option('default-branch', {
71+
alias: 'b',
72+
describe: 'The name of the default branch in the repository.',
73+
default: 'main',
74+
type: 'string',
75+
})
76+
.option('interactive', {
77+
alias: 'i',
78+
describe:
79+
'Start an interactive web UI for selecting package versions to release',
80+
type: 'boolean',
81+
default: false,
82+
})
83+
.option('port', {
84+
describe:
85+
'Port to run the interactive web UI server (only used with --interactive)',
86+
type: 'number',
87+
default: 3000,
88+
}),
89+
)
90+
.command(
91+
'check-deps',
92+
'Check dependency version bumps between git references',
93+
(commandYargs) =>
94+
commandYargs
95+
.option('from', {
96+
describe:
97+
'The starting git reference (commit, branch, or tag). If not provided, auto-detects from merge base with default branch.',
98+
type: 'string',
99+
})
100+
.option('to', {
101+
describe: 'The ending git reference (commit, branch, or tag).',
102+
type: 'string',
103+
default: 'HEAD',
104+
})
105+
.option('default-branch', {
106+
alias: 'b',
107+
describe:
108+
'The name of the default branch to compare against when auto-detecting.',
109+
default: 'main',
110+
type: 'string',
111+
})
112+
.option('fix', {
113+
describe:
114+
'Automatically update changelogs with missing dependency bump entries.',
115+
type: 'boolean',
116+
default: false,
117+
})
118+
.option('pr', {
119+
describe:
120+
'PR number to use in changelog entries (uses placeholder if not provided).',
121+
type: 'string',
122+
}),
27123
)
28-
.option('project-directory', {
29-
alias: 'd',
30-
describe: 'The directory that holds your project.',
31-
default: '.',
32-
})
33-
.option('temp-directory', {
34-
describe:
35-
'The directory that is used to hold temporary files, such as the release spec template.',
36-
type: 'string',
37-
})
38-
.option('reset', {
39-
describe:
40-
'Removes any cached files from a previous run that may have been created.',
41-
type: 'boolean',
42-
default: false,
43-
})
44-
.option('backport', {
45-
describe:
46-
'Instructs the tool to bump the second part of the version rather than the first for a backport release.',
47-
type: 'boolean',
48-
default: false,
49-
})
50-
.option('default-branch', {
51-
alias: 'b',
52-
describe: 'The name of the default branch in the repository.',
53-
default: 'main',
54-
type: 'string',
55-
})
56-
.option('interactive', {
57-
alias: 'i',
58-
describe:
59-
'Start an interactive web UI for selecting package versions to release',
60-
type: 'boolean',
61-
default: false,
62-
})
63-
.option('port', {
64-
describe:
65-
'Port to run the interactive web UI server (only used with --interactive)',
66-
type: 'number',
67-
default: 3000,
68-
})
69124
.help()
70125
.strict()
126+
.demandCommand(0, 1)
71127
.parse();
128+
129+
const command = args._[0] || 'release';
130+
131+
if (command === 'check-deps') {
132+
return {
133+
...args,
134+
command: 'check-deps',
135+
fromRef: args.from,
136+
toRef: args.to,
137+
defaultBranch: args.defaultBranch,
138+
fix: args.fix,
139+
pr: args.pr,
140+
} as CheckDepsCommandArguments;
141+
}
142+
143+
return {
144+
...args,
145+
command: 'release',
146+
projectDirectory: args.projectDirectory,
147+
tempDirectory: args.tempDirectory,
148+
reset: args.reset,
149+
backport: args.backport,
150+
defaultBranch: args.defaultBranch,
151+
interactive: args.interactive,
152+
port: args.port,
153+
} as ReleaseCommandArguments;
72154
}

0 commit comments

Comments
 (0)