mirror of
				https://git.mirrors.martin98.com/https://github.com/actions/setup-python
				synced 2025-10-31 13:41:06 +08:00 
			
		
		
		
	Fix for Candidate Not Iterable Error (#1082)
* candidates not iterable * update the error message * update error to debug * update debug to info * error message updates
This commit is contained in:
		
							parent
							
								
									e348410e00
								
							
						
					
					
						commit
						6ed2c67c8a
					
				
							
								
								
									
										2
									
								
								.github/workflows/e2e-cache.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/e2e-cache.yml
									
									
									
									
										vendored
									
									
								
							| @ -82,6 +82,8 @@ jobs: | ||||
|             python-version: pypy-3.10-v7.x | ||||
|           - os: ubuntu-22.04-arm | ||||
|             python-version: pypy-3.11-v7.x | ||||
|           - os: ubuntu-22.04-arm | ||||
|             python-version: pypy-3.10-v7.x | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|       - name: Setup Python | ||||
|  | ||||
| @ -8,10 +8,29 @@ import * as tc from '@actions/tool-cache'; | ||||
| 
 | ||||
| jest.mock('@actions/http-client'); | ||||
| jest.mock('@actions/tool-cache'); | ||||
| 
 | ||||
| const mockManifest = [{version: '1.0.0'}]; | ||||
| jest.mock('@actions/tool-cache', () => ({ | ||||
|   getManifestFromRepo: jest.fn() | ||||
| })); | ||||
| const mockManifest = [ | ||||
|   { | ||||
|     version: '1.0.0', | ||||
|     stable: true, | ||||
|     files: [ | ||||
|       { | ||||
|         filename: 'tool-v1.0.0-linux-x64.tar.gz', | ||||
|         platform: 'linux', | ||||
|         arch: 'x64', | ||||
|         download_url: 'https://example.com/tool-v1.0.0-linux-x64.tar.gz' | ||||
|       } | ||||
|     ] | ||||
|   } | ||||
| ]; | ||||
| 
 | ||||
| describe('getManifest', () => { | ||||
|   beforeEach(() => { | ||||
|     jest.resetAllMocks(); | ||||
|   }); | ||||
| 
 | ||||
|   it('should return manifest from repo', async () => { | ||||
|     (tc.getManifestFromRepo as jest.Mock).mockResolvedValue(mockManifest); | ||||
|     const manifest = await getManifest(); | ||||
|  | ||||
							
								
								
									
										32
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							| @ -97461,16 +97461,36 @@ function findReleaseFromManifest(semanticVersionSpec, architecture, manifest) { | ||||
|     }); | ||||
| } | ||||
| exports.findReleaseFromManifest = findReleaseFromManifest; | ||||
| function isIToolRelease(obj) { | ||||
|     return (typeof obj === 'object' && | ||||
|         obj !== null && | ||||
|         typeof obj.version === 'string' && | ||||
|         typeof obj.stable === 'boolean' && | ||||
|         Array.isArray(obj.files) && | ||||
|         obj.files.every((file) => typeof file.filename === 'string' && | ||||
|             typeof file.platform === 'string' && | ||||
|             typeof file.arch === 'string' && | ||||
|             typeof file.download_url === 'string')); | ||||
| } | ||||
| function getManifest() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         try { | ||||
|             return yield getManifestFromRepo(); | ||||
|             const repoManifest = yield getManifestFromRepo(); | ||||
|             if (Array.isArray(repoManifest) && | ||||
|                 repoManifest.length && | ||||
|                 repoManifest.every(isIToolRelease)) { | ||||
|                 return repoManifest; | ||||
|             } | ||||
|             throw new Error('The repository manifest is invalid or does not include any valid tool release (IToolRelease) entries.'); | ||||
|         } | ||||
|         catch (err) { | ||||
|             core.debug('Fetching the manifest via the API failed.'); | ||||
|             if (err instanceof Error) { | ||||
|                 core.debug(err.message); | ||||
|             } | ||||
|             else { | ||||
|                 core.error('An unexpected error occurred while fetching the manifest.'); | ||||
|             } | ||||
|         } | ||||
|         return yield getManifestFromURL(); | ||||
|     }); | ||||
| @ -97518,6 +97538,9 @@ function installPython(workingDirectory) { | ||||
| } | ||||
| function installCpythonFromRelease(release) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         if (!release.files || release.files.length === 0) { | ||||
|             throw new Error('No files found in the release to download.'); | ||||
|         } | ||||
|         const downloadUrl = release.files[0].download_url; | ||||
|         core.info(`Download from "${downloadUrl}"`); | ||||
|         let pythonPath = ''; | ||||
| @ -97538,8 +97561,11 @@ function installCpythonFromRelease(release) { | ||||
|         catch (err) { | ||||
|             if (err instanceof tc.HTTPError) { | ||||
|                 // Rate limit?
 | ||||
|                 if (err.httpStatusCode === 403 || err.httpStatusCode === 429) { | ||||
|                     core.info(`Received HTTP status code ${err.httpStatusCode}.  This usually indicates the rate limit has been exceeded`); | ||||
|                 if (err.httpStatusCode === 403) { | ||||
|                     core.error(`Received HTTP status code 403. This indicates a permission issue or restricted access.`); | ||||
|                 } | ||||
|                 else if (err.httpStatusCode === 429) { | ||||
|                     core.info(`Received HTTP status code 429.  This usually indicates the rate limit has been exceeded`); | ||||
|                 } | ||||
|                 else { | ||||
|                     core.info(err.message); | ||||
|  | ||||
| @ -5,6 +5,7 @@ import * as exec from '@actions/exec'; | ||||
| import * as httpm from '@actions/http-client'; | ||||
| import {ExecOptions} from '@actions/exec/lib/interfaces'; | ||||
| import {IS_WINDOWS, IS_LINUX, getDownloadFileName} from './utils'; | ||||
| import {IToolRelease} from '@actions/tool-cache'; | ||||
| 
 | ||||
| const TOKEN = core.getInput('token'); | ||||
| const AUTH = !TOKEN ? undefined : `token ${TOKEN}`; | ||||
| @ -31,14 +32,41 @@ export async function findReleaseFromManifest( | ||||
| 
 | ||||
|   return foundRelease; | ||||
| } | ||||
| 
 | ||||
| function isIToolRelease(obj: any): obj is IToolRelease { | ||||
|   return ( | ||||
|     typeof obj === 'object' && | ||||
|     obj !== null && | ||||
|     typeof obj.version === 'string' && | ||||
|     typeof obj.stable === 'boolean' && | ||||
|     Array.isArray(obj.files) && | ||||
|     obj.files.every( | ||||
|       (file: any) => | ||||
|         typeof file.filename === 'string' && | ||||
|         typeof file.platform === 'string' && | ||||
|         typeof file.arch === 'string' && | ||||
|         typeof file.download_url === 'string' | ||||
|     ) | ||||
|   ); | ||||
| } | ||||
| export async function getManifest(): Promise<tc.IToolRelease[]> { | ||||
|   try { | ||||
|     return await getManifestFromRepo(); | ||||
|     const repoManifest = await getManifestFromRepo(); | ||||
|     if ( | ||||
|       Array.isArray(repoManifest) && | ||||
|       repoManifest.length && | ||||
|       repoManifest.every(isIToolRelease) | ||||
|     ) { | ||||
|       return repoManifest; | ||||
|     } | ||||
|     throw new Error( | ||||
|       'The repository manifest is invalid or does not include any valid tool release (IToolRelease) entries.' | ||||
|     ); | ||||
|   } catch (err) { | ||||
|     core.debug('Fetching the manifest via the API failed.'); | ||||
|     if (err instanceof Error) { | ||||
|       core.debug(err.message); | ||||
|     } else { | ||||
|       core.error('An unexpected error occurred while fetching the manifest.'); | ||||
|     } | ||||
|   } | ||||
|   return await getManifestFromURL(); | ||||
| @ -93,6 +121,9 @@ async function installPython(workingDirectory: string) { | ||||
| } | ||||
| 
 | ||||
| export async function installCpythonFromRelease(release: tc.IToolRelease) { | ||||
|   if (!release.files || release.files.length === 0) { | ||||
|     throw new Error('No files found in the release to download.'); | ||||
|   } | ||||
|   const downloadUrl = release.files[0].download_url; | ||||
| 
 | ||||
|   core.info(`Download from "${downloadUrl}"`); | ||||
| @ -113,9 +144,13 @@ export async function installCpythonFromRelease(release: tc.IToolRelease) { | ||||
|   } catch (err) { | ||||
|     if (err instanceof tc.HTTPError) { | ||||
|       // Rate limit?
 | ||||
|       if (err.httpStatusCode === 403 || err.httpStatusCode === 429) { | ||||
|       if (err.httpStatusCode === 403) { | ||||
|         core.error( | ||||
|           `Received HTTP status code 403. This indicates a permission issue or restricted access.` | ||||
|         ); | ||||
|       } else if (err.httpStatusCode === 429) { | ||||
|         core.info( | ||||
|           `Received HTTP status code ${err.httpStatusCode}.  This usually indicates the rate limit has been exceeded` | ||||
|           `Received HTTP status code 429.  This usually indicates the rate limit has been exceeded` | ||||
|         ); | ||||
|       } else { | ||||
|         core.info(err.message); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 aparnajyothi-y
						aparnajyothi-y