1- import { ENDPOINT , MM_REGEX , BUILD_REGEX } from './constants' ;
2- import { Platform , Version , Versions , parsePlatform } from '../structures/versioning' ;
1+ import { ENDPOINT , MM_REGEX , BUILD_REGEX , GITHUB_RELEASES_ENDPOINT , GITHUB_ASSET_REGEX } from './constants' ;
2+ import { Platform , Version , GithubVersion , Versions , parsePlatform } from '../structures/versioning' ;
33import { HttpClient } from 'typed-rest-client/HttpClient' ;
4+ import { BearerCredentialHandler } from 'typed-rest-client/Handlers' ;
45import to from 'await-to-js' ;
6+ import { warning , getInput } from '@actions/core' ;
57
68const client = new HttpClient ( 'setup-sp' ) ;
79
10+ function getGithubClient ( ) : HttpClient {
11+ const token = getInput ( 'github-token' ) || process . env . GITHUB_TOKEN ;
12+ if ( token ) {
13+ return new HttpClient ( 'setup-sp' , [ new BearerCredentialHandler ( token ) ] ) ;
14+ }
15+ return new HttpClient ( 'setup-sp' ) ;
16+ }
17+
818export async function getVersions ( ) : Promise < Versions > {
19+ const results = await Promise . allSettled ( [
20+ getSmDropVersions ( ) ,
21+ getGithubVersions ( ) ,
22+ ] ) ;
23+
24+ let versions : Versions = { } ;
25+
26+ if ( results [ 0 ] . status === 'fulfilled' ) {
27+ Object . assign ( versions , results [ 0 ] . value ) ;
28+ } else {
29+ warning ( `Failed to fetch versions from smdrop: ${ results [ 0 ] . reason } ` ) ;
30+ }
31+
32+ if ( results [ 1 ] . status === 'fulfilled' ) {
33+ // GitHub releases take precedence over smdrop for overlapping builds
34+ Object . assign ( versions , results [ 1 ] . value ) ;
35+ } else {
36+ warning ( `Failed to fetch versions from GitHub releases: ${ results [ 1 ] . reason } ` ) ;
37+ }
38+
39+ if ( Object . keys ( versions ) . length === 0 ) {
40+ throw new Error ( 'Failed to fetch SourceMod versions from all sources' ) ;
41+ }
42+
43+ return versions ;
44+ }
45+
46+ async function getSmDropVersions ( ) : Promise < Versions > {
947 const [ err , res ] = await to ( client . get ( ENDPOINT ) ) ;
1048
1149 if ( err || ! res || res . message . statusCode !== 200 ) {
@@ -14,10 +52,6 @@ export async function getVersions(): Promise<Versions> {
1452
1553 let versions : Versions = { } ;
1654
17- if ( err ) {
18- return versions ;
19- }
20-
2155 const body = await res . readBody ( ) ;
2256
2357 let match , promises : Promise < void > [ ] = [ ] ;
@@ -44,6 +78,68 @@ export async function getVersions(): Promise<Versions> {
4478 return versions ;
4579}
4680
81+ async function getGithubVersions ( ) : Promise < Versions > {
82+ const githubClient = getGithubClient ( ) ;
83+ let versions : Versions = { } ;
84+ let page = 1 ;
85+ const perPage = 100 ;
86+
87+ while ( true ) {
88+ const url = `${ GITHUB_RELEASES_ENDPOINT } ?per_page=${ perPage } &page=${ page } ` ;
89+ const [ err , res ] = await to ( githubClient . get ( url ) ) ;
90+
91+ if ( err || ! res || res . message . statusCode !== 200 ) {
92+ if ( page === 1 ) {
93+ throw new Error ( `Failed to fetch releases from GitHub: ${ err ?. message ?? res ?. message . statusCode } ` ) ;
94+ }
95+ break ;
96+ }
97+
98+ const body = await res . readBody ( ) ;
99+ const releases : any [ ] = JSON . parse ( body ) ;
100+
101+ if ( ! releases || releases . length === 0 ) {
102+ break ;
103+ }
104+
105+ for ( const release of releases ) {
106+ if ( ! release . tag_name ) continue ;
107+
108+ // Tag format: "1.13.0.7316"
109+ const tagParts = release . tag_name . split ( '.' ) ;
110+ if ( tagParts . length !== 4 ) continue ;
111+
112+ const major = parseInt ( tagParts [ 0 ] ) ;
113+ const minor = parseInt ( tagParts [ 1 ] ) ;
114+ const build = parseInt ( tagParts [ 3 ] ) ;
115+
116+ if ( isNaN ( major ) || isNaN ( minor ) || isNaN ( build ) ) continue ;
117+
118+ for ( const asset of release . assets as any [ ] ) {
119+ const match = GITHUB_ASSET_REGEX . exec ( asset . name ) ;
120+ if ( ! match ) continue ;
121+
122+ const platform = parsePlatform ( match [ 2 ] ) ;
123+
124+ if ( process . platform === 'win32' && platform !== Platform . Windows ) continue ;
125+ if ( process . platform === 'darwin' && platform !== Platform . Mac ) continue ;
126+ if ( process . platform === 'linux' && platform !== Platform . Linux ) continue ;
127+
128+ const v = new GithubVersion ( major , minor , build , platform , match [ 3 ] , asset . browser_download_url ) ;
129+ versions [ v . toString ( ) ] = v ;
130+ }
131+ }
132+
133+ if ( releases . length < perPage ) {
134+ break ;
135+ }
136+
137+ page ++ ;
138+ }
139+
140+ return versions ;
141+ }
142+
47143async function getBuilds ( endpoint : string , versions : Versions , major : number , minor : number ) {
48144 const [ err , res ] = await to ( client . get ( endpoint ) ) ;
49145
0 commit comments