88import { platformTypes } from '@orginjs/oss-evaluation-util' ;
99import { getValidToken , refreshValidToken } from '../util/util.js' ;
1010
11- const nonPreReleasePredicate = release => ! release . prerelease && ! release . draft ;
12-
1311async function fetchGithubLatestRelease ( owner , repo ) {
1412 const token = await getValidToken ( platformTypes . GITHUB ) ;
1513 const url = `https://api.github.com/repos/${ owner } /${ repo } /releases` ;
@@ -32,7 +30,9 @@ async function fetchGithubLatestRelease(owner, repo) {
3230 return null ;
3331 }
3432 const releases = await response . json ( ) ;
35- const stable = releases . find ( nonPreReleasePredicate ) ;
33+ const stable = releases . find (
34+ r => ! r . prerelease && ! r . draft && r . tag_name && r . published_at ,
35+ ) ;
3636 return stable
3737 ? {
3838 tagName : stable . tag_name ,
@@ -67,12 +67,15 @@ async function fetchGiteeLatestRelease(owner, repo) {
6767 }
6868 const releases = await response . json ( ) ;
6969 if ( ! Array . isArray ( releases ) || releases . length === 0 ) return null ;
70- const stable = releases . find ( r => ! r . prerelease ) ;
71- const picked = stable || releases [ 0 ] ;
72- return {
73- tagName : picked . tag_name || picked . tag || '' ,
74- publishedAt : picked . created_at || picked . updated_at || '' ,
75- } ;
70+ const stable = releases . find (
71+ r => ! r . prerelease && ( r . tag_name || r . tag ) && ( r . created_at || r . updated_at ) ,
72+ ) ;
73+ return stable
74+ ? {
75+ tagName : stable . tag_name || stable . tag || '' ,
76+ publishedAt : stable . created_at || stable . updated_at || '' ,
77+ }
78+ : null ;
7679 } catch ( e ) {
7780 logger . warn ( `[Release] Gitee fetch error ${ owner } /${ repo } : ${ e . message } ` ) ;
7881 return null ;
@@ -86,7 +89,7 @@ async function fetchGitcodeLatestRelease(owner, repo) {
8689 page : '1' ,
8790 } ) ;
8891 if ( token ) params . set ( 'access_token' , token ) ;
89- const url = `https://api.gitcode.com/api/v5/projects /${ owner } /${ repo } /releases?${ params . toString ( ) } ` ;
92+ const url = `https://api.gitcode.com/api/v5/repos /${ owner } /${ repo } /releases?${ params . toString ( ) } ` ;
9093
9194 try {
9295 const response = await fetch ( url ) ;
@@ -101,12 +104,15 @@ async function fetchGitcodeLatestRelease(owner, repo) {
101104 }
102105 const releases = await response . json ( ) ;
103106 if ( ! Array . isArray ( releases ) || releases . length === 0 ) return null ;
104- const stable = releases . find ( r => ! r . prerelease ) ;
105- const picked = stable || releases [ 0 ] ;
106- return {
107- tagName : picked . tag_name || picked . tag || '' ,
108- publishedAt : picked . created_at || picked . updated_at || '' ,
109- } ;
107+ const stable = releases . find (
108+ r => ! r . prerelease && ( r . tag_name || r . tag ) && ( r . created_at || r . updated_at ) ,
109+ ) ;
110+ return stable
111+ ? {
112+ tagName : stable . tag_name || stable . tag || '' ,
113+ publishedAt : stable . created_at || stable . updated_at || '' ,
114+ }
115+ : null ;
110116 } catch ( e ) {
111117 logger . warn ( `[Release] GitCode fetch error ${ owner } /${ repo } : ${ e . message } ` ) ;
112118 return null ;
@@ -125,43 +131,61 @@ const tableMap = {
125131 [ platformTypes . GITCODE ] : GitcodeProjectsTable ,
126132} ;
127133
128- async function syncSingleProjectRelease ( project ) {
134+ export const RELEASE_SYNC_STATUS = Object . freeze ( {
135+ UPDATED : 'updated' ,
136+ SKIPPED : 'skipped' ,
137+ FAILED : 'failed' ,
138+ } ) ;
139+
140+ export async function syncSingleProjectRelease ( project ) {
129141 const platformType = project . platformType ;
130142 const fullName = project . fullName ;
143+
131144 if ( ! fullName ) {
132145 logger . warn ( `[Release] project missing fullName, pId=${ project . pId } ` ) ;
133- return ;
146+ return RELEASE_SYNC_STATUS . FAILED ;
134147 }
148+
135149 const parts = fullName . split ( '/' ) ;
136150 if ( parts . length < 2 ) {
137151 logger . warn ( `[Release] invalid fullName "${ fullName } ", pId=${ project . pId } ` ) ;
138- return ;
152+ return RELEASE_SYNC_STATUS . FAILED ;
139153 }
140154 const [ owner , repo ] = parts ;
155+
141156 const fetcher = fetchers [ platformType ] ;
142157 if ( ! fetcher ) {
143158 logger . warn ( `[Release] unsupported platformType=${ platformType } ` ) ;
144- return ;
159+ return RELEASE_SYNC_STATUS . SKIPPED ;
145160 }
146161
147162 const info = await fetcher ( owner , repo ) ;
148163 if ( ! info ) {
149- logger . info ( `[Release] no release for ${ fullName } ` ) ;
150- return ;
164+ logger . info ( `[Release] no stable release for ${ fullName } ` ) ;
165+ return RELEASE_SYNC_STATUS . SKIPPED ;
151166 }
152167
153168 const Model = tableMap [ platformType ] ;
154169 const [ platformRaw , idRaw ] = project . pId . split ( '#' ) ;
155- await Model . update (
170+ const [ affectedRows ] = await Model . update (
156171 {
157172 latestReleaseTagName : info . tagName ,
158173 latestReleasePublishedAt : info . publishedAt ,
159174 } ,
160175 { where : { platformType : Number ( platformRaw ) , id : Number ( idRaw ) } } ,
161176 ) ;
177+
178+ if ( ! affectedRows ) {
179+ logger . warn (
180+ `[Release] no row updated for ${ fullName } (pId=${ project . pId } )` ,
181+ ) ;
182+ return RELEASE_SYNC_STATUS . FAILED ;
183+ }
184+
162185 logger . info (
163186 `[Release] synced ${ fullName } : tag=${ info . tagName } , published_at=${ info . publishedAt } ` ,
164187 ) ;
188+ return RELEASE_SYNC_STATUS . UPDATED ;
165189}
166190
167191export async function syncSingleProjectReleaseHandler ( req , res ) {
@@ -173,11 +197,12 @@ export async function syncSingleProjectReleaseHandler(req, res) {
173197 project = await ViewProjects . findOne ( { where : { pId : req . body . pId } } ) ;
174198 }
175199 if ( ! project ) {
176- res . status ( 404 ) . json ( { error : 'Project not found' } ) ;
200+ res . status ( 404 ) . json ( { ok : false , error : 'Project not found' } ) ;
177201 return ;
178202 }
179- await syncSingleProjectRelease ( project ) ;
180- res . status ( 200 ) . json ( { ok : true , pId : project . pId } ) ;
203+ const status = await syncSingleProjectRelease ( project ) ;
204+ const ok = status === RELEASE_SYNC_STATUS . UPDATED ;
205+ res . status ( 200 ) . json ( { ok, pId : project . pId , status } ) ;
181206}
182207
183208export async function syncAllProjectReleaseHandler ( req , res ) {
@@ -204,20 +229,24 @@ export async function syncAllProjectReleaseHandler(req, res) {
204229
205230 let okCount = 0 ;
206231 let skipCount = 0 ;
232+ let failCount = 0 ;
207233 for ( const p of projects ) {
208234 try {
209- await syncSingleProjectRelease ( p ) ;
210- okCount += 1 ;
235+ const status = await syncSingleProjectRelease ( p ) ;
236+ if ( status === RELEASE_SYNC_STATUS . UPDATED ) okCount += 1 ;
237+ else if ( status === RELEASE_SYNC_STATUS . SKIPPED ) skipCount += 1 ;
238+ else failCount += 1 ;
211239 } catch ( e ) {
212- skipCount += 1 ;
240+ failCount += 1 ;
213241 logger . error ( `[Release] batch error ${ p . pId } : ${ e . message } ` ) ;
214242 }
215243 }
216244
217245 logger . info (
218- `[Release] batch sync done: ok =${ okCount } , skip =${ skipCount } , total=${ projects . length } ` ,
246+ `[Release] batch sync done: updated =${ okCount } , skipped =${ skipCount } , failed= ${ failCount } , total=${ projects . length } ` ,
219247 ) ;
220- res . status ( 200 ) . json ( { ok : true , total : projects . length , okCount, skipCount } ) ;
248+ res
249+ . status ( 200 )
250+ . json ( { ok : true , total : projects . length , okCount, skipCount, failCount } ) ;
221251}
222252
223- export { syncSingleProjectRelease } ;
0 commit comments