@@ -34,8 +34,7 @@ const firstCommit = async () => {
34
34
} ;
35
35
36
36
exports . previousTagOrFirstCommit = async ( ) => {
37
- const { stdout} = await execa ( 'git' , [ 'tag' ] ) ;
38
- const tags = stdout . split ( '\n' ) ;
37
+ const tags = await exports . tagList ( ) ;
39
38
40
39
if ( tags . length === 0 ) {
41
40
return ;
@@ -45,7 +44,15 @@ exports.previousTagOrFirstCommit = async () => {
45
44
return firstCommit ( ) ;
46
45
}
47
46
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
+ }
49
56
} ;
50
57
51
58
exports . latestTagOrFirstCommit = async ( ) => {
@@ -80,6 +87,22 @@ exports.verifyCurrentBranchIsReleaseBranch = async releaseBranch => {
80
87
}
81
88
} ;
82
89
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
+
83
106
exports . isWorkingTreeClean = async ( ) => {
84
107
try {
85
108
const { stdout : status } = await execa ( 'git' , [ 'status' , '--porcelain' ] ) ;
0 commit comments