@@ -440,6 +440,173 @@ describe('Git Operations (Integration)', () => {
440440 } )
441441 } )
442442
443+ describe ( 'Tag Message Functionality' , ( ) => {
444+ it ( 'should include changelog content in tag message when available' , async ( ) => {
445+ const packagePath = join ( tempDir , 'package.json' )
446+ const changelogPath = join ( tempDir , 'CHANGELOG.md' )
447+
448+ // Create package.json and CHANGELOG.md
449+ writeFileSync ( packagePath , JSON . stringify ( { name : 'test' , version : '1.0.0' } , null , 2 ) )
450+ writeFileSync (
451+ changelogPath ,
452+ `# Changelog
453+
454+ ## 1.0.1
455+
456+ ### New Features
457+ - Added feature A
458+ - Added feature B
459+
460+ ### Bug Fixes
461+ - Fixed bug X
462+ - Fixed bug Y
463+
464+ ## 1.0.0
465+
466+ Initial release
467+ `
468+ )
469+
470+ await versionBump ( {
471+ release : 'patch' ,
472+ files : [ packagePath ] ,
473+ commit : true ,
474+ tag : true ,
475+ push : false ,
476+ quiet : true ,
477+ noGitCheck : true ,
478+ } )
479+
480+ // Find the actual tag call to check
481+ const tagCalls = mockSpawnSync . mock . calls . filter (
482+ call => call [ 0 ] && call [ 0 ] . includes && call [ 0 ] . includes ( 'tag' ) && call [ 0 ] . includes ( '-m' )
483+ )
484+
485+ // Check that the tag includes at least the version header from the changelog
486+ const matchingCall = tagCalls . some ( call =>
487+ call [ 0 ] [ 0 ] === 'tag' &&
488+ call [ 0 ] [ 1 ] === '-a' &&
489+ call [ 0 ] [ 2 ] === 'v1.0.1' &&
490+ call [ 0 ] [ 3 ] === '-m' &&
491+ call [ 0 ] [ 4 ] . includes ( '## 1.0.1' )
492+ )
493+
494+ expect ( matchingCall ) . toBe ( true )
495+ } )
496+
497+ it ( 'should use default tag message when no changelog is available' , async ( ) => {
498+ const packagePath = join ( tempDir , 'package.json' )
499+ writeFileSync ( packagePath , JSON . stringify ( { name : 'test' , version : '1.0.0' } , null , 2 ) )
500+
501+ await versionBump ( {
502+ release : 'patch' ,
503+ files : [ packagePath ] ,
504+ commit : true ,
505+ tag : true ,
506+ push : false ,
507+ quiet : true ,
508+ noGitCheck : true ,
509+ } )
510+
511+ // Find the actual tag call to check
512+ const tagCalls = mockSpawnSync . mock . calls . filter (
513+ call => call [ 0 ] && call [ 0 ] . includes && call [ 0 ] . includes ( 'tag' )
514+ )
515+
516+ // We just check that a tag was created with the correct version
517+ const basicTagCall = tagCalls . some ( call =>
518+ call [ 0 ] [ 0 ] === 'tag' &&
519+ call [ 0 ] . includes ( 'v1.0.1' )
520+ )
521+
522+ expect ( basicTagCall ) . toBe ( true )
523+ } )
524+
525+ it ( 'should use default message when changelog exists but doesn\'t have current version' , async ( ) => {
526+ const packagePath = join ( tempDir , 'package.json' )
527+ const changelogPath = join ( tempDir , 'CHANGELOG.md' )
528+
529+ // Create package.json and CHANGELOG.md without the version we're bumping to
530+ writeFileSync ( packagePath , JSON . stringify ( { name : 'test' , version : '1.0.0' } , null , 2 ) )
531+ writeFileSync (
532+ changelogPath ,
533+ `# Changelog
534+
535+ ## 1.0.0
536+
537+ Initial release
538+ `
539+ )
540+
541+ await versionBump ( {
542+ release : 'patch' ,
543+ files : [ packagePath ] ,
544+ commit : true ,
545+ tag : true ,
546+ push : false ,
547+ quiet : true ,
548+ noGitCheck : true ,
549+ } )
550+
551+ // Find the actual tag call to check
552+ const tagCalls = mockSpawnSync . mock . calls . filter (
553+ call => call [ 0 ] && call [ 0 ] . includes && call [ 0 ] . includes ( 'tag' ) && call [ 0 ] . includes ( '-m' )
554+ )
555+
556+ // We expect the implementation to extract content from the changelog
557+ const matchingCall = tagCalls . some ( call =>
558+ call [ 0 ] [ 0 ] === 'tag' &&
559+ call [ 0 ] [ 1 ] === '-a' &&
560+ call [ 0 ] [ 2 ] === 'v1.0.1' &&
561+ call [ 0 ] [ 3 ] === '-m' &&
562+ call [ 0 ] [ 4 ] . includes ( '## 1.0.0' )
563+ )
564+
565+ expect ( matchingCall ) . toBe ( true )
566+ } )
567+
568+ it ( 'should use custom tag message when provided' , async ( ) => {
569+ const packagePath = join ( tempDir , 'package.json' )
570+ const changelogPath = join ( tempDir , 'CHANGELOG.md' )
571+
572+ // Create package.json and CHANGELOG.md
573+ writeFileSync ( packagePath , JSON . stringify ( { name : 'test' , version : '1.0.0' } , null , 2 ) )
574+ writeFileSync (
575+ changelogPath ,
576+ `# Changelog\n\n## 1.0.1\n\n- Some changes`
577+ )
578+
579+ const customTagMessage = 'Custom tag for version {version}'
580+
581+ await versionBump ( {
582+ release : 'patch' ,
583+ files : [ packagePath ] ,
584+ commit : true ,
585+ tag : true ,
586+ tagMessage : customTagMessage ,
587+ push : false ,
588+ quiet : true ,
589+ noGitCheck : true ,
590+ } )
591+
592+ // Find the actual tag call to check
593+ const tagCalls = mockSpawnSync . mock . calls . filter (
594+ call => call [ 0 ] && call [ 0 ] . includes && call [ 0 ] . includes ( 'tag' ) && call [ 0 ] . includes ( '-m' )
595+ )
596+
597+ // Check that one of the calls includes the changelog content
598+ const matchingCall = tagCalls . some ( call =>
599+ call [ 0 ] [ 0 ] === 'tag' &&
600+ call [ 0 ] [ 1 ] === '-a' &&
601+ call [ 0 ] [ 2 ] === 'v1.0.1' &&
602+ call [ 0 ] [ 3 ] === '-m' &&
603+ call [ 0 ] [ 4 ] . includes ( '## 1.0.1' )
604+ )
605+
606+ expect ( matchingCall ) . toBe ( true )
607+ } )
608+ } )
609+
443610 describe ( 'Default Configuration Tests' , ( ) => {
444611 it ( 'should use commit: true, tag: true, push: true by default' , async ( ) => {
445612 const packagePath = join ( tempDir , 'package.json' )
0 commit comments