@@ -5,6 +5,7 @@ import * as exec from '@actions/exec';
55import * as httpm from '@actions/http-client' ;
66import { ExecOptions } from '@actions/exec/lib/interfaces' ;
77import { IS_WINDOWS , IS_LINUX , getDownloadFileName } from './utils' ;
8+ import { IToolRelease } from '@actions/tool-cache' ;
89
910const TOKEN = core . getInput ( 'token' ) ;
1011const AUTH = ! TOKEN ? undefined : `token ${ TOKEN } ` ;
@@ -31,14 +32,41 @@ export async function findReleaseFromManifest(
3132
3233 return foundRelease ;
3334}
34-
35+ function isIToolRelease ( obj : any ) : obj is IToolRelease {
36+ return (
37+ typeof obj === 'object' &&
38+ obj !== null &&
39+ typeof obj . version === 'string' &&
40+ typeof obj . stable === 'boolean' &&
41+ Array . isArray ( obj . files ) &&
42+ obj . files . every (
43+ ( file : any ) =>
44+ typeof file . filename === 'string' &&
45+ typeof file . platform === 'string' &&
46+ typeof file . arch === 'string' &&
47+ typeof file . download_url === 'string'
48+ )
49+ ) ;
50+ }
3551export async function getManifest ( ) : Promise < tc . IToolRelease [ ] > {
3652 try {
37- return await getManifestFromRepo ( ) ;
53+ const repoManifest = await getManifestFromRepo ( ) ;
54+ if (
55+ Array . isArray ( repoManifest ) &&
56+ repoManifest . length &&
57+ repoManifest . every ( isIToolRelease )
58+ ) {
59+ return repoManifest ;
60+ }
61+ throw new Error (
62+ 'The repository manifest is invalid or does not include any valid tool release (IToolRelease) entries.'
63+ ) ;
3864 } catch ( err ) {
3965 core . debug ( 'Fetching the manifest via the API failed.' ) ;
4066 if ( err instanceof Error ) {
4167 core . debug ( err . message ) ;
68+ } else {
69+ core . error ( 'An unexpected error occurred while fetching the manifest.' ) ;
4270 }
4371 }
4472 return await getManifestFromURL ( ) ;
@@ -93,6 +121,9 @@ async function installPython(workingDirectory: string) {
93121}
94122
95123export async function installCpythonFromRelease ( release : tc . IToolRelease ) {
124+ if ( ! release . files || release . files . length === 0 ) {
125+ throw new Error ( 'No files found in the release to download.' ) ;
126+ }
96127 const downloadUrl = release . files [ 0 ] . download_url ;
97128
98129 core . info ( `Download from "${ downloadUrl } "` ) ;
@@ -113,9 +144,13 @@ export async function installCpythonFromRelease(release: tc.IToolRelease) {
113144 } catch ( err ) {
114145 if ( err instanceof tc . HTTPError ) {
115146 // Rate limit?
116- if ( err . httpStatusCode === 403 || err . httpStatusCode === 429 ) {
147+ if ( err . httpStatusCode === 403 ) {
148+ core . error (
149+ `Received HTTP status code 403. This indicates a permission issue or restricted access.`
150+ ) ;
151+ } else if ( err . httpStatusCode === 429 ) {
117152 core . info (
118- `Received HTTP status code ${ err . httpStatusCode } . This usually indicates the rate limit has been exceeded`
153+ `Received HTTP status code 429 . This usually indicates the rate limit has been exceeded`
119154 ) ;
120155 } else {
121156 core . info ( err . message ) ;
0 commit comments