|
1 | 1 | import CoreGit from "#core/api/git"; |
| 2 | +import SemanticVersion from "#core/semantic-version"; |
2 | 3 | import GitChangelog from "./git/changelog.js"; |
3 | 4 |
|
4 | 5 | export default class Git extends CoreGit { |
@@ -59,4 +60,117 @@ export default class Git extends CoreGit { |
59 | 60 |
|
60 | 61 | return res; |
61 | 62 | } |
| 63 | + |
| 64 | + async getReleaseTags ( { allowMajorTag } = {} ) { |
| 65 | + const res = await this.getTags(); |
| 66 | + if ( !res.ok ) return res; |
| 67 | + |
| 68 | + const tags = {}; |
| 69 | + |
| 70 | + if ( res.data ) { |
| 71 | + for ( const [ tag, commit ] of Object.entries( res.data ) ) { |
| 72 | + const isMajorTag = /^v\d+$/.test( tag ); |
| 73 | + |
| 74 | + // release tag |
| 75 | + if ( /^v\d+\.\d+\.\d+/.test( tag ) ) { |
| 76 | + if ( !SemanticVersion.isValid( tag ) ) continue; |
| 77 | + |
| 78 | + const releaseVersion = new SemanticVersion( tag ); |
| 79 | + |
| 80 | + // next |
| 81 | + tags.next ??= {}; |
| 82 | + tags.next.version ??= releaseVersion; |
| 83 | + if ( releaseVersion.gt( tags.next.version ) ) { |
| 84 | + tags.next.version = releaseVersion; |
| 85 | + } |
| 86 | + |
| 87 | + // major.next |
| 88 | + const majorNextTag = `v${ releaseVersion.majorNumber }.next`; |
| 89 | + tags[ majorNextTag ] ??= {}; |
| 90 | + tags[ majorNextTag ].version ??= releaseVersion; |
| 91 | + if ( releaseVersion.gt( tags[ majorNextTag ].version ) ) { |
| 92 | + tags[ majorNextTag ].version = releaseVersion; |
| 93 | + } |
| 94 | + |
| 95 | + // stable release |
| 96 | + if ( releaseVersion.isStableRelease ) { |
| 97 | + |
| 98 | + // latest |
| 99 | + tags.latest ??= {}; |
| 100 | + tags.latest.version ??= releaseVersion; |
| 101 | + if ( releaseVersion.gt( tags.latest.version ) ) { |
| 102 | + tags.latest.version = releaseVersion; |
| 103 | + } |
| 104 | + |
| 105 | + // major.latest |
| 106 | + const majorLatestTag = `v${ releaseVersion.majorNumber }.latest`; |
| 107 | + tags[ majorLatestTag ] ??= {}; |
| 108 | + tags[ majorLatestTag ].version ??= releaseVersion; |
| 109 | + if ( releaseVersion.gt( tags[ majorLatestTag ].version ) ) { |
| 110 | + tags[ majorLatestTag ].version = releaseVersion; |
| 111 | + } |
| 112 | + |
| 113 | + // major |
| 114 | + const majorTag = `v${ releaseVersion.majorNumber }`; |
| 115 | + tags[ majorTag ] ??= { |
| 116 | + "isMajorTag": true, |
| 117 | + }; |
| 118 | + tags[ majorTag ].version = tags[ majorLatestTag ].version; |
| 119 | + } |
| 120 | + } |
| 121 | + else if ( tag === "latest" || tag === "next" || /^v\d+\.(?:latest|next)$/.test( tag ) || isMajorTag ) { |
| 122 | + tags[ tag ] ??= { |
| 123 | + isMajorTag, |
| 124 | + }; |
| 125 | + |
| 126 | + if ( commit.isRelease ) { |
| 127 | + tags[ tag ].current = commit.releaseVersion.version; |
| 128 | + } |
| 129 | + else { |
| 130 | + tags[ tag ].current = false; |
| 131 | + } |
| 132 | + } |
| 133 | + } |
| 134 | + } |
| 135 | + |
| 136 | + const releaseTags = {}; |
| 137 | + |
| 138 | + for ( const tag in tags ) { |
| 139 | + releaseTags[ tag ] = { |
| 140 | + "version": tags[ tag ].version?.version, |
| 141 | + "action": null, |
| 142 | + }; |
| 143 | + |
| 144 | + // tag is not set |
| 145 | + if ( tags[ tag ].current == null ) { |
| 146 | + if ( tags[ tag ].version ) { |
| 147 | + if ( !tags[ tag ].isMajorTag || allowMajorTag ) { |
| 148 | + releaseTags[ tag ].action = "update"; |
| 149 | + } |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + // major tag is set, but not allowed |
| 154 | + else if ( tags[ tag ].isMajorTag && !allowMajorTag ) { |
| 155 | + releaseTags[ tag ].action = "delete"; |
| 156 | + } |
| 157 | + |
| 158 | + // tag is set, but has no version |
| 159 | + else if ( !tags[ tag ].version ) { |
| 160 | + releaseTags[ tag ].action = "delete"; |
| 161 | + } |
| 162 | + |
| 163 | + // tag is set incorrectly |
| 164 | + else if ( tags[ tag ].current === false ) { |
| 165 | + releaseTags[ tag ].action = "update"; |
| 166 | + } |
| 167 | + |
| 168 | + // tag is set, but version is not valid |
| 169 | + else if ( tags[ tag ].current !== tags[ tag ].version.version ) { |
| 170 | + releaseTags[ tag ].action = "update"; |
| 171 | + } |
| 172 | + } |
| 173 | + |
| 174 | + return result( 200, releaseTags ); |
| 175 | + } |
62 | 176 | } |
0 commit comments