@@ -267,33 +267,70 @@ async function unpackRelease(
267267 return target
268268}
269269
270+ const MAX_RETRIES = 3
271+ const RETRY_DELAY_MS = 1000
272+
270273/**
271- * Fetch the latest Elide release from GitHub.
274+ * Fetch the latest Elide release from GitHub, with retry on transient failures .
272275 *
273276 * @param token GitHub token active for this workflow step.
274277 */
275278export async function resolveLatestVersion (
276279 token ?: string
277280) : Promise < ElideVersionInfo > {
281+ if ( ! token ) {
282+ core . warning (
283+ 'No GitHub token provided. API requests may be rate-limited. ' +
284+ 'Set the `token` input or ensure GITHUB_TOKEN is available.'
285+ )
286+ }
278287 const octokit = token ? github . getOctokit ( token ) : new Octokit ( { } )
279- const latest = await octokit . request (
280- 'GET /repos/{owner}/{repo}/releases/latest' ,
281- {
282- owner : 'elide-dev' ,
283- repo : 'elide' ,
284- headers : GITHUB_DEFAULT_HEADERS
285- }
286- )
287288
288- if ( ! latest ) {
289- throw new Error ( 'Failed to fetch the latest Elide version' )
290- }
291- const name = latest . data ?. name || undefined
292- return {
293- name,
294- tag_name : latest . data . tag_name ,
295- userProvided : ! ! token
289+ let lastError : Error | undefined
290+ for ( let attempt = 1 ; attempt <= MAX_RETRIES ; attempt ++ ) {
291+ try {
292+ const latest = await octokit . request (
293+ 'GET /repos/{owner}/{repo}/releases/latest' ,
294+ {
295+ owner : 'elide-dev' ,
296+ repo : 'elide' ,
297+ headers : GITHUB_DEFAULT_HEADERS
298+ }
299+ )
300+
301+ if ( ! latest ) {
302+ throw new Error ( 'Failed to fetch the latest Elide version' )
303+ }
304+ const name = latest . data ?. name || undefined
305+ return {
306+ name,
307+ tag_name : latest . data . tag_name ,
308+ userProvided : ! ! token
309+ }
310+ } catch ( err ) {
311+ lastError = err instanceof Error ? err : new Error ( String ( err ) )
312+ const isRateLimit =
313+ lastError . message . includes ( 'rate limit' ) ||
314+ lastError . message . includes ( 'quota exhausted' ) ||
315+ lastError . message . includes ( '403' ) ||
316+ lastError . message . includes ( '429' )
317+
318+ if ( attempt < MAX_RETRIES ) {
319+ const delay = RETRY_DELAY_MS * attempt
320+ core . warning (
321+ `GitHub API request failed (attempt ${ attempt } /${ MAX_RETRIES } ): ${ lastError . message } . Retrying in ${ delay } ms...`
322+ )
323+ await new Promise ( resolve => setTimeout ( resolve , delay ) )
324+ } else if ( isRateLimit ) {
325+ core . error (
326+ 'GitHub API rate limit exhausted. Provide a token via the `token` input to increase the limit.' ,
327+ { title : 'Rate Limited' }
328+ )
329+ }
330+ }
296331 }
332+
333+ throw lastError !
297334}
298335
299336/**
0 commit comments