mirror of
				https://kkgithub.com/actions/setup-python.git
				synced 2025-10-31 02:31:52 +08:00 
			
		
		
		
	Install multiple python versions (#567)
This commit is contained in:
		
							
								
								
									
										42
									
								
								.github/workflows/test-pypy.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								.github/workflows/test-pypy.yml
									
									
									
									
										vendored
									
									
								
							| @ -124,4 +124,46 @@ jobs: | ||||
|           EXECUTABLE=${EXECUTABLE/-/}  # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name | ||||
|           EXECUTABLE=${EXECUTABLE%%-*}  # remove any -* suffixe | ||||
|           ${EXECUTABLE} --version | ||||
|         shell: bash | ||||
|  | ||||
|   setup-pypy-multiple-versions: | ||||
|     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 | ||||
|               pypy3.8 | ||||
|           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 | ||||
|       - name: Assert expected binaries (or symlinks) are present | ||||
|         run: | | ||||
|           EXECUTABLE='pypy3.8' | ||||
|           EXECUTABLE=${EXECUTABLE/pypy-/pypy}  # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name | ||||
|           EXECUTABLE=${EXECUTABLE%%-*}  # remove any -* suffixe | ||||
|           ${EXECUTABLE} --version | ||||
|         shell: bash | ||||
							
								
								
									
										31
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							| @ -191,8 +191,35 @@ jobs: | ||||
|       - name: Validate version | ||||
|         run: | | ||||
|           $pythonVersion = (python --version) | ||||
|           if ("$pythonVersion" -NotMatch "${{ matrix.python }}"){ | ||||
|             Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}" | ||||
|           if ("$pythonVersion" -NotMatch "${{ matrix.python-version }}"){ | ||||
|             Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python-version }}" | ||||
|             exit 1 | ||||
|           } | ||||
|           $pythonVersion | ||||
|         shell: pwsh | ||||
|  | ||||
|   setup-python-multiple-python-versions: | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: [ubuntu-latest, windows-latest, macos-latest] | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - name: Setup Python and check latest | ||||
|         uses: ./ | ||||
|         with: | ||||
|           python-version: | | ||||
|               3.7 | ||||
|               3.8 | ||||
|               3.9 | ||||
|               3.10 | ||||
|           check-latest: true | ||||
|       - name: Validate version | ||||
|         run: | | ||||
|           $pythonVersion = (python --version) | ||||
|           if ("$pythonVersion" -NotMatch "3.10"){ | ||||
|             Write-Host "The current version is $pythonVersion; expected version is 3.10" | ||||
|             exit 1 | ||||
|           } | ||||
|           $pythonVersion | ||||
|  | ||||
							
								
								
									
										46
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							| @ -66867,31 +66867,31 @@ function cacheDependencies(cache, pythonVersion) { | ||||
|     }); | ||||
| } | ||||
| function resolveVersionInput() { | ||||
|     let version = core.getInput('python-version'); | ||||
|     let versions = core.getMultilineInput('python-version'); | ||||
|     let versionFile = core.getInput('python-version-file'); | ||||
|     if (version && versionFile) { | ||||
|     if (versions.length && versionFile) { | ||||
|         core.warning('Both python-version and python-version-file inputs are specified, only python-version will be used.'); | ||||
|     } | ||||
|     if (version) { | ||||
|         return version; | ||||
|     if (versions.length) { | ||||
|         return versions; | ||||
|     } | ||||
|     if (versionFile) { | ||||
|         if (!fs_1.default.existsSync(versionFile)) { | ||||
|             throw new Error(`The specified python version file at: ${versionFile} doesn't exist.`); | ||||
|         } | ||||
|         version = fs_1.default.readFileSync(versionFile, 'utf8'); | ||||
|         const version = fs_1.default.readFileSync(versionFile, 'utf8'); | ||||
|         core.info(`Resolved ${versionFile} as ${version}`); | ||||
|         return version; | ||||
|         return [version]; | ||||
|     } | ||||
|     utils_1.logWarning("Neither 'python-version' nor 'python-version-file' inputs were supplied. Attempting to find '.python-version' file."); | ||||
|     versionFile = '.python-version'; | ||||
|     if (fs_1.default.existsSync(versionFile)) { | ||||
|         version = fs_1.default.readFileSync(versionFile, 'utf8'); | ||||
|         const version = fs_1.default.readFileSync(versionFile, 'utf8'); | ||||
|         core.info(`Resolved ${versionFile} as ${version}`); | ||||
|         return version; | ||||
|         return [version]; | ||||
|     } | ||||
|     utils_1.logWarning(`${versionFile} doesn't exist.`); | ||||
|     return version; | ||||
|     return versions; | ||||
| } | ||||
| function run() { | ||||
|     var _a; | ||||
| @ -66904,22 +66904,26 @@ function run() { | ||||
|         } | ||||
|         core.debug(`Python is expected to be installed into ${process.env['RUNNER_TOOL_CACHE']}`); | ||||
|         try { | ||||
|             const version = resolveVersionInput(); | ||||
|             const versions = resolveVersionInput(); | ||||
|             const checkLatest = core.getBooleanInput('check-latest'); | ||||
|             if (version) { | ||||
|                 let pythonVersion; | ||||
|             if (versions.length) { | ||||
|                 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, 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, checkLatest); | ||||
|                     pythonVersion = installed.version; | ||||
|                     core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||
|                 core.startGroup('Installed versions'); | ||||
|                 for (const version of versions) { | ||||
|                     if (isPyPyVersion(version)) { | ||||
|                         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, checkLatest); | ||||
|                         pythonVersion = installed.version; | ||||
|                         core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||
|                     } | ||||
|                 } | ||||
|                 core.endGroup(); | ||||
|                 const cache = core.getInput('cache'); | ||||
|                 if (cache && utils_1.isCacheFeatureAvailable()) { | ||||
|                     yield cacheDependencies(cache, pythonVersion); | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| - [Using the python-version input](advanced-usage.md#using-the-python-version-input) | ||||
|     - [Specifying a Python version](advanced-usage.md#specifying-a-python-version) | ||||
|     - [Specifying a PyPy version](advanced-usage.md#specifying-a-pypy-version) | ||||
|     - [Specifying multiple Python and PyPy versions](advanced-usage.md#specifying-multiple-python/pypy-version) | ||||
|     - [Matrix Testing](advanced-usage.md#matrix-testing) | ||||
| - [Using the python-version-file input](advanced-usage.md#using-the-python-version-file-input) | ||||
| - [Check latest version](advanced-usage.md#check-latest-version) | ||||
| @ -132,6 +133,62 @@ jobs: | ||||
| ``` | ||||
| More details on PyPy syntax can be found in the [Available versions of PyPy](#pypy) section. | ||||
|  | ||||
| ### Specifying multiple Python/PyPy version | ||||
| The python-version input can get multiple python/pypy versions. The last specified version will be used as a default one.  | ||||
|  | ||||
| Download and set up multiple Python versions: | ||||
|  | ||||
| ```yaml | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|     - uses: actions/setup-python@v4 | ||||
|       with: | ||||
|         python-version: | | ||||
|             3.8 | ||||
|             3.9 | ||||
|             3.10 | ||||
|     - run: python my_script.py | ||||
| ``` | ||||
|  | ||||
| Download and set up multiple PyPy versions: | ||||
|  | ||||
| ```yaml | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|     - uses: actions/setup-python@v4 | ||||
|       with: | ||||
|         python-version: | | ||||
|             pypy-3.7-v7.3.x | ||||
|             pypy3.9-nightly | ||||
|             pypy3.8 | ||||
|     - run: python my_script.py | ||||
| ``` | ||||
|  | ||||
| Download and set up multiple Python/PyPy versions: | ||||
|  | ||||
| ```yaml | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|     - uses: actions/setup-python@v4 | ||||
|       with: | ||||
|         python-version: | | ||||
|             3.8 | ||||
|             3.9 | ||||
|             pypy3.9-nightly | ||||
|             pypy3.8 | ||||
|             3.10 | ||||
|     - run: python my_script.py | ||||
| ``` | ||||
|  | ||||
| ### Matrix Testing | ||||
|  | ||||
| Using `setup-python` it's possible to use [matrix syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) to install several versions of Python or PyPy: | ||||
|  | ||||
| @ -22,18 +22,18 @@ async function cacheDependencies(cache: string, pythonVersion: string) { | ||||
|   await cacheDistributor.restoreCache(); | ||||
| } | ||||
|  | ||||
| function resolveVersionInput(): string { | ||||
|   let version = core.getInput('python-version'); | ||||
| function resolveVersionInput() { | ||||
|   let versions = core.getMultilineInput('python-version'); | ||||
|   let versionFile = core.getInput('python-version-file'); | ||||
|  | ||||
|   if (version && versionFile) { | ||||
|   if (versions.length && versionFile) { | ||||
|     core.warning( | ||||
|       'Both python-version and python-version-file inputs are specified, only python-version will be used.' | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   if (version) { | ||||
|     return version; | ||||
|   if (versions.length) { | ||||
|     return versions; | ||||
|   } | ||||
|  | ||||
|   if (versionFile) { | ||||
| @ -42,9 +42,9 @@ function resolveVersionInput(): string { | ||||
|         `The specified python version file at: ${versionFile} doesn't exist.` | ||||
|       ); | ||||
|     } | ||||
|     version = fs.readFileSync(versionFile, 'utf8'); | ||||
|     const version = fs.readFileSync(versionFile, 'utf8'); | ||||
|     core.info(`Resolved ${versionFile} as ${version}`); | ||||
|     return version; | ||||
|     return [version]; | ||||
|   } | ||||
|  | ||||
|   logWarning( | ||||
| @ -52,14 +52,14 @@ function resolveVersionInput(): string { | ||||
|   ); | ||||
|   versionFile = '.python-version'; | ||||
|   if (fs.existsSync(versionFile)) { | ||||
|     version = fs.readFileSync(versionFile, 'utf8'); | ||||
|     const version = fs.readFileSync(versionFile, 'utf8'); | ||||
|     core.info(`Resolved ${versionFile} as ${version}`); | ||||
|     return version; | ||||
|     return [version]; | ||||
|   } | ||||
|  | ||||
|   logWarning(`${versionFile} doesn't exist.`); | ||||
|  | ||||
|   return version; | ||||
|   return versions; | ||||
| } | ||||
|  | ||||
| async function run() { | ||||
| @ -75,35 +75,38 @@ async function run() { | ||||
|     `Python is expected to be installed into ${process.env['RUNNER_TOOL_CACHE']}` | ||||
|   ); | ||||
|   try { | ||||
|     const version = resolveVersionInput(); | ||||
|     const versions = resolveVersionInput(); | ||||
|     const checkLatest = core.getBooleanInput('check-latest'); | ||||
|  | ||||
|     if (version) { | ||||
|       let pythonVersion: string; | ||||
|     if (versions.length) { | ||||
|       let pythonVersion = ''; | ||||
|       const arch: string = core.getInput('architecture') || os.arch(); | ||||
|       const updateEnvironment = core.getBooleanInput('update-environment'); | ||||
|       if (isPyPyVersion(version)) { | ||||
|         const installed = await 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 = await finder.useCpythonVersion( | ||||
|           version, | ||||
|           arch, | ||||
|           updateEnvironment, | ||||
|           checkLatest | ||||
|         ); | ||||
|         pythonVersion = installed.version; | ||||
|         core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||
|       core.startGroup('Installed versions'); | ||||
|       for (const version of versions) { | ||||
|         if (isPyPyVersion(version)) { | ||||
|           const installed = await 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 = await finder.useCpythonVersion( | ||||
|             version, | ||||
|             arch, | ||||
|             updateEnvironment, | ||||
|             checkLatest | ||||
|           ); | ||||
|           pythonVersion = installed.version; | ||||
|           core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       core.endGroup(); | ||||
|       const cache = core.getInput('cache'); | ||||
|       if (cache && isCacheFeatureAvailable()) { | ||||
|         await cacheDependencies(cache, pythonVersion); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Dmitry Shibanov
					Dmitry Shibanov