Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
71ff282
feat: add automated dependency bump checker and changelog validator
cryptodev-2s Nov 6, 2025
8ee555d
refactor: inline package name resolution during diff parsing
cryptodev-2s Nov 6, 2025
084415e
refactor: use example repo name instead of core
cryptodev-2s Nov 6, 2025
2a87c2e
fix: remove useless re-exported types
cryptodev-2s Nov 6, 2025
88d116a
docs: add changelog entry for check-deps command
cryptodev-2s Nov 12, 2025
044b46e
fix: correct changelog entry order - BREAKING first, then deps
cryptodev-2s Dec 2, 2025
ccc66e2
fix: distinguish BREAKING entries when matching changelog entries
cryptodev-2s Dec 2, 2025
48221f2
fix: show correct section name in changelog validation error
cryptodev-2s Dec 2, 2025
045331a
feat: support renamed packages in changelog validation
cryptodev-2s Dec 2, 2025
8af5181
fix: include packageRename in second parseChangelog call
cryptodev-2s Dec 2, 2025
19c3ccd
fix: detect non-scoped package dependency changes
cryptodev-2s Dec 2, 2025
0d1de51
tests: add functional tests (#189)
cryptodev-2s Dec 3, 2025
49b197d
Fix optionalDependencies incorrectly attributed to dependencies section
cryptodev-2s Dec 3, 2025
b53e89c
Fix operator precedence in section boundary check
cryptodev-2s Dec 3, 2025
2f73bd8
Fix default branch check to use defaultBranch parameter instead of ha…
cryptodev-2s Dec 3, 2025
259d980
Reset section state when parsing new file in diff
cryptodev-2s Dec 3, 2025
703e1c3
Fix check-deps command usage in CHANGELOG
cryptodev-2s Dec 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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
  • Loading branch information
cryptodev-2s committed Nov 18, 2025
commit 71ff282e343533fb2fd678511c125e8359033ae1
1,742 changes: 1,742 additions & 0 deletions src/changelog-validator.test.ts

Large diffs are not rendered by default.

438 changes: 438 additions & 0 deletions src/changelog-validator.ts

Large diffs are not rendered by default.

1,979 changes: 1,979 additions & 0 deletions src/check-dependency-bumps.test.ts

Large diffs are not rendered by default.

444 changes: 444 additions & 0 deletions src/check-dependency-bumps.ts

Large diffs are not rendered by default.

174 changes: 128 additions & 46 deletions src/command-line-arguments.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
import yargs from 'yargs/yargs';
import { hideBin } from 'yargs/helpers';

export type CommandLineArguments = {
export type ReleaseCommandArguments = {
_: string[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was is this for? Do we need to return this from readCommandLineArguments? It doesn't seem to be used anywhere.

command: 'release';
projectDirectory: string;
tempDirectory: string | undefined;
tempDirectory?: string;
reset: boolean;
backport: boolean;
defaultBranch: string;
interactive: boolean;
port: number;
};

export type CheckDepsCommandArguments = {
_: string[];
command: 'check-deps';
fromRef?: string;
toRef?: string;
defaultBranch: string;
fix?: boolean;
pr?: string;
};

export type CommandLineArguments =
| ReleaseCommandArguments
| CheckDepsCommandArguments;

/**
* Parses the arguments provided on the command line using `yargs`.
*
Expand All @@ -21,52 +37,118 @@ export type CommandLineArguments = {
export async function readCommandLineArguments(
argv: string[],
): Promise<CommandLineArguments> {
return await yargs(hideBin(argv))
.usage(
'This tool prepares your project for a new release by bumping versions and updating changelogs.',
const args = await yargs(hideBin(argv))
.scriptName('create-release-branch')
.usage('$0 <command> [options]')
.command(
['release', '$0'],
'Prepare your project for a new release by bumping versions and updating changelogs',
(commandYargs) =>
commandYargs
.option('project-directory', {
alias: 'd',
describe: 'The directory that holds your project.',
default: '.',
})
.option('temp-directory', {
describe:
'The directory that is used to hold temporary files, such as the release spec template.',
type: 'string',
})
.option('reset', {
describe:
'Removes any cached files from a previous run that may have been created.',
type: 'boolean',
default: false,
})
.option('backport', {
describe:
'Instructs the tool to bump the second part of the version rather than the first for a backport release.',
type: 'boolean',
default: false,
})
.option('default-branch', {
alias: 'b',
describe: 'The name of the default branch in the repository.',
default: 'main',
type: 'string',
})
.option('interactive', {
alias: 'i',
describe:
'Start an interactive web UI for selecting package versions to release',
type: 'boolean',
default: false,
})
.option('port', {
describe:
'Port to run the interactive web UI server (only used with --interactive)',
type: 'number',
default: 3000,
}),
)
.command(
'check-deps',
'Check dependency version bumps between git references',
(commandYargs) =>
commandYargs
.option('from', {
describe:
'The starting git reference (commit, branch, or tag). If not provided, auto-detects from merge base with default branch.',
type: 'string',
})
.option('to', {
describe: 'The ending git reference (commit, branch, or tag).',
type: 'string',
default: 'HEAD',
})
.option('default-branch', {
alias: 'b',
describe:
'The name of the default branch to compare against when auto-detecting.',
default: 'main',
type: 'string',
})
.option('fix', {
describe:
'Automatically update changelogs with missing dependency bump entries.',
type: 'boolean',
default: false,
})
.option('pr', {
describe:
'PR number to use in changelog entries (uses placeholder if not provided).',
type: 'string',
}),
)
.option('project-directory', {
alias: 'd',
describe: 'The directory that holds your project.',
default: '.',
})
.option('temp-directory', {
describe:
'The directory that is used to hold temporary files, such as the release spec template.',
type: 'string',
})
.option('reset', {
describe:
'Removes any cached files from a previous run that may have been created.',
type: 'boolean',
default: false,
})
.option('backport', {
describe:
'Instructs the tool to bump the second part of the version rather than the first for a backport release.',
type: 'boolean',
default: false,
})
.option('default-branch', {
alias: 'b',
describe: 'The name of the default branch in the repository.',
default: 'main',
type: 'string',
})
.option('interactive', {
alias: 'i',
describe:
'Start an interactive web UI for selecting package versions to release',
type: 'boolean',
default: false,
})
.option('port', {
describe:
'Port to run the interactive web UI server (only used with --interactive)',
type: 'number',
default: 3000,
})
.help()
.strict()
.demandCommand(0, 1)
.parse();

const command = args._[0] || 'release';

if (command === 'check-deps') {
return {
...args,
command: 'check-deps',
fromRef: args.from,
toRef: args.to,
defaultBranch: args.defaultBranch,
fix: args.fix,
pr: args.pr,
} as CheckDepsCommandArguments;
}

return {
...args,
command: 'release',
projectDirectory: args.projectDirectory,
tempDirectory: args.tempDirectory,
reset: args.reset,
backport: args.backport,
defaultBranch: args.defaultBranch,
interactive: args.interactive,
port: args.port,
} as ReleaseCommandArguments;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that this type assertion can be removed if you undo the tempDirectory type change (back to string | undefined). Is there a reason that type change was made? Ideally we'd avoid type assertions if we can.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that the CheckDepsCommandArguments type assertion is there for the same reason.

}
Loading