11import * as core from '@actions/core'
2+ import * as exec from '@actions/exec'
23import { ChangeTypeEnum } from '../changedFiles'
34import { Inputs } from '../inputs'
45import {
56 getDirname ,
67 getDirnameMaxDepth ,
78 getFilteredChangedFiles ,
9+ getPreviousGitTag ,
810 normalizeSeparators ,
911 warnUnsupportedRESTAPIInputs
1012} from '../utils'
@@ -638,7 +640,9 @@ describe('utils test', () => {
638640 useRestApi : false ,
639641 excludeSubmodules : false ,
640642 fetchMissingHistoryMaxRetries : 10 ,
641- usePosixPathSeparator : false
643+ usePosixPathSeparator : false ,
644+ tagsPattern : '*' ,
645+ tagsIgnorePattern : ''
642646 }
643647
644648 const coreWarningSpy = jest . spyOn ( core , 'warning' )
@@ -654,4 +658,193 @@ describe('utils test', () => {
654658 expect ( coreWarningSpy ) . toHaveBeenCalledTimes ( 1 )
655659 } )
656660 } )
661+ describe ( 'getPreviousGitTag' , ( ) => {
662+ // Function returns the second latest tag and its SHA
663+ it ( 'should return the second latest tag and its SHA when multiple tags are present' , async ( ) => {
664+ jest
665+ . spyOn ( exec , 'getExecOutput' )
666+ . mockResolvedValueOnce ( {
667+ stdout : 'v1.0.1\nv1.0.0\nv0.9.9' ,
668+ stderr : '' ,
669+ exitCode : 0
670+ } )
671+ . mockResolvedValueOnce ( {
672+ stdout : 'abc123' ,
673+ stderr : '' ,
674+ exitCode : 0
675+ } )
676+ const result = await getPreviousGitTag ( {
677+ cwd : '.' ,
678+ tagsPattern : '*' ,
679+ tagsIgnorePattern : ''
680+ } )
681+ expect ( result ) . toEqual ( { tag : 'v1.0.0' , sha : 'abc123' } )
682+ } )
683+
684+ // Tags are filtered by a specified pattern when 'tagsPattern' is provided
685+ it ( 'should filter tags by the specified pattern' , async ( ) => {
686+ jest
687+ . spyOn ( exec , 'getExecOutput' )
688+ . mockResolvedValueOnce ( {
689+ stdout : 'v1.0.1\nv1.0.0\nv0.9.9' ,
690+ stderr : '' ,
691+ exitCode : 0
692+ } )
693+ . mockResolvedValueOnce ( {
694+ stdout : 'def456' ,
695+ stderr : '' ,
696+ exitCode : 0
697+ } )
698+ const result = await getPreviousGitTag ( {
699+ cwd : '.' ,
700+ tagsPattern : 'v1.*' ,
701+ tagsIgnorePattern : ''
702+ } )
703+ expect ( result ) . toEqual ( { tag : 'v1.0.0' , sha : 'def456' } )
704+ } )
705+
706+ // Tags are excluded by a specified ignore pattern when 'tagsIgnorePattern' is provided
707+ it ( 'should exclude tags by the specified ignore pattern' , async ( ) => {
708+ jest
709+ . spyOn ( exec , 'getExecOutput' )
710+ . mockResolvedValueOnce ( {
711+ stdout : 'v1.0.1\nv1.0.0\nv0.9.9' ,
712+ stderr : '' ,
713+ exitCode : 0
714+ } )
715+ . mockResolvedValueOnce ( {
716+ stdout : 'ghi789' ,
717+ stderr : '' ,
718+ exitCode : 0
719+ } )
720+ const result = await getPreviousGitTag ( {
721+ cwd : '.' ,
722+ tagsPattern : '*' ,
723+ tagsIgnorePattern : 'v0.*.*'
724+ } )
725+ expect ( result ) . toEqual ( { tag : 'v1.0.0' , sha : 'ghi789' } )
726+ } )
727+
728+ // Function executes silently when debug mode is not active
729+ it ( 'should execute silently when debug mode is not active' , async ( ) => {
730+ jest . spyOn ( core , 'isDebug' ) . mockReturnValue ( false )
731+ const spy = jest
732+ . spyOn ( exec , 'getExecOutput' )
733+ . mockResolvedValueOnce ( {
734+ stdout : 'v1.0.1\nv1.0.0' ,
735+ stderr : '' ,
736+ exitCode : 0
737+ } )
738+ . mockResolvedValueOnce ( {
739+ stdout : 'jkl012' ,
740+ stderr : '' ,
741+ exitCode : 0
742+ } )
743+ await getPreviousGitTag ( {
744+ cwd : '.' ,
745+ tagsPattern : '*' ,
746+ tagsIgnorePattern : ''
747+ } )
748+ expect ( spy ) . toHaveBeenCalledWith ( 'git' , [ 'tag' , '--sort=-creatordate' ] , {
749+ cwd : '.' ,
750+ silent : true
751+ } )
752+ } )
753+
754+ // No tags are available in the repository
755+ it ( 'should return empty values when no tags are available in the repository' , async ( ) => {
756+ jest . spyOn ( exec , 'getExecOutput' ) . mockResolvedValueOnce ( {
757+ stdout : '' ,
758+ stderr : '' ,
759+ exitCode : 0
760+ } )
761+ const result = await getPreviousGitTag ( {
762+ cwd : '.' ,
763+ tagsPattern : '*' ,
764+ tagsIgnorePattern : ''
765+ } )
766+ expect ( result ) . toEqual ( { tag : '' , sha : '' } )
767+ } )
768+
769+ // Only one tag is available, making it impossible to find a previous tag
770+ it ( 'should return empty values when only one tag is available' , async ( ) => {
771+ jest . spyOn ( exec , 'getExecOutput' ) . mockResolvedValueOnce ( {
772+ stdout : 'v1.0.1' ,
773+ stderr : '' ,
774+ exitCode : 0
775+ } )
776+ const result = await getPreviousGitTag ( {
777+ cwd : '.' ,
778+ tagsPattern : '*' ,
779+ tagsIgnorePattern : ''
780+ } )
781+ expect ( result ) . toEqual ( { tag : '' , sha : '' } )
782+ } )
783+
784+ // Provided 'tagsPattern' matches no tags
785+ it ( 'should return empty values when provided tagsPattern matches no tags' , async ( ) => {
786+ jest . spyOn ( exec , 'getExecOutput' ) . mockResolvedValueOnce ( {
787+ stdout : 'v1.0.1\nv1.0.0' ,
788+ stderr : '' ,
789+ exitCode : 0
790+ } )
791+ const result = await getPreviousGitTag ( {
792+ cwd : '.' ,
793+ tagsPattern : 'nonexistent*' ,
794+ tagsIgnorePattern : ''
795+ } )
796+ expect ( result ) . toEqual ( { tag : '' , sha : '' } )
797+ } )
798+
799+ // Provided 'tagsIgnorePattern' excludes all tags
800+ it ( 'should return empty values when provided tagsIgnorePattern excludes all tags' , async ( ) => {
801+ jest . spyOn ( exec , 'getExecOutput' ) . mockResolvedValueOnce ( {
802+ stdout : 'v1.0.1\nv1.0.0' ,
803+ stderr : '' ,
804+ exitCode : 0
805+ } )
806+ const result = await getPreviousGitTag ( {
807+ cwd : '.' ,
808+ tagsPattern : '*' ,
809+ tagsIgnorePattern : 'v*'
810+ } )
811+ expect ( result ) . toEqual ( { tag : '' , sha : '' } )
812+ } )
813+
814+ // Git commands fail and throw errors
815+ it ( 'should throw an error when git commands fail' , async ( ) => {
816+ jest
817+ . spyOn ( exec , 'getExecOutput' )
818+ . mockRejectedValue ( new Error ( 'git command failed' ) )
819+ await expect (
820+ getPreviousGitTag ( { cwd : '.' , tagsPattern : '*' , tagsIgnorePattern : '' } )
821+ ) . rejects . toThrow ( 'git command failed' )
822+ } )
823+
824+ // Debug mode logs additional information
825+ it ( 'should log additional information when debug mode is active' , async ( ) => {
826+ jest . spyOn ( core , 'isDebug' ) . mockReturnValue ( true )
827+ const spy = jest
828+ . spyOn ( exec , 'getExecOutput' )
829+ . mockResolvedValueOnce ( {
830+ stdout : 'v1.0.1\nv1.0.0' ,
831+ stderr : '' ,
832+ exitCode : 0
833+ } )
834+ . mockResolvedValueOnce ( {
835+ stdout : 'mno345' ,
836+ stderr : '' ,
837+ exitCode : 0
838+ } )
839+ await getPreviousGitTag ( {
840+ cwd : '.' ,
841+ tagsPattern : '*' ,
842+ tagsIgnorePattern : ''
843+ } )
844+ expect ( spy ) . toHaveBeenCalledWith ( 'git' , [ 'tag' , '--sort=-creatordate' ] , {
845+ cwd : '.' ,
846+ silent : false
847+ } )
848+ } )
849+ } )
657850} )
0 commit comments