@@ -34,8 +34,7 @@ const firstCommit = async () => {
3434} ;
3535
3636exports . previousTagOrFirstCommit = async ( ) => {
37- const { stdout} = await execa ( 'git' , [ 'tag' ] ) ;
38- const tags = stdout . split ( '\n' ) ;
37+ const tags = await exports . tagList ( ) ;
3938
4039 if ( tags . length === 0 ) {
4140 return ;
@@ -45,7 +44,15 @@ exports.previousTagOrFirstCommit = async () => {
4544 return firstCommit ( ) ;
4645 }
4746
48- return tags [ tags . length - 2 ] ;
47+ try {
48+ // Return the tag before the latest one.
49+ const latest = await exports . latestTag ( ) ;
50+ const index = tags . indexOf ( latest ) ;
51+ return tags [ index - 1 ] ;
52+ } catch {
53+ // Fallback to the first commit.
54+ return firstCommit ( ) ;
55+ }
4956} ;
5057
5158exports . latestTagOrFirstCommit = async ( ) => {
@@ -80,6 +87,22 @@ exports.verifyCurrentBranchIsReleaseBranch = async releaseBranch => {
8087 }
8188} ;
8289
90+ exports . tagList = async ( ) => {
91+ // Returns the list of tags, sorted by creation date in ascending order.
92+ const { stdout} = await execa ( 'git' , [ 'tag' , '--sort=creatordate' ] ) ;
93+ return stdout . split ( '\n' ) ;
94+ } ;
95+
96+ exports . isHeadDetached = async ( ) => {
97+ try {
98+ // Command will fail with code 1 if the HEAD is detached.
99+ await execa ( 'git' , [ 'symbolic-ref' , '--quiet' , 'HEAD' ] ) ;
100+ return false ;
101+ } catch {
102+ return true ;
103+ }
104+ } ;
105+
83106exports . isWorkingTreeClean = async ( ) => {
84107 try {
85108 const { stdout : status } = await execa ( 'git' , [ 'status' , '--porcelain' ] ) ;
0 commit comments