mirror of
				https://git.mirrors.martin98.com/https://github.com/actions/setup-python
				synced 2025-10-31 18:21:06 +08:00 
			
		
		
		
	Add check-latest functionality (#406)
This commit is contained in:
		
							parent
							
								
									49a521fa06
								
							
						
					
					
						commit
						2f06e9da25
					
				
							
								
								
									
										33
									
								
								.github/workflows/test-pypy.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								.github/workflows/test-pypy.yml
									
									
									
									
										vendored
									
									
								
							| @ -91,3 +91,36 @@ jobs: | ||||
| 
 | ||||
|       - name: Run simple code | ||||
|         run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))' | ||||
| 
 | ||||
|   check-latest: | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: [ubuntu-latest, windows-latest, macos-latest] | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - name: Setup PyPy and check latest | ||||
|         uses: ./ | ||||
|         with: | ||||
|           python-version: 'pypy-3.7-v7.3.x' | ||||
|           check-latest: true | ||||
|       - name: PyPy and Python version | ||||
|         run: python --version | ||||
| 
 | ||||
|       - name: Run simple code | ||||
|         run: python -c 'import math; print(math.factorial(5))' | ||||
| 
 | ||||
|       - name: Assert PyPy is running | ||||
|         run: | | ||||
|           import platform | ||||
|           assert platform.python_implementation().lower() == "pypy" | ||||
|         shell: python | ||||
| 
 | ||||
|       - name: Assert expected binaries (or symlinks) are present | ||||
|         run: | | ||||
|           EXECUTABLE="pypy-3.7-v7.3.x" | ||||
|           EXECUTABLE=${EXECUTABLE/-/}  # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name | ||||
|           EXECUTABLE=${EXECUTABLE%%-*}  # remove any -* suffixe | ||||
|           ${EXECUTABLE} --version | ||||
|         shell: bash | ||||
							
								
								
									
										24
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							| @ -172,3 +172,27 @@ jobs: | ||||
| 
 | ||||
|     - name: Run simple code | ||||
|       run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))' | ||||
| 
 | ||||
|   check-latest: | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: [ubuntu-latest, windows-latest, macos-latest] | ||||
|         python-version: ["3.8", "3.9", "3.10"] | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - name: Setup Python and check latest | ||||
|         uses: ./ | ||||
|         with: | ||||
|           python-version: ${{ matrix.python-version }} | ||||
|           check-latest: true | ||||
|       - name: Validate version | ||||
|         run: | | ||||
|           $pythonVersion = (python --version) | ||||
|           if ("$pythonVersion" -NotMatch "${{ matrix.python }}"){ | ||||
|             Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}" | ||||
|             exit 1 | ||||
|           } | ||||
|           $pythonVersion | ||||
|         shell: pwsh | ||||
							
								
								
									
										32
									
								
								.licenses/npm/@actions/http-client.dep.yml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										32
									
								
								.licenses/npm/@actions/http-client.dep.yml
									
									
									
										generated
									
									
									
								
							| @ -1,32 +0,0 @@ | ||||
| --- | ||||
| name: "@actions/http-client" | ||||
| version: 1.0.11 | ||||
| type: npm | ||||
| summary: Actions Http Client | ||||
| homepage: https://github.com/actions/http-client#readme | ||||
| license: mit | ||||
| licenses: | ||||
| - sources: LICENSE | ||||
|   text: | | ||||
|     Actions Http Client for Node.js | ||||
| 
 | ||||
|     Copyright (c) GitHub, Inc. | ||||
| 
 | ||||
|     All rights reserved. | ||||
| 
 | ||||
|     MIT License | ||||
| 
 | ||||
|     Permission is hereby granted, free of charge, to any person obtaining a copy of this software and | ||||
|     associated documentation files (the "Software"), to deal in the Software without restriction, | ||||
|     including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|     and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, | ||||
|     subject to the following conditions: | ||||
| 
 | ||||
|     The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||||
| 
 | ||||
|     THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT | ||||
|     LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||||
|     NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||||
|     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||||
|     SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| notices: [] | ||||
							
								
								
									
										18
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								README.md
									
									
									
									
									
								
							| @ -259,6 +259,24 @@ pypy3.7-nightly or pypy-3.7-nightly # Python 3.7 and nightly PyPy | ||||
| 
 | ||||
| Note: `pypy2` and `pypy3` have been removed in v3. Use the format above instead. | ||||
| 
 | ||||
| # Check latest version | ||||
| 
 | ||||
| The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific `Python/PyPy` version is always used. | ||||
| 
 | ||||
| If `check-latest` is set to `true`, the action first checks if the cached version is the latest one. If the locally cached version is not the most up-to-date, a `Python/PyPy` version will then be downloaded. Set `check-latest` to `true` if you want the most up-to-date `Python/PyPy` version to always be used. | ||||
| 
 | ||||
| > Setting `check-latest` to `true` has performance implications as downloading `Python/PyPy` versions is slower than using cached versions. | ||||
| 
 | ||||
| ```yaml | ||||
| steps: | ||||
|   - uses: actions/checkout@v3 | ||||
|   - uses: actions/setup-python@v3 | ||||
|     with: | ||||
|       python-version: '3.7' | ||||
|       check-latest: true | ||||
|   - run: python my_script.py | ||||
| ``` | ||||
| 
 | ||||
| # Caching packages dependencies | ||||
| 
 | ||||
| The action has built-in functionality for caching and restoring dependencies. It uses [actions/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip`, `pipenv` and `poetry`. The `cache` input is optional, and caching is turned off by default. | ||||
|  | ||||
| @ -14,7 +14,6 @@ import * as finder from '../src/find-pypy'; | ||||
| import { | ||||
|   IPyPyManifestRelease, | ||||
|   IS_WINDOWS, | ||||
|   validateVersion, | ||||
|   getPyPyVersionFromPath | ||||
| } from '../src/utils'; | ||||
| 
 | ||||
| @ -82,6 +81,12 @@ describe('findPyPyToolCache', () => { | ||||
|   const pypyPath = path.join('PyPy', actualPythonVersion, architecture); | ||||
|   let tcFind: jest.SpyInstance; | ||||
|   let spyReadExactPyPyVersion: jest.SpyInstance; | ||||
|   let infoSpy: jest.SpyInstance; | ||||
|   let warningSpy: jest.SpyInstance; | ||||
|   let debugSpy: jest.SpyInstance; | ||||
|   let addPathSpy: jest.SpyInstance; | ||||
|   let exportVariableSpy: jest.SpyInstance; | ||||
|   let setOutputSpy: jest.SpyInstance; | ||||
| 
 | ||||
|   beforeEach(() => { | ||||
|     tcFind = jest.spyOn(tc, 'find'); | ||||
| @ -94,6 +99,24 @@ describe('findPyPyToolCache', () => { | ||||
| 
 | ||||
|     spyReadExactPyPyVersion = jest.spyOn(utils, 'readExactPyPyVersionFile'); | ||||
|     spyReadExactPyPyVersion.mockImplementation(() => actualPyPyVersion); | ||||
| 
 | ||||
|     infoSpy = jest.spyOn(core, 'info'); | ||||
|     infoSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     warningSpy = jest.spyOn(core, 'warning'); | ||||
|     warningSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     debugSpy = jest.spyOn(core, 'debug'); | ||||
|     debugSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     addPathSpy = jest.spyOn(core, 'addPath'); | ||||
|     addPathSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     exportVariableSpy = jest.spyOn(core, 'exportVariable'); | ||||
|     exportVariableSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     setOutputSpy = jest.spyOn(core, 'setOutput'); | ||||
|     setOutputSpy.mockImplementation(() => null); | ||||
|   }); | ||||
| 
 | ||||
|   afterEach(() => { | ||||
| @ -136,6 +159,13 @@ describe('findPyPyToolCache', () => { | ||||
| }); | ||||
| 
 | ||||
| describe('findPyPyVersion', () => { | ||||
|   let getBooleanInputSpy: jest.SpyInstance; | ||||
|   let warningSpy: jest.SpyInstance; | ||||
|   let debugSpy: jest.SpyInstance; | ||||
|   let infoSpy: jest.SpyInstance; | ||||
|   let addPathSpy: jest.SpyInstance; | ||||
|   let exportVariableSpy: jest.SpyInstance; | ||||
|   let setOutputSpy: jest.SpyInstance; | ||||
|   let tcFind: jest.SpyInstance; | ||||
|   let spyExtractZip: jest.SpyInstance; | ||||
|   let spyExtractTar: jest.SpyInstance; | ||||
| @ -154,6 +184,27 @@ describe('findPyPyVersion', () => { | ||||
|   const env = process.env; | ||||
| 
 | ||||
|   beforeEach(() => { | ||||
|     getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput'); | ||||
|     getBooleanInputSpy.mockImplementation(() => false); | ||||
| 
 | ||||
|     infoSpy = jest.spyOn(core, 'info'); | ||||
|     infoSpy.mockImplementation(() => {}); | ||||
| 
 | ||||
|     warningSpy = jest.spyOn(core, 'warning'); | ||||
|     warningSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     debugSpy = jest.spyOn(core, 'debug'); | ||||
|     debugSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     addPathSpy = jest.spyOn(core, 'addPath'); | ||||
|     addPathSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     exportVariableSpy = jest.spyOn(core, 'exportVariable'); | ||||
|     exportVariableSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     setOutputSpy = jest.spyOn(core, 'setOutput'); | ||||
|     setOutputSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     jest.resetModules(); | ||||
|     process.env = {...env}; | ||||
|     tcFind = jest.spyOn(tc, 'find'); | ||||
| @ -222,7 +273,7 @@ describe('findPyPyVersion', () => { | ||||
| 
 | ||||
|   it('found PyPy in toolcache', async () => { | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, true) | ||||
|       finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, true, false) | ||||
|     ).resolves.toEqual({ | ||||
|       resolvedPythonVersion: '3.6.12', | ||||
|       resolvedPyPyVersion: '7.3.3' | ||||
| @ -240,13 +291,13 @@ describe('findPyPyVersion', () => { | ||||
| 
 | ||||
|   it('throw on invalid input format', async () => { | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true) | ||||
|       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false) | ||||
|     ).rejects.toThrow(); | ||||
|   }); | ||||
| 
 | ||||
|   it('throw on invalid input format pypy3.7-7.3.x', async () => { | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true) | ||||
|       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false) | ||||
|     ).rejects.toThrow(); | ||||
|   }); | ||||
| 
 | ||||
| @ -258,7 +309,7 @@ describe('findPyPyVersion', () => { | ||||
|     spyChmodSync = jest.spyOn(fs, 'chmodSync'); | ||||
|     spyChmodSync.mockImplementation(() => undefined); | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, true) | ||||
|       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, true, false) | ||||
|     ).resolves.toEqual({ | ||||
|       resolvedPythonVersion: '3.7.9', | ||||
|       resolvedPyPyVersion: '7.3.3' | ||||
| @ -282,7 +333,7 @@ describe('findPyPyVersion', () => { | ||||
|     spyChmodSync = jest.spyOn(fs, 'chmodSync'); | ||||
|     spyChmodSync.mockImplementation(() => undefined); | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false) | ||||
|       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, false) | ||||
|     ).resolves.toEqual({ | ||||
|       resolvedPythonVersion: '3.7.9', | ||||
|       resolvedPyPyVersion: '7.3.3' | ||||
| @ -293,9 +344,61 @@ describe('findPyPyVersion', () => { | ||||
| 
 | ||||
|   it('throw if release is not found', async () => { | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture, true) | ||||
|       finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture, true, false) | ||||
|     ).rejects.toThrowError( | ||||
|       `PyPy version 3.7 (v7.5.x) with arch ${architecture} not found` | ||||
|     ); | ||||
|   }); | ||||
| 
 | ||||
|   it('check-latest enabled version found and used from toolcache', async () => { | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, false, true) | ||||
|     ).resolves.toEqual({ | ||||
|       resolvedPythonVersion: '3.6.12', | ||||
|       resolvedPyPyVersion: '7.3.3' | ||||
|     }); | ||||
| 
 | ||||
|     expect(infoSpy).toHaveBeenCalledWith( | ||||
|       'Resolved as PyPy 7.3.3 with Python (3.6.12)' | ||||
|     ); | ||||
|   }); | ||||
| 
 | ||||
|   it('check-latest enabled version found and install successfully', async () => { | ||||
|     spyCacheDir = jest.spyOn(tc, 'cacheDir'); | ||||
|     spyCacheDir.mockImplementation(() => | ||||
|       path.join(toolDir, 'PyPy', '3.7.7', architecture) | ||||
|     ); | ||||
|     spyChmodSync = jest.spyOn(fs, 'chmodSync'); | ||||
|     spyChmodSync.mockImplementation(() => undefined); | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, true) | ||||
|     ).resolves.toEqual({ | ||||
|       resolvedPythonVersion: '3.7.9', | ||||
|       resolvedPyPyVersion: '7.3.3' | ||||
|     }); | ||||
|     expect(infoSpy).toHaveBeenCalledWith( | ||||
|       'Resolved as PyPy 7.3.3 with Python (3.7.9)' | ||||
|     ); | ||||
|   }); | ||||
| 
 | ||||
|   it('check-latest enabled version is not found and used from toolcache', async () => { | ||||
|     tcFind.mockImplementationOnce((tool: string, version: string) => { | ||||
|       const semverRange = new semver.Range(version); | ||||
|       let pypyPath = ''; | ||||
|       if (semver.satisfies('3.8.8', semverRange)) { | ||||
|         pypyPath = path.join(toolDir, 'PyPy', '3.8.8', architecture); | ||||
|       } | ||||
|       return pypyPath; | ||||
|     }); | ||||
|     await expect( | ||||
|       finder.findPyPyVersion('pypy-3.8-v7.3.x', architecture, false, true) | ||||
|     ).resolves.toEqual({ | ||||
|       resolvedPythonVersion: '3.8.8', | ||||
|       resolvedPyPyVersion: '7.3.3' | ||||
|     }); | ||||
| 
 | ||||
|     expect(infoSpy).toHaveBeenCalledWith( | ||||
|       'Failed to resolve PyPy v7.3.x with Python (3.8) from manifest' | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| import io = require('@actions/io'); | ||||
| import fs = require('fs'); | ||||
| import path = require('path'); | ||||
| import * as io from '@actions/io'; | ||||
| import os from 'os'; | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| 
 | ||||
| const toolDir = path.join( | ||||
|   __dirname, | ||||
| @ -26,11 +27,14 @@ import * as installer from '../src/install-python'; | ||||
| const manifestData = require('./data/versions-manifest.json'); | ||||
| 
 | ||||
| describe('Finder tests', () => { | ||||
|   let writeSpy: jest.SpyInstance; | ||||
|   let spyCoreAddPath: jest.SpyInstance; | ||||
|   let spyCoreExportVariable: jest.SpyInstance; | ||||
|   const env = process.env; | ||||
| 
 | ||||
|   beforeEach(() => { | ||||
|     writeSpy = jest.spyOn(process.stdout, 'write'); | ||||
|     writeSpy.mockImplementation(() => {}); | ||||
|     jest.resetModules(); | ||||
|     process.env = {...env}; | ||||
|     spyCoreAddPath = jest.spyOn(core, 'addPath'); | ||||
| @ -45,11 +49,14 @@ describe('Finder tests', () => { | ||||
|   }); | ||||
| 
 | ||||
|   it('Finds Python if it is installed', async () => { | ||||
|     const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput'); | ||||
|     getBooleanInputSpy.mockImplementation(input => false); | ||||
| 
 | ||||
|     const pythonDir: string = path.join(toolDir, 'Python', '3.0.0', 'x64'); | ||||
|     await io.mkdirP(pythonDir); | ||||
|     fs.writeFileSync(`${pythonDir}.complete`, 'hello'); | ||||
|     // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
 | ||||
|     await finder.useCpythonVersion('3.x', 'x64', true); | ||||
|     await finder.useCpythonVersion('3.x', 'x64', true, false); | ||||
|     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||
|     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||
|       'pythonLocation', | ||||
| @ -66,7 +73,7 @@ describe('Finder tests', () => { | ||||
|     await io.mkdirP(pythonDir); | ||||
|     fs.writeFileSync(`${pythonDir}.complete`, 'hello'); | ||||
|     // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
 | ||||
|     await finder.useCpythonVersion('3.x', 'x64', false); | ||||
|     await finder.useCpythonVersion('3.x', 'x64', false, false); | ||||
|     expect(spyCoreAddPath).not.toHaveBeenCalled(); | ||||
|     expect(spyCoreExportVariable).not.toHaveBeenCalled(); | ||||
|   }); | ||||
| @ -75,6 +82,9 @@ describe('Finder tests', () => { | ||||
|     const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo'); | ||||
|     findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData); | ||||
| 
 | ||||
|     const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput'); | ||||
|     getBooleanInputSpy.mockImplementation(input => false); | ||||
| 
 | ||||
|     const installSpy: jest.SpyInstance = jest.spyOn( | ||||
|       installer, | ||||
|       'installCpythonFromRelease' | ||||
| @ -85,7 +95,7 @@ describe('Finder tests', () => { | ||||
|       fs.writeFileSync(`${pythonDir}.complete`, 'hello'); | ||||
|     }); | ||||
|     // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
 | ||||
|     await finder.useCpythonVersion('1.2.3', 'x64', true); | ||||
|     await finder.useCpythonVersion('1.2.3', 'x64', true, false); | ||||
|     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||
|     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||
|       'pythonLocation', | ||||
| @ -101,6 +111,9 @@ describe('Finder tests', () => { | ||||
|     const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo'); | ||||
|     findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData); | ||||
| 
 | ||||
|     const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput'); | ||||
|     getBooleanInputSpy.mockImplementation(input => false); | ||||
| 
 | ||||
|     const installSpy: jest.SpyInstance = jest.spyOn( | ||||
|       installer, | ||||
|       'installCpythonFromRelease' | ||||
| @ -116,7 +129,65 @@ describe('Finder tests', () => { | ||||
|       fs.writeFileSync(`${pythonDir}.complete`, 'hello'); | ||||
|     }); | ||||
|     // This will throw if it doesn't find it in the manifest (because no such version exists)
 | ||||
|     await finder.useCpythonVersion('1.2.3-beta.2', 'x64', true); | ||||
|     await finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, false); | ||||
|   }); | ||||
| 
 | ||||
|   it('Check-latest true, finds the latest version in the manifest', async () => { | ||||
|     const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo'); | ||||
|     findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData); | ||||
| 
 | ||||
|     const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput'); | ||||
|     getBooleanInputSpy.mockImplementation(input => true); | ||||
| 
 | ||||
|     const cnSpy: jest.SpyInstance = jest.spyOn(process.stdout, 'write'); | ||||
|     cnSpy.mockImplementation(line => { | ||||
|       // uncomment to debug
 | ||||
|       // process.stderr.write('write:' + line + '\n');
 | ||||
|     }); | ||||
| 
 | ||||
|     const addPathSpy: jest.SpyInstance = jest.spyOn(core, 'addPath'); | ||||
|     addPathSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     const infoSpy: jest.SpyInstance = jest.spyOn(core, 'info'); | ||||
|     infoSpy.mockImplementation(() => {}); | ||||
| 
 | ||||
|     const debugSpy: jest.SpyInstance = jest.spyOn(core, 'debug'); | ||||
|     debugSpy.mockImplementation(() => {}); | ||||
| 
 | ||||
|     const pythonDir: string = path.join(toolDir, 'Python', '1.2.2', 'x64'); | ||||
|     const expPath: string = path.join(toolDir, 'Python', '1.2.3', 'x64'); | ||||
| 
 | ||||
|     const installSpy: jest.SpyInstance = jest.spyOn( | ||||
|       installer, | ||||
|       'installCpythonFromRelease' | ||||
|     ); | ||||
|     installSpy.mockImplementation(async () => { | ||||
|       await io.mkdirP(expPath); | ||||
|       fs.writeFileSync(`${expPath}.complete`, 'hello'); | ||||
|     }); | ||||
| 
 | ||||
|     const tcFindSpy: jest.SpyInstance = jest.spyOn(tc, 'find'); | ||||
|     tcFindSpy | ||||
|       .mockImplementationOnce(() => '') | ||||
|       .mockImplementationOnce(() => expPath); | ||||
| 
 | ||||
|     await io.mkdirP(pythonDir); | ||||
|     await io.rmRF(path.join(toolDir, 'Python', '1.2.3')); | ||||
| 
 | ||||
|     fs.writeFileSync(`${pythonDir}.complete`, 'hello'); | ||||
|     // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
 | ||||
|     await finder.useCpythonVersion('1.2', 'x64', true, true); | ||||
| 
 | ||||
|     expect(infoSpy).toHaveBeenCalledWith("Resolved as '1.2.3'"); | ||||
|     expect(infoSpy).toHaveBeenCalledWith( | ||||
|       'Version 1.2.3 was not found in the local cache' | ||||
|     ); | ||||
|     expect(infoSpy).toBeCalledWith( | ||||
|       'Version 1.2.3 is available for downloading' | ||||
|     ); | ||||
|     expect(installSpy).toHaveBeenCalled(); | ||||
|     expect(addPathSpy).toHaveBeenCalledWith(expPath); | ||||
|     await finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, true); | ||||
|     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||
|     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||
|       'pythonLocation', | ||||
| @ -132,7 +203,7 @@ describe('Finder tests', () => { | ||||
|     // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
 | ||||
|     let thrown = false; | ||||
|     try { | ||||
|       await finder.useCpythonVersion('3.300000', 'x64', true); | ||||
|       await finder.useCpythonVersion('3.300000', 'x64', true, false); | ||||
|     } catch { | ||||
|       thrown = true; | ||||
|     } | ||||
|  | ||||
| @ -4,6 +4,7 @@ import {HttpClient} from '@actions/http-client'; | ||||
| import * as ifm from '@actions/http-client/interfaces'; | ||||
| import * as tc from '@actions/tool-cache'; | ||||
| import * as exec from '@actions/exec'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as path from 'path'; | ||||
| 
 | ||||
| import * as installer from '../src/install-pypy'; | ||||
| @ -51,6 +52,22 @@ describe('findRelease', () => { | ||||
|     download_url: `https://test.download.python.org/pypy/pypy3.6-v7.3.3-${extensionName}` | ||||
|   }; | ||||
| 
 | ||||
|   let getBooleanInputSpy: jest.SpyInstance; | ||||
|   let warningSpy: jest.SpyInstance; | ||||
|   let debugSpy: jest.SpyInstance; | ||||
|   let infoSpy: jest.SpyInstance; | ||||
| 
 | ||||
|   beforeEach(() => { | ||||
|     infoSpy = jest.spyOn(core, 'info'); | ||||
|     infoSpy.mockImplementation(() => {}); | ||||
| 
 | ||||
|     warningSpy = jest.spyOn(core, 'warning'); | ||||
|     warningSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     debugSpy = jest.spyOn(core, 'debug'); | ||||
|     debugSpy.mockImplementation(() => null); | ||||
|   }); | ||||
| 
 | ||||
|   it("Python version is found, but PyPy version doesn't match", () => { | ||||
|     const pythonVersion = '3.6'; | ||||
|     const pypyVersion = '7.3.7'; | ||||
| @ -133,6 +150,10 @@ describe('findRelease', () => { | ||||
| 
 | ||||
| describe('installPyPy', () => { | ||||
|   let tcFind: jest.SpyInstance; | ||||
|   let getBooleanInputSpy: jest.SpyInstance; | ||||
|   let warningSpy: jest.SpyInstance; | ||||
|   let debugSpy: jest.SpyInstance; | ||||
|   let infoSpy: jest.SpyInstance; | ||||
|   let spyExtractZip: jest.SpyInstance; | ||||
|   let spyExtractTar: jest.SpyInstance; | ||||
|   let spyFsReadDir: jest.SpyInstance; | ||||
| @ -158,6 +179,15 @@ describe('installPyPy', () => { | ||||
|     spyExtractTar = jest.spyOn(tc, 'extractTar'); | ||||
|     spyExtractTar.mockImplementation(() => tempDir); | ||||
| 
 | ||||
|     infoSpy = jest.spyOn(core, 'info'); | ||||
|     infoSpy.mockImplementation(() => {}); | ||||
| 
 | ||||
|     warningSpy = jest.spyOn(core, 'warning'); | ||||
|     warningSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     debugSpy = jest.spyOn(core, 'debug'); | ||||
|     debugSpy.mockImplementation(() => null); | ||||
| 
 | ||||
|     spyFsReadDir = jest.spyOn(fs, 'readdirSync'); | ||||
|     spyFsReadDir.mockImplementation(() => ['PyPyTest']); | ||||
| 
 | ||||
| @ -194,7 +224,7 @@ describe('installPyPy', () => { | ||||
| 
 | ||||
|   it('throw if release is not found', async () => { | ||||
|     await expect( | ||||
|       installer.installPyPy('7.3.3', '3.6.17', architecture) | ||||
|       installer.installPyPy('7.3.3', '3.6.17', architecture, undefined) | ||||
|     ).rejects.toThrowError( | ||||
|       `PyPy version 3.6.17 (7.3.3) with arch ${architecture} not found` | ||||
|     ); | ||||
| @ -214,7 +244,7 @@ describe('installPyPy', () => { | ||||
|     spyChmodSync.mockImplementation(() => undefined); | ||||
| 
 | ||||
|     await expect( | ||||
|       installer.installPyPy('7.3.x', '3.6.12', architecture) | ||||
|       installer.installPyPy('7.3.x', '3.6.12', architecture, undefined) | ||||
|     ).resolves.toEqual({ | ||||
|       installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture), | ||||
|       resolvedPythonVersion: '3.6.12', | ||||
|  | ||||
| @ -12,6 +12,9 @@ inputs: | ||||
|     required: false | ||||
|   architecture: | ||||
|     description: 'The target architecture (x86, x64) of the Python interpreter.' | ||||
|   check-latest: | ||||
|     description: 'Set this option if you want the action to check for the latest available version that satisfies the version spec.' | ||||
|     default: false | ||||
|   token: | ||||
|     description: Used to pull python distributions from actions/python-versions. Since there's a default, this is typically not supplied by the user. | ||||
|     default: ${{ github.token }} | ||||
|  | ||||
							
								
								
									
										66
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										66
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							| @ -64685,19 +64685,34 @@ const utils_1 = __nccwpck_require__(1314); | ||||
| const semver = __importStar(__nccwpck_require__(1383)); | ||||
| const core = __importStar(__nccwpck_require__(2186)); | ||||
| const tc = __importStar(__nccwpck_require__(7784)); | ||||
| function findPyPyVersion(versionSpec, architecture, updateEnvironment) { | ||||
| function findPyPyVersion(versionSpec, architecture, updateEnvironment, checkLatest) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let resolvedPyPyVersion = ''; | ||||
|         let resolvedPythonVersion = ''; | ||||
|         let installDir; | ||||
|         let releases; | ||||
|         const pypyVersionSpec = parsePyPyVersion(versionSpec); | ||||
|         if (checkLatest) { | ||||
|             releases = yield pypyInstall.getAvailablePyPyVersions(); | ||||
|             if (releases && releases.length > 0) { | ||||
|                 const releaseData = pypyInstall.findRelease(releases, pypyVersionSpec.pythonVersion, pypyVersionSpec.pypyVersion, architecture); | ||||
|                 if (releaseData) { | ||||
|                     core.info(`Resolved as PyPy ${releaseData.resolvedPyPyVersion} with Python (${releaseData.resolvedPythonVersion})`); | ||||
|                     pypyVersionSpec.pythonVersion = releaseData.resolvedPythonVersion; | ||||
|                     pypyVersionSpec.pypyVersion = releaseData.resolvedPyPyVersion; | ||||
|                 } | ||||
|                 else { | ||||
|                     core.info(`Failed to resolve PyPy ${pypyVersionSpec.pypyVersion} with Python (${pypyVersionSpec.pythonVersion}) from manifest`); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         ({ installDir, resolvedPythonVersion, resolvedPyPyVersion } = findPyPyToolCache(pypyVersionSpec.pythonVersion, pypyVersionSpec.pypyVersion, architecture)); | ||||
|         if (!installDir) { | ||||
|             ({ | ||||
|                 installDir, | ||||
|                 resolvedPythonVersion, | ||||
|                 resolvedPyPyVersion | ||||
|             } = yield pypyInstall.installPyPy(pypyVersionSpec.pypyVersion, pypyVersionSpec.pythonVersion, architecture)); | ||||
|             } = yield pypyInstall.installPyPy(pypyVersionSpec.pypyVersion, pypyVersionSpec.pythonVersion, architecture, releases)); | ||||
|         } | ||||
|         const pipDir = utils_1.IS_WINDOWS ? 'Scripts' : 'bin'; | ||||
|         const _binDir = path.join(installDir, pipDir); | ||||
| @ -64847,15 +64862,28 @@ function binDir(installDir) { | ||||
|         return path.join(installDir, 'bin'); | ||||
|     } | ||||
| } | ||||
| function useCpythonVersion(version, architecture, updateEnvironment) { | ||||
| function useCpythonVersion(version, architecture, updateEnvironment, checkLatest) { | ||||
|     var _a; | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let manifest = null; | ||||
|         const desugaredVersionSpec = desugarDevVersion(version); | ||||
|         const semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); | ||||
|         let semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); | ||||
|         core.debug(`Semantic version spec of ${version} is ${semanticVersionSpec}`); | ||||
|         if (checkLatest) { | ||||
|             manifest = yield installer.getManifest(); | ||||
|             const resolvedVersion = (_a = (yield installer.findReleaseFromManifest(semanticVersionSpec, architecture, manifest))) === null || _a === void 0 ? void 0 : _a.version; | ||||
|             if (resolvedVersion) { | ||||
|                 semanticVersionSpec = resolvedVersion; | ||||
|                 core.info(`Resolved as '${semanticVersionSpec}'`); | ||||
|             } | ||||
|             else { | ||||
|                 core.info(`Failed to resolve version ${semanticVersionSpec} from manifest`); | ||||
|             } | ||||
|         } | ||||
|         let installDir = tc.find('Python', semanticVersionSpec, architecture); | ||||
|         if (!installDir) { | ||||
|             core.info(`Version ${semanticVersionSpec} was not found in the local cache`); | ||||
|             const foundRelease = yield installer.findReleaseFromManifest(semanticVersionSpec, architecture); | ||||
|             const foundRelease = yield installer.findReleaseFromManifest(semanticVersionSpec, architecture, manifest); | ||||
|             if (foundRelease && foundRelease.files && foundRelease.files.length > 0) { | ||||
|                 core.info(`Version ${semanticVersionSpec} is available for downloading`); | ||||
|                 yield installer.installCpythonFromRelease(foundRelease); | ||||
| @ -64974,7 +65002,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | ||||
|     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||
| exports.findAssetForMacOrLinux = exports.findAssetForWindows = exports.isArchPresentForMacOrLinux = exports.isArchPresentForWindows = exports.pypyVersionToSemantic = exports.getPyPyBinaryPath = exports.findRelease = exports.installPyPy = void 0; | ||||
| exports.findAssetForMacOrLinux = exports.findAssetForWindows = exports.isArchPresentForMacOrLinux = exports.isArchPresentForWindows = exports.pypyVersionToSemantic = exports.getPyPyBinaryPath = exports.findRelease = exports.getAvailablePyPyVersions = exports.installPyPy = void 0; | ||||
| const path = __importStar(__nccwpck_require__(1017)); | ||||
| const core = __importStar(__nccwpck_require__(2186)); | ||||
| const tc = __importStar(__nccwpck_require__(7784)); | ||||
| @ -64983,10 +65011,10 @@ const httpm = __importStar(__nccwpck_require__(9925)); | ||||
| const exec = __importStar(__nccwpck_require__(1514)); | ||||
| const fs_1 = __importDefault(__nccwpck_require__(7147)); | ||||
| const utils_1 = __nccwpck_require__(1314); | ||||
| function installPyPy(pypyVersion, pythonVersion, architecture) { | ||||
| function installPyPy(pypyVersion, pythonVersion, architecture, releases) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let downloadDir; | ||||
|         const releases = yield getAvailablePyPyVersions(); | ||||
|         releases = releases !== null && releases !== void 0 ? releases : (yield getAvailablePyPyVersions()); | ||||
|         if (!releases || releases.length === 0) { | ||||
|             throw new Error('No release was found in PyPy version.json'); | ||||
|         } | ||||
| @ -65032,6 +65060,7 @@ function getAvailablePyPyVersions() { | ||||
|         return response.result; | ||||
|     }); | ||||
| } | ||||
| exports.getAvailablePyPyVersions = getAvailablePyPyVersions; | ||||
| function createPyPySymlink(pypyBinaryPath, pythonVersion) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const version = semver.coerce(pythonVersion); | ||||
| @ -65154,7 +65183,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | ||||
|     }); | ||||
| }; | ||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||
| exports.installCpythonFromRelease = exports.findReleaseFromManifest = exports.MANIFEST_URL = void 0; | ||||
| exports.installCpythonFromRelease = exports.getManifest = exports.findReleaseFromManifest = exports.MANIFEST_URL = void 0; | ||||
| const path = __importStar(__nccwpck_require__(1017)); | ||||
| const core = __importStar(__nccwpck_require__(2186)); | ||||
| const tc = __importStar(__nccwpck_require__(7784)); | ||||
| @ -65166,13 +65195,21 @@ const MANIFEST_REPO_OWNER = 'actions'; | ||||
| const MANIFEST_REPO_NAME = 'python-versions'; | ||||
| const MANIFEST_REPO_BRANCH = 'main'; | ||||
| exports.MANIFEST_URL = `https://raw.githubusercontent.com/${MANIFEST_REPO_OWNER}/${MANIFEST_REPO_NAME}/${MANIFEST_REPO_BRANCH}/versions-manifest.json`; | ||||
| function findReleaseFromManifest(semanticVersionSpec, architecture) { | ||||
| function findReleaseFromManifest(semanticVersionSpec, architecture, manifest) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const manifest = yield tc.getManifestFromRepo(MANIFEST_REPO_OWNER, MANIFEST_REPO_NAME, AUTH, MANIFEST_REPO_BRANCH); | ||||
|         return yield tc.findFromManifest(semanticVersionSpec, false, manifest, architecture); | ||||
|         if (!manifest) { | ||||
|             manifest = yield getManifest(); | ||||
|         } | ||||
|         const foundRelease = yield tc.findFromManifest(semanticVersionSpec, false, manifest, architecture); | ||||
|         return foundRelease; | ||||
|     }); | ||||
| } | ||||
| exports.findReleaseFromManifest = findReleaseFromManifest; | ||||
| function getManifest() { | ||||
|     core.debug(`Getting manifest from ${MANIFEST_REPO_OWNER}/${MANIFEST_REPO_NAME}@${MANIFEST_REPO_BRANCH}`); | ||||
|     return tc.getManifestFromRepo(MANIFEST_REPO_OWNER, MANIFEST_REPO_NAME, AUTH, MANIFEST_REPO_BRANCH); | ||||
| } | ||||
| exports.getManifest = getManifest; | ||||
| function installPython(workingDirectory) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const options = { | ||||
| @ -65315,17 +65352,18 @@ function run() { | ||||
|         core.debug(`Python is expected to be installed into RUNNER_TOOL_CACHE=${process.env['RUNNER_TOOL_CACHE']}`); | ||||
|         try { | ||||
|             const version = resolveVersionInput(); | ||||
|             const checkLatest = core.getBooleanInput('check-latest'); | ||||
|             if (version) { | ||||
|                 let pythonVersion; | ||||
|                 const arch = core.getInput('architecture') || os.arch(); | ||||
|                 const updateEnvironment = core.getBooleanInput('update-environment'); | ||||
|                 if (isPyPyVersion(version)) { | ||||
|                     const installed = yield finderPyPy.findPyPyVersion(version, arch, updateEnvironment); | ||||
|                     const installed = yield finderPyPy.findPyPyVersion(version, arch, updateEnvironment, checkLatest); | ||||
|                     pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; | ||||
|                     core.info(`Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`); | ||||
|                 } | ||||
|                 else { | ||||
|                     const installed = yield finder.useCpythonVersion(version, arch, updateEnvironment); | ||||
|                     const installed = yield finder.useCpythonVersion(version, arch, updateEnvironment, checkLatest); | ||||
|                     pythonVersion = installed.version; | ||||
|                     core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||
|                 } | ||||
|  | ||||
| @ -6,7 +6,8 @@ import { | ||||
|   validateVersion, | ||||
|   getPyPyVersionFromPath, | ||||
|   readExactPyPyVersionFile, | ||||
|   validatePythonVersionFormatForPyPy | ||||
|   validatePythonVersionFormatForPyPy, | ||||
|   IPyPyManifestRelease | ||||
| } from './utils'; | ||||
| 
 | ||||
| import * as semver from 'semver'; | ||||
| @ -21,14 +22,40 @@ interface IPyPyVersionSpec { | ||||
| export async function findPyPyVersion( | ||||
|   versionSpec: string, | ||||
|   architecture: string, | ||||
|   updateEnvironment: boolean | ||||
|   updateEnvironment: boolean, | ||||
|   checkLatest: boolean | ||||
| ): Promise<{resolvedPyPyVersion: string; resolvedPythonVersion: string}> { | ||||
|   let resolvedPyPyVersion = ''; | ||||
|   let resolvedPythonVersion = ''; | ||||
|   let installDir: string | null; | ||||
|   let releases: IPyPyManifestRelease[] | undefined; | ||||
| 
 | ||||
|   const pypyVersionSpec = parsePyPyVersion(versionSpec); | ||||
| 
 | ||||
|   if (checkLatest) { | ||||
|     releases = await pypyInstall.getAvailablePyPyVersions(); | ||||
|     if (releases && releases.length > 0) { | ||||
|       const releaseData = pypyInstall.findRelease( | ||||
|         releases, | ||||
|         pypyVersionSpec.pythonVersion, | ||||
|         pypyVersionSpec.pypyVersion, | ||||
|         architecture | ||||
|       ); | ||||
| 
 | ||||
|       if (releaseData) { | ||||
|         core.info( | ||||
|           `Resolved as PyPy ${releaseData.resolvedPyPyVersion} with Python (${releaseData.resolvedPythonVersion})` | ||||
|         ); | ||||
|         pypyVersionSpec.pythonVersion = releaseData.resolvedPythonVersion; | ||||
|         pypyVersionSpec.pypyVersion = releaseData.resolvedPyPyVersion; | ||||
|       } else { | ||||
|         core.info( | ||||
|           `Failed to resolve PyPy ${pypyVersionSpec.pypyVersion} with Python (${pypyVersionSpec.pythonVersion}) from manifest` | ||||
|         ); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   ({installDir, resolvedPythonVersion, resolvedPyPyVersion} = findPyPyToolCache( | ||||
|     pypyVersionSpec.pythonVersion, | ||||
|     pypyVersionSpec.pypyVersion, | ||||
| @ -43,7 +70,8 @@ export async function findPyPyVersion( | ||||
|     } = await pypyInstall.installPyPy( | ||||
|       pypyVersionSpec.pypyVersion, | ||||
|       pypyVersionSpec.pythonVersion, | ||||
|       architecture | ||||
|       architecture, | ||||
|       releases | ||||
|     )); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -33,12 +33,34 @@ function binDir(installDir: string): string { | ||||
| export async function useCpythonVersion( | ||||
|   version: string, | ||||
|   architecture: string, | ||||
|   updateEnvironment: boolean | ||||
|   updateEnvironment: boolean, | ||||
|   checkLatest: boolean | ||||
| ): Promise<InstalledVersion> { | ||||
|   let manifest: tc.IToolRelease[] | null = null; | ||||
|   const desugaredVersionSpec = desugarDevVersion(version); | ||||
|   const semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); | ||||
|   let semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); | ||||
|   core.debug(`Semantic version spec of ${version} is ${semanticVersionSpec}`); | ||||
| 
 | ||||
|   if (checkLatest) { | ||||
|     manifest = await installer.getManifest(); | ||||
|     const resolvedVersion = ( | ||||
|       await installer.findReleaseFromManifest( | ||||
|         semanticVersionSpec, | ||||
|         architecture, | ||||
|         manifest | ||||
|       ) | ||||
|     )?.version; | ||||
| 
 | ||||
|     if (resolvedVersion) { | ||||
|       semanticVersionSpec = resolvedVersion; | ||||
|       core.info(`Resolved as '${semanticVersionSpec}'`); | ||||
|     } else { | ||||
|       core.info( | ||||
|         `Failed to resolve version ${semanticVersionSpec} from manifest` | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   let installDir: string | null = tc.find( | ||||
|     'Python', | ||||
|     semanticVersionSpec, | ||||
| @ -50,7 +72,8 @@ export async function useCpythonVersion( | ||||
|     ); | ||||
|     const foundRelease = await installer.findReleaseFromManifest( | ||||
|       semanticVersionSpec, | ||||
|       architecture | ||||
|       architecture, | ||||
|       manifest | ||||
|     ); | ||||
| 
 | ||||
|     if (foundRelease && foundRelease.files && foundRelease.files.length > 0) { | ||||
|  | ||||
| @ -19,11 +19,13 @@ import { | ||||
| export async function installPyPy( | ||||
|   pypyVersion: string, | ||||
|   pythonVersion: string, | ||||
|   architecture: string | ||||
|   architecture: string, | ||||
|   releases: IPyPyManifestRelease[] | undefined | ||||
| ) { | ||||
|   let downloadDir; | ||||
| 
 | ||||
|   const releases = await getAvailablePyPyVersions(); | ||||
|   releases = releases ?? (await getAvailablePyPyVersions()); | ||||
| 
 | ||||
|   if (!releases || releases.length === 0) { | ||||
|     throw new Error('No release was found in PyPy version.json'); | ||||
|   } | ||||
| @ -78,7 +80,7 @@ export async function installPyPy( | ||||
|   return {installDir, resolvedPythonVersion, resolvedPyPyVersion}; | ||||
| } | ||||
| 
 | ||||
| async function getAvailablePyPyVersions() { | ||||
| export async function getAvailablePyPyVersions() { | ||||
|   const url = 'https://downloads.python.org/pypy/versions.json'; | ||||
|   const http: httpm.HttpClient = new httpm.HttpClient('tool-cache'); | ||||
| 
 | ||||
|  | ||||
| @ -14,20 +14,33 @@ export const MANIFEST_URL = `https://raw.githubusercontent.com/${MANIFEST_REPO_O | ||||
| 
 | ||||
| export async function findReleaseFromManifest( | ||||
|   semanticVersionSpec: string, | ||||
|   architecture: string | ||||
|   architecture: string, | ||||
|   manifest: tc.IToolRelease[] | null | ||||
| ): Promise<tc.IToolRelease | undefined> { | ||||
|   const manifest: tc.IToolRelease[] = await tc.getManifestFromRepo( | ||||
|     MANIFEST_REPO_OWNER, | ||||
|     MANIFEST_REPO_NAME, | ||||
|     AUTH, | ||||
|     MANIFEST_REPO_BRANCH | ||||
|   ); | ||||
|   return await tc.findFromManifest( | ||||
|   if (!manifest) { | ||||
|     manifest = await getManifest(); | ||||
|   } | ||||
| 
 | ||||
|   const foundRelease = await tc.findFromManifest( | ||||
|     semanticVersionSpec, | ||||
|     false, | ||||
|     manifest, | ||||
|     architecture | ||||
|   ); | ||||
| 
 | ||||
|   return foundRelease; | ||||
| } | ||||
| 
 | ||||
| export function getManifest(): Promise<tc.IToolRelease[]> { | ||||
|   core.debug( | ||||
|     `Getting manifest from ${MANIFEST_REPO_OWNER}/${MANIFEST_REPO_NAME}@${MANIFEST_REPO_BRANCH}` | ||||
|   ); | ||||
|   return tc.getManifestFromRepo( | ||||
|     MANIFEST_REPO_OWNER, | ||||
|     MANIFEST_REPO_NAME, | ||||
|     AUTH, | ||||
|     MANIFEST_REPO_BRANCH | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| async function installPython(workingDirectory: string) { | ||||
|  | ||||
| @ -80,6 +80,8 @@ async function run() { | ||||
|   ); | ||||
|   try { | ||||
|     const version = resolveVersionInput(); | ||||
|     const checkLatest = core.getBooleanInput('check-latest'); | ||||
| 
 | ||||
|     if (version) { | ||||
|       let pythonVersion: string; | ||||
|       const arch: string = core.getInput('architecture') || os.arch(); | ||||
| @ -88,7 +90,8 @@ async function run() { | ||||
|         const installed = await finderPyPy.findPyPyVersion( | ||||
|           version, | ||||
|           arch, | ||||
|           updateEnvironment | ||||
|           updateEnvironment, | ||||
|           checkLatest | ||||
|         ); | ||||
|         pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; | ||||
|         core.info( | ||||
| @ -98,7 +101,8 @@ async function run() { | ||||
|         const installed = await finder.useCpythonVersion( | ||||
|           version, | ||||
|           arch, | ||||
|           updateEnvironment | ||||
|           updateEnvironment, | ||||
|           checkLatest | ||||
|         ); | ||||
|         pythonVersion = installed.version; | ||||
|         core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dmitry Shibanov
						Dmitry Shibanov