feature: fallback to pre-release when no stable version is found (#414)
This allows to specify version like `3.11` or `pypy3.10` in workflows before those versions are released. This lessen the burden for users of `setup-python` by not having to modify their workflow twice: once when a pre-release is available (e.g. `3.11-dev`) and once when the first stable release is published (e.g. `3.11`)
This commit is contained in:
		
							parent
							
								
									a6eba85bba
								
							
						
					
					
						commit
						2652534ead
					
				
							
								
								
									
										29
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							| @ -149,6 +149,35 @@ jobs: | |||||||
|     - name: Run simple code |     - name: Run simple code | ||||||
|       run: python -c 'import math; print(math.factorial(5))' |       run: python -c 'import math; print(math.factorial(5))' | ||||||
| 
 | 
 | ||||||
|  |   setup-prerelease-version: | ||||||
|  |     name: Setup 3.12 ${{ matrix.os }} | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         os: [macos-latest, windows-latest, ubuntu-latest] | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  | 
 | ||||||
|  |     - name: setup-python 3.12 | ||||||
|  |       id: setup-python | ||||||
|  |       uses: ./ | ||||||
|  |       with: | ||||||
|  |         python-version: '3.12' | ||||||
|  |         allow-prereleases: true | ||||||
|  | 
 | ||||||
|  |     - name: Check python-path | ||||||
|  |       run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' | ||||||
|  |       shell: bash | ||||||
|  | 
 | ||||||
|  |     - name: Validate version | ||||||
|  |       run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.12.') }} | ||||||
|  |       shell: bash | ||||||
|  | 
 | ||||||
|  |     - name: Run simple code | ||||||
|  |       run: python -c 'import math; print(math.factorial(5))' | ||||||
|  | 
 | ||||||
|   setup-versions-noenv: |   setup-versions-noenv: | ||||||
|     name: Setup ${{ matrix.python }} ${{ matrix.os }} (noenv) |     name: Setup ${{ matrix.python }} ${{ matrix.os }} (noenv) | ||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
|  | |||||||
| @ -85,6 +85,7 @@ See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poet | |||||||
| - [Hosted tool cache](docs/advanced-usage.md#hosted-tool-cache)  | - [Hosted tool cache](docs/advanced-usage.md#hosted-tool-cache)  | ||||||
| - [Using `setup-python` with a self-hosted runner](docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner) | - [Using `setup-python` with a self-hosted runner](docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner) | ||||||
| - [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes) | - [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes) | ||||||
|  | - [Allow pre-releases](docs/advanced-usage.md#allow-pre-releases) | ||||||
| 
 | 
 | ||||||
| ## License | ## License | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,94 @@ | |||||||
| [ | [ | ||||||
|  |   { | ||||||
|  |     "pypy_version": "7.3.8rc2", | ||||||
|  |     "python_version": "3.8.12", | ||||||
|  |     "stable": false, | ||||||
|  |     "latest_pypy": false, | ||||||
|  |     "date": "2022-02-11", | ||||||
|  |     "files": [ | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.8-v7.3.8rc2-linux32.tar.bz2", | ||||||
|  |         "arch": "i686", | ||||||
|  |         "platform": "linux", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-linux32.tar.bz2" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.8-v7.3.8rc2-linux64.tar.bz2", | ||||||
|  |         "arch": "x64", | ||||||
|  |         "platform": "linux", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-linux64.tar.bz2" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.8-v7.3.8rc2-darwin64.tar.bz2", | ||||||
|  |         "arch": "x64", | ||||||
|  |         "platform": "darwin", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-darwin64.tar.bz2" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.8-v7.3.8rc2-s390x.tar.bz2", | ||||||
|  |         "arch": "s390x", | ||||||
|  |         "platform": "linux", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-s390x.tar.bz2" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.8-v7.3.8rc2-win64.zip", | ||||||
|  |         "arch": "x64", | ||||||
|  |         "platform": "win64", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-win64.zip" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.8-v7.3.8rc2-win32.zip", | ||||||
|  |         "arch": "x86", | ||||||
|  |         "platform": "win32", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-win32.zip" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     "pypy_version": "7.4.0rc1", | ||||||
|  |     "python_version": "3.6.12", | ||||||
|  |     "stable": false, | ||||||
|  |     "latest_pypy": false, | ||||||
|  |     "date": "2021-11-11", | ||||||
|  |     "files": [ | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.6-v7.4.0rc1-aarch64.tar.bz2", | ||||||
|  |         "arch": "aarch64", | ||||||
|  |         "platform": "linux", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-aarch64.tar.bz2" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.6-v7.4.0rc1-linux32.tar.bz2", | ||||||
|  |         "arch": "i686", | ||||||
|  |         "platform": "linux", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-linux32.tar.bz2" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.6-v7.4.0rc1-linux64.tar.bz2", | ||||||
|  |         "arch": "x64", | ||||||
|  |         "platform": "linux", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-linux64.tar.bz2" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.6-v7.4.0rc1-darwin64.tar.bz2", | ||||||
|  |         "arch": "x64", | ||||||
|  |         "platform": "darwin", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-darwin64.tar.bz2" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.6-v7.4.0rc1-win32.zip", | ||||||
|  |         "arch": "x86", | ||||||
|  |         "platform": "win32", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-win32.zip" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "filename": "pypy3.6-v7.4.0rc1-s390x.tar.bz2", | ||||||
|  |         "arch": "s390x", | ||||||
|  |         "platform": "linux", | ||||||
|  |         "download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-s390x.tar.bz2" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|   { |   { | ||||||
|     "pypy_version": "7.3.3", |     "pypy_version": "7.3.3", | ||||||
|     "python_version": "3.6.12", |     "python_version": "3.6.12", | ||||||
|  | |||||||
| @ -1,4 +1,29 @@ | |||||||
| [ | [ | ||||||
|  |     { | ||||||
|  |       "version": "1.2.4-beta.2", | ||||||
|  |       "stable": false, | ||||||
|  |       "release_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5", | ||||||
|  |       "files": [ | ||||||
|  |         { | ||||||
|  |           "filename": "sometool-1.2.4-linux-x64.tar.gz", | ||||||
|  |           "arch": "x64", | ||||||
|  |           "platform": "linux", | ||||||
|  |           "download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-linux-x64.tar.gz" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "filename": "sometool-1.2.4-darwin-x64.tar.gz", | ||||||
|  |           "arch": "x64", | ||||||
|  |           "platform": "darwin", | ||||||
|  |           "download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-darwin-x64.tar.gz" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "filename": "sometool-1.2.4-win32-x64.tar.gz", | ||||||
|  |           "arch": "x64", | ||||||
|  |           "platform": "win32", | ||||||
|  |           "download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-win32-x64.tar.gz" | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|     { |     { | ||||||
|       "version": "1.2.3", |       "version": "1.2.3", | ||||||
|       "stable": true, |       "stable": true, | ||||||
| @ -25,27 +50,27 @@ | |||||||
|       ] |       ] | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "version": "1.2.3-beta.2", |       "version": "1.1.0-beta.2", | ||||||
|       "stable": false, |       "stable": false, | ||||||
|       "release_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5", |       "release_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5", | ||||||
|       "files": [ |       "files": [ | ||||||
|         { |         { | ||||||
|           "filename": "sometool-1.2.3-linux-x64.tar.gz", |           "filename": "sometool-1.1.0-linux-x64.tar.gz", | ||||||
|           "arch": "x64", |           "arch": "x64", | ||||||
|           "platform": "linux", |           "platform": "linux", | ||||||
|           "download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5/sometool-1.2.3-linux-x64.tar.gz" |           "download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-linux-x64.tar.gz" | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "filename": "sometool-1.2.3-darwin-x64.tar.gz", |           "filename": "sometool-1.1.0-darwin-x64.tar.gz", | ||||||
|           "arch": "x64", |           "arch": "x64", | ||||||
|           "platform": "darwin", |           "platform": "darwin", | ||||||
|           "download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-darwin-x64.tar.gz" |           "download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-darwin-x64.tar.gz" | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|           "filename": "sometool-1.2.3-win32-x64.tar.gz", |           "filename": "sometool-1.1.0-win32-x64.tar.gz", | ||||||
|           "arch": "x64", |           "arch": "x64", | ||||||
|           "platform": "win32", |           "platform": "win32", | ||||||
|           "download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-win32-x64.tar.gz" |           "download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-win32-x64.tar.gz" | ||||||
|         } |         } | ||||||
|       ] |       ] | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -273,7 +273,13 @@ describe('findPyPyVersion', () => { | |||||||
| 
 | 
 | ||||||
|   it('found PyPy in toolcache', async () => { |   it('found PyPy in toolcache', async () => { | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, true, false) |       finder.findPyPyVersion( | ||||||
|  |         'pypy-3.6-v7.3.x', | ||||||
|  |         architecture, | ||||||
|  |         true, | ||||||
|  |         false, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       resolvedPythonVersion: '3.6.12', |       resolvedPythonVersion: '3.6.12', | ||||||
|       resolvedPyPyVersion: '7.3.3' |       resolvedPyPyVersion: '7.3.3' | ||||||
| @ -291,13 +297,13 @@ describe('findPyPyVersion', () => { | |||||||
| 
 | 
 | ||||||
|   it('throw on invalid input format', async () => { |   it('throw on invalid input format', async () => { | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false) |       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false) | ||||||
|     ).rejects.toThrow(); |     ).rejects.toThrow(); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it('throw on invalid input format pypy3.7-7.3.x', async () => { |   it('throw on invalid input format pypy3.7-7.3.x', async () => { | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false) |       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false) | ||||||
|     ).rejects.toThrow(); |     ).rejects.toThrow(); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
| @ -309,7 +315,13 @@ describe('findPyPyVersion', () => { | |||||||
|     spyChmodSync = jest.spyOn(fs, 'chmodSync'); |     spyChmodSync = jest.spyOn(fs, 'chmodSync'); | ||||||
|     spyChmodSync.mockImplementation(() => undefined); |     spyChmodSync.mockImplementation(() => undefined); | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, true, false) |       finder.findPyPyVersion( | ||||||
|  |         'pypy-3.7-v7.3.x', | ||||||
|  |         architecture, | ||||||
|  |         true, | ||||||
|  |         false, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       resolvedPythonVersion: '3.7.9', |       resolvedPythonVersion: '3.7.9', | ||||||
|       resolvedPyPyVersion: '7.3.3' |       resolvedPyPyVersion: '7.3.3' | ||||||
| @ -333,7 +345,13 @@ describe('findPyPyVersion', () => { | |||||||
|     spyChmodSync = jest.spyOn(fs, 'chmodSync'); |     spyChmodSync = jest.spyOn(fs, 'chmodSync'); | ||||||
|     spyChmodSync.mockImplementation(() => undefined); |     spyChmodSync.mockImplementation(() => undefined); | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, false) |       finder.findPyPyVersion( | ||||||
|  |         'pypy-3.7-v7.3.x', | ||||||
|  |         architecture, | ||||||
|  |         false, | ||||||
|  |         false, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       resolvedPythonVersion: '3.7.9', |       resolvedPythonVersion: '3.7.9', | ||||||
|       resolvedPyPyVersion: '7.3.3' |       resolvedPyPyVersion: '7.3.3' | ||||||
| @ -344,7 +362,13 @@ describe('findPyPyVersion', () => { | |||||||
| 
 | 
 | ||||||
|   it('throw if release is not found', async () => { |   it('throw if release is not found', async () => { | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture, true, false) |       finder.findPyPyVersion( | ||||||
|  |         'pypy-3.7-v7.5.x', | ||||||
|  |         architecture, | ||||||
|  |         true, | ||||||
|  |         false, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).rejects.toThrowError( |     ).rejects.toThrowError( | ||||||
|       `PyPy version 3.7 (v7.5.x) with arch ${architecture} not found` |       `PyPy version 3.7 (v7.5.x) with arch ${architecture} not found` | ||||||
|     ); |     ); | ||||||
| @ -352,7 +376,13 @@ describe('findPyPyVersion', () => { | |||||||
| 
 | 
 | ||||||
|   it('check-latest enabled version found and used from toolcache', async () => { |   it('check-latest enabled version found and used from toolcache', async () => { | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, false, true) |       finder.findPyPyVersion( | ||||||
|  |         'pypy-3.6-v7.3.x', | ||||||
|  |         architecture, | ||||||
|  |         false, | ||||||
|  |         true, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       resolvedPythonVersion: '3.6.12', |       resolvedPythonVersion: '3.6.12', | ||||||
|       resolvedPyPyVersion: '7.3.3' |       resolvedPyPyVersion: '7.3.3' | ||||||
| @ -371,7 +401,13 @@ describe('findPyPyVersion', () => { | |||||||
|     spyChmodSync = jest.spyOn(fs, 'chmodSync'); |     spyChmodSync = jest.spyOn(fs, 'chmodSync'); | ||||||
|     spyChmodSync.mockImplementation(() => undefined); |     spyChmodSync.mockImplementation(() => undefined); | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, true) |       finder.findPyPyVersion( | ||||||
|  |         'pypy-3.7-v7.3.x', | ||||||
|  |         architecture, | ||||||
|  |         false, | ||||||
|  |         true, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       resolvedPythonVersion: '3.7.9', |       resolvedPythonVersion: '3.7.9', | ||||||
|       resolvedPyPyVersion: '7.3.3' |       resolvedPyPyVersion: '7.3.3' | ||||||
| @ -391,7 +427,13 @@ describe('findPyPyVersion', () => { | |||||||
|       return pypyPath; |       return pypyPath; | ||||||
|     }); |     }); | ||||||
|     await expect( |     await expect( | ||||||
|       finder.findPyPyVersion('pypy-3.8-v7.3.x', architecture, false, true) |       finder.findPyPyVersion( | ||||||
|  |         'pypy-3.8-v7.3.x', | ||||||
|  |         architecture, | ||||||
|  |         false, | ||||||
|  |         true, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       resolvedPythonVersion: '3.8.8', |       resolvedPythonVersion: '3.8.8', | ||||||
|       resolvedPyPyVersion: '7.3.3' |       resolvedPyPyVersion: '7.3.3' | ||||||
| @ -401,4 +443,22 @@ describe('findPyPyVersion', () => { | |||||||
|       'Failed to resolve PyPy v7.3.x with Python (3.8) from manifest' |       'Failed to resolve PyPy v7.3.x with Python (3.8) from manifest' | ||||||
|     ); |     ); | ||||||
|   }); |   }); | ||||||
|  | 
 | ||||||
|  |   it('found and install successfully, pre-release fallback', async () => { | ||||||
|  |     spyCacheDir = jest.spyOn(tc, 'cacheDir'); | ||||||
|  |     spyCacheDir.mockImplementation(() => | ||||||
|  |       path.join(toolDir, 'PyPy', '3.8.12', architecture) | ||||||
|  |     ); | ||||||
|  |     spyChmodSync = jest.spyOn(fs, 'chmodSync'); | ||||||
|  |     spyChmodSync.mockImplementation(() => undefined); | ||||||
|  |     await expect( | ||||||
|  |       finder.findPyPyVersion('pypy3.8', architecture, false, false, false) | ||||||
|  |     ).rejects.toThrowError(); | ||||||
|  |     await expect( | ||||||
|  |       finder.findPyPyVersion('pypy3.8', architecture, false, false, true) | ||||||
|  |     ).resolves.toEqual({ | ||||||
|  |       resolvedPythonVersion: '3.8.12', | ||||||
|  |       resolvedPyPyVersion: '7.3.8rc2' | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -56,7 +56,7 @@ describe('Finder tests', () => { | |||||||
|     await io.mkdirP(pythonDir); |     await io.mkdirP(pythonDir); | ||||||
|     fs.writeFileSync(`${pythonDir}.complete`, 'hello'); |     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)
 |     // 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, false); |     await finder.useCpythonVersion('3.x', 'x64', true, false, false); | ||||||
|     expect(spyCoreAddPath).toHaveBeenCalled(); |     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||||
|     expect(spyCoreExportVariable).toHaveBeenCalledWith( |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|       'pythonLocation', |       'pythonLocation', | ||||||
| @ -73,7 +73,7 @@ describe('Finder tests', () => { | |||||||
|     await io.mkdirP(pythonDir); |     await io.mkdirP(pythonDir); | ||||||
|     fs.writeFileSync(`${pythonDir}.complete`, 'hello'); |     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)
 |     // 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, false); |     await finder.useCpythonVersion('3.x', 'x64', false, false, false); | ||||||
|     expect(spyCoreAddPath).not.toHaveBeenCalled(); |     expect(spyCoreAddPath).not.toHaveBeenCalled(); | ||||||
|     expect(spyCoreExportVariable).not.toHaveBeenCalled(); |     expect(spyCoreExportVariable).not.toHaveBeenCalled(); | ||||||
|   }); |   }); | ||||||
| @ -95,7 +95,12 @@ describe('Finder tests', () => { | |||||||
|       fs.writeFileSync(`${pythonDir}.complete`, 'hello'); |       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)
 |     // 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, false); |     await expect( | ||||||
|  |       finder.useCpythonVersion('1.2.3', 'x64', true, false, false) | ||||||
|  |     ).resolves.toEqual({ | ||||||
|  |       impl: 'CPython', | ||||||
|  |       version: '1.2.3' | ||||||
|  |     }); | ||||||
|     expect(spyCoreAddPath).toHaveBeenCalled(); |     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||||
|     expect(spyCoreExportVariable).toHaveBeenCalledWith( |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|       'pythonLocation', |       'pythonLocation', | ||||||
| @ -122,14 +127,19 @@ describe('Finder tests', () => { | |||||||
|       const pythonDir: string = path.join( |       const pythonDir: string = path.join( | ||||||
|         toolDir, |         toolDir, | ||||||
|         'Python', |         'Python', | ||||||
|         '1.2.3-beta.2', |         '1.2.4-beta.2', | ||||||
|         'x64' |         'x64' | ||||||
|       ); |       ); | ||||||
|       await io.mkdirP(pythonDir); |       await io.mkdirP(pythonDir); | ||||||
|       fs.writeFileSync(`${pythonDir}.complete`, 'hello'); |       fs.writeFileSync(`${pythonDir}.complete`, 'hello'); | ||||||
|     }); |     }); | ||||||
|     // This will throw if it doesn't find it in the manifest (because no such version exists)
 |     // 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', false, false); |     await expect( | ||||||
|  |       finder.useCpythonVersion('1.2.4-beta.2', 'x64', false, false, false) | ||||||
|  |     ).resolves.toEqual({ | ||||||
|  |       impl: 'CPython', | ||||||
|  |       version: '1.2.4-beta.2' | ||||||
|  |     }); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it('Check-latest true, finds the latest version in the manifest', async () => { |   it('Check-latest true, finds the latest version in the manifest', async () => { | ||||||
| @ -176,7 +186,7 @@ describe('Finder tests', () => { | |||||||
| 
 | 
 | ||||||
|     fs.writeFileSync(`${pythonDir}.complete`, 'hello'); |     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)
 |     // 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); |     await finder.useCpythonVersion('1.2', 'x64', true, true, false); | ||||||
| 
 | 
 | ||||||
|     expect(infoSpy).toHaveBeenCalledWith("Resolved as '1.2.3'"); |     expect(infoSpy).toHaveBeenCalledWith("Resolved as '1.2.3'"); | ||||||
|     expect(infoSpy).toHaveBeenCalledWith( |     expect(infoSpy).toHaveBeenCalledWith( | ||||||
| @ -187,7 +197,7 @@ describe('Finder tests', () => { | |||||||
|     ); |     ); | ||||||
|     expect(installSpy).toHaveBeenCalled(); |     expect(installSpy).toHaveBeenCalled(); | ||||||
|     expect(addPathSpy).toHaveBeenCalledWith(expPath); |     expect(addPathSpy).toHaveBeenCalledWith(expPath); | ||||||
|     await finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, true); |     await finder.useCpythonVersion('1.2.4-beta.2', 'x64', false, true, false); | ||||||
|     expect(spyCoreAddPath).toHaveBeenCalled(); |     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||||
|     expect(spyCoreExportVariable).toHaveBeenCalledWith( |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|       'pythonLocation', |       'pythonLocation', | ||||||
| @ -199,11 +209,67 @@ describe('Finder tests', () => { | |||||||
|     ); |     ); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   it('Finds stable Python version if it is not installed, but exists in the manifest, skipping newer pre-release', async () => { | ||||||
|  |     const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo'); | ||||||
|  |     findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData); | ||||||
|  | 
 | ||||||
|  |     const installSpy: jest.SpyInstance = jest.spyOn( | ||||||
|  |       installer, | ||||||
|  |       'installCpythonFromRelease' | ||||||
|  |     ); | ||||||
|  |     installSpy.mockImplementation(async () => { | ||||||
|  |       const pythonDir: string = path.join(toolDir, 'Python', '1.2.3', '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 expect( | ||||||
|  |       finder.useCpythonVersion('1.2', 'x64', false, false, false) | ||||||
|  |     ).resolves.toEqual({ | ||||||
|  |       impl: 'CPython', | ||||||
|  |       version: '1.2.3' | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   it('Finds Python version if it is not installed, but exists in the manifest, pre-release fallback', async () => { | ||||||
|  |     const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo'); | ||||||
|  |     findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData); | ||||||
|  | 
 | ||||||
|  |     const installSpy: jest.SpyInstance = jest.spyOn( | ||||||
|  |       installer, | ||||||
|  |       'installCpythonFromRelease' | ||||||
|  |     ); | ||||||
|  |     installSpy.mockImplementation(async () => { | ||||||
|  |       const pythonDir: string = path.join( | ||||||
|  |         toolDir, | ||||||
|  |         'Python', | ||||||
|  |         '1.1.0-beta.2', | ||||||
|  |         '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 expect( | ||||||
|  |       finder.useCpythonVersion('1.1', 'x64', false, false, false) | ||||||
|  |     ).rejects.toThrowError(); | ||||||
|  |     await expect( | ||||||
|  |       finder.useCpythonVersion('1.1', 'x64', false, false, true) | ||||||
|  |     ).resolves.toEqual({ | ||||||
|  |       impl: 'CPython', | ||||||
|  |       version: '1.1.0-beta.2' | ||||||
|  |     }); | ||||||
|  |     // Check 1.1.0 version specifier does not fallback to '1.1.0-beta.2'
 | ||||||
|  |     await expect( | ||||||
|  |       finder.useCpythonVersion('1.1.0', 'x64', false, false, true) | ||||||
|  |     ).rejects.toThrowError(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|   it('Errors if Python is not installed', async () => { |   it('Errors if Python is not installed', async () => { | ||||||
|     // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
 |     // This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
 | ||||||
|     let thrown = false; |     let thrown = false; | ||||||
|     try { |     try { | ||||||
|       await finder.useCpythonVersion('3.300000', 'x64', true, false); |       await finder.useCpythonVersion('3.300000', 'x64', true, false, false); | ||||||
|     } catch { |     } catch { | ||||||
|       thrown = true; |       thrown = true; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -51,6 +51,12 @@ describe('findRelease', () => { | |||||||
|     platform: process.platform, |     platform: process.platform, | ||||||
|     download_url: `https://test.download.python.org/pypy/pypy3.6-v7.3.3-${extensionName}` |     download_url: `https://test.download.python.org/pypy/pypy3.6-v7.3.3-${extensionName}` | ||||||
|   }; |   }; | ||||||
|  |   const filesRC1: IPyPyManifestAsset = { | ||||||
|  |     filename: `pypy3.6-v7.4.0rc1-${extensionName}`, | ||||||
|  |     arch: architecture, | ||||||
|  |     platform: process.platform, | ||||||
|  |     download_url: `https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-${extensionName}` | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   let getBooleanInputSpy: jest.SpyInstance; |   let getBooleanInputSpy: jest.SpyInstance; | ||||||
|   let warningSpy: jest.SpyInstance; |   let warningSpy: jest.SpyInstance; | ||||||
| @ -72,7 +78,13 @@ describe('findRelease', () => { | |||||||
|     const pythonVersion = '3.6'; |     const pythonVersion = '3.6'; | ||||||
|     const pypyVersion = '7.3.7'; |     const pypyVersion = '7.3.7'; | ||||||
|     expect( |     expect( | ||||||
|       installer.findRelease(releases, pythonVersion, pypyVersion, architecture) |       installer.findRelease( | ||||||
|  |         releases, | ||||||
|  |         pythonVersion, | ||||||
|  |         pypyVersion, | ||||||
|  |         architecture, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).toEqual(null); |     ).toEqual(null); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
| @ -80,7 +92,13 @@ describe('findRelease', () => { | |||||||
|     const pythonVersion = '3.6'; |     const pythonVersion = '3.6'; | ||||||
|     const pypyVersion = '7.3.3'; |     const pypyVersion = '7.3.3'; | ||||||
|     expect( |     expect( | ||||||
|       installer.findRelease(releases, pythonVersion, pypyVersion, architecture) |       installer.findRelease( | ||||||
|  |         releases, | ||||||
|  |         pythonVersion, | ||||||
|  |         pypyVersion, | ||||||
|  |         architecture, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).toEqual({ |     ).toEqual({ | ||||||
|       foundAsset: files, |       foundAsset: files, | ||||||
|       resolvedPythonVersion: '3.6.12', |       resolvedPythonVersion: '3.6.12', | ||||||
| @ -92,7 +110,13 @@ describe('findRelease', () => { | |||||||
|     const pythonVersion = '3.6'; |     const pythonVersion = '3.6'; | ||||||
|     const pypyVersion = '7.x'; |     const pypyVersion = '7.x'; | ||||||
|     expect( |     expect( | ||||||
|       installer.findRelease(releases, pythonVersion, pypyVersion, architecture) |       installer.findRelease( | ||||||
|  |         releases, | ||||||
|  |         pythonVersion, | ||||||
|  |         pypyVersion, | ||||||
|  |         architecture, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).toEqual({ |     ).toEqual({ | ||||||
|       foundAsset: files, |       foundAsset: files, | ||||||
|       resolvedPythonVersion: '3.6.12', |       resolvedPythonVersion: '3.6.12', | ||||||
| @ -104,7 +128,13 @@ describe('findRelease', () => { | |||||||
|     const pythonVersion = '3.7'; |     const pythonVersion = '3.7'; | ||||||
|     const pypyVersion = installer.pypyVersionToSemantic('7.3.3rc2'); |     const pypyVersion = installer.pypyVersionToSemantic('7.3.3rc2'); | ||||||
|     expect( |     expect( | ||||||
|       installer.findRelease(releases, pythonVersion, pypyVersion, architecture) |       installer.findRelease( | ||||||
|  |         releases, | ||||||
|  |         pythonVersion, | ||||||
|  |         pypyVersion, | ||||||
|  |         architecture, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).toEqual({ |     ).toEqual({ | ||||||
|       foundAsset: { |       foundAsset: { | ||||||
|         filename: `test${extension}`, |         filename: `test${extension}`, | ||||||
| @ -121,7 +151,13 @@ describe('findRelease', () => { | |||||||
|     const pythonVersion = '3.6'; |     const pythonVersion = '3.6'; | ||||||
|     const pypyVersion = 'x'; |     const pypyVersion = 'x'; | ||||||
|     expect( |     expect( | ||||||
|       installer.findRelease(releases, pythonVersion, pypyVersion, architecture) |       installer.findRelease( | ||||||
|  |         releases, | ||||||
|  |         pythonVersion, | ||||||
|  |         pypyVersion, | ||||||
|  |         architecture, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).toEqual({ |     ).toEqual({ | ||||||
|       foundAsset: files, |       foundAsset: files, | ||||||
|       resolvedPythonVersion: '3.6.12', |       resolvedPythonVersion: '3.6.12', | ||||||
| @ -129,12 +165,45 @@ describe('findRelease', () => { | |||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   it('Python version and PyPy version matches semver (pre-release)', () => { | ||||||
|  |     const pythonVersion = '3.6'; | ||||||
|  |     const pypyVersion = '7.4.x'; | ||||||
|  |     expect( | ||||||
|  |       installer.findRelease( | ||||||
|  |         releases, | ||||||
|  |         pythonVersion, | ||||||
|  |         pypyVersion, | ||||||
|  |         architecture, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|  |     ).toBeNull(); | ||||||
|  |     expect( | ||||||
|  |       installer.findRelease( | ||||||
|  |         releases, | ||||||
|  |         pythonVersion, | ||||||
|  |         pypyVersion, | ||||||
|  |         architecture, | ||||||
|  |         true | ||||||
|  |       ) | ||||||
|  |     ).toEqual({ | ||||||
|  |       foundAsset: filesRC1, | ||||||
|  |       resolvedPythonVersion: '3.6.12', | ||||||
|  |       resolvedPyPyVersion: '7.4.0rc1' | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|   it('Nightly release is found', () => { |   it('Nightly release is found', () => { | ||||||
|     const pythonVersion = '3.6'; |     const pythonVersion = '3.6'; | ||||||
|     const pypyVersion = 'nightly'; |     const pypyVersion = 'nightly'; | ||||||
|     const filename = IS_WINDOWS ? 'filename.zip' : 'filename.tar.bz2'; |     const filename = IS_WINDOWS ? 'filename.zip' : 'filename.tar.bz2'; | ||||||
|     expect( |     expect( | ||||||
|       installer.findRelease(releases, pythonVersion, pypyVersion, architecture) |       installer.findRelease( | ||||||
|  |         releases, | ||||||
|  |         pythonVersion, | ||||||
|  |         pypyVersion, | ||||||
|  |         architecture, | ||||||
|  |         false | ||||||
|  |       ) | ||||||
|     ).toEqual({ |     ).toEqual({ | ||||||
|       foundAsset: { |       foundAsset: { | ||||||
|         filename: filename, |         filename: filename, | ||||||
| @ -224,7 +293,7 @@ describe('installPyPy', () => { | |||||||
| 
 | 
 | ||||||
|   it('throw if release is not found', async () => { |   it('throw if release is not found', async () => { | ||||||
|     await expect( |     await expect( | ||||||
|       installer.installPyPy('7.3.3', '3.6.17', architecture, undefined) |       installer.installPyPy('7.3.3', '3.6.17', architecture, false, undefined) | ||||||
|     ).rejects.toThrowError( |     ).rejects.toThrowError( | ||||||
|       `PyPy version 3.6.17 (7.3.3) with arch ${architecture} not found` |       `PyPy version 3.6.17 (7.3.3) with arch ${architecture} not found` | ||||||
|     ); |     ); | ||||||
| @ -244,7 +313,7 @@ describe('installPyPy', () => { | |||||||
|     spyChmodSync.mockImplementation(() => undefined); |     spyChmodSync.mockImplementation(() => undefined); | ||||||
| 
 | 
 | ||||||
|     await expect( |     await expect( | ||||||
|       installer.installPyPy('7.3.x', '3.6.12', architecture, undefined) |       installer.installPyPy('7.x', '3.6.12', architecture, false, undefined) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture), |       installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture), | ||||||
|       resolvedPythonVersion: '3.6.12', |       resolvedPythonVersion: '3.6.12', | ||||||
| @ -257,4 +326,31 @@ describe('installPyPy', () => { | |||||||
|     expect(spyCacheDir).toHaveBeenCalled(); |     expect(spyCacheDir).toHaveBeenCalled(); | ||||||
|     expect(spyExec).toHaveBeenCalled(); |     expect(spyExec).toHaveBeenCalled(); | ||||||
|   }); |   }); | ||||||
|  | 
 | ||||||
|  |   it('found and install PyPy, pre-release fallback', async () => { | ||||||
|  |     spyCacheDir = jest.spyOn(tc, 'cacheDir'); | ||||||
|  |     spyCacheDir.mockImplementation(() => | ||||||
|  |       path.join(toolDir, 'PyPy', '3.6.12', architecture) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     spyChmodSync = jest.spyOn(fs, 'chmodSync'); | ||||||
|  |     spyChmodSync.mockImplementation(() => undefined); | ||||||
|  | 
 | ||||||
|  |     await expect( | ||||||
|  |       installer.installPyPy('7.4.x', '3.6.12', architecture, false, undefined) | ||||||
|  |     ).rejects.toThrowError(); | ||||||
|  |     await expect( | ||||||
|  |       installer.installPyPy('7.4.x', '3.6.12', architecture, true, undefined) | ||||||
|  |     ).resolves.toEqual({ | ||||||
|  |       installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture), | ||||||
|  |       resolvedPythonVersion: '3.6.12', | ||||||
|  |       resolvedPyPyVersion: '7.4.0rc1' | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(spyHttpClient).toHaveBeenCalled(); | ||||||
|  |     expect(spyDownloadTool).toHaveBeenCalled(); | ||||||
|  |     expect(spyExistsSync).toHaveBeenCalled(); | ||||||
|  |     expect(spyCacheDir).toHaveBeenCalled(); | ||||||
|  |     expect(spyExec).toHaveBeenCalled(); | ||||||
|  |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -23,6 +23,9 @@ inputs: | |||||||
|   update-environment: |   update-environment: | ||||||
|     description: "Set this option if you want the action to update environment variables." |     description: "Set this option if you want the action to update environment variables." | ||||||
|     default: true |     default: true | ||||||
|  |   allow-prereleases: | ||||||
|  |     description: "When 'true', a version range passed to 'python-version' input will match prerelease versions if no GA versions are found. Only 'x.y' version range is supported for CPython." | ||||||
|  |     default: false | ||||||
| outputs: | outputs: | ||||||
|   python-version: |   python-version: | ||||||
|     description: "The installed Python or PyPy version. Useful when given a version range as input." |     description: "The installed Python or PyPy version. Useful when given a version range as input." | ||||||
|  | |||||||
							
								
								
									
										44
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							| @ -66237,7 +66237,7 @@ const utils_1 = __nccwpck_require__(1314); | |||||||
| const semver = __importStar(__nccwpck_require__(1383)); | const semver = __importStar(__nccwpck_require__(1383)); | ||||||
| const core = __importStar(__nccwpck_require__(2186)); | const core = __importStar(__nccwpck_require__(2186)); | ||||||
| const tc = __importStar(__nccwpck_require__(7784)); | const tc = __importStar(__nccwpck_require__(7784)); | ||||||
| function findPyPyVersion(versionSpec, architecture, updateEnvironment, checkLatest) { | function findPyPyVersion(versionSpec, architecture, updateEnvironment, checkLatest, allowPreReleases) { | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         let resolvedPyPyVersion = ''; |         let resolvedPyPyVersion = ''; | ||||||
|         let resolvedPythonVersion = ''; |         let resolvedPythonVersion = ''; | ||||||
| @ -66247,7 +66247,7 @@ function findPyPyVersion(versionSpec, architecture, updateEnvironment, checkLate | |||||||
|         if (checkLatest) { |         if (checkLatest) { | ||||||
|             releases = yield pypyInstall.getAvailablePyPyVersions(); |             releases = yield pypyInstall.getAvailablePyPyVersions(); | ||||||
|             if (releases && releases.length > 0) { |             if (releases && releases.length > 0) { | ||||||
|                 const releaseData = pypyInstall.findRelease(releases, pypyVersionSpec.pythonVersion, pypyVersionSpec.pypyVersion, architecture); |                 const releaseData = pypyInstall.findRelease(releases, pypyVersionSpec.pythonVersion, pypyVersionSpec.pypyVersion, architecture, false); | ||||||
|                 if (releaseData) { |                 if (releaseData) { | ||||||
|                     core.info(`Resolved as PyPy ${releaseData.resolvedPyPyVersion} with Python (${releaseData.resolvedPythonVersion})`); |                     core.info(`Resolved as PyPy ${releaseData.resolvedPyPyVersion} with Python (${releaseData.resolvedPythonVersion})`); | ||||||
|                     pypyVersionSpec.pythonVersion = releaseData.resolvedPythonVersion; |                     pypyVersionSpec.pythonVersion = releaseData.resolvedPythonVersion; | ||||||
| @ -66264,7 +66264,7 @@ function findPyPyVersion(versionSpec, architecture, updateEnvironment, checkLate | |||||||
|                 installDir, |                 installDir, | ||||||
|                 resolvedPythonVersion, |                 resolvedPythonVersion, | ||||||
|                 resolvedPyPyVersion |                 resolvedPyPyVersion | ||||||
|             } = yield pypyInstall.installPyPy(pypyVersionSpec.pypyVersion, pypyVersionSpec.pythonVersion, architecture, releases)); |             } = yield pypyInstall.installPyPy(pypyVersionSpec.pypyVersion, pypyVersionSpec.pythonVersion, architecture, allowPreReleases, releases)); | ||||||
|         } |         } | ||||||
|         const pipDir = utils_1.IS_WINDOWS ? 'Scripts' : 'bin'; |         const pipDir = utils_1.IS_WINDOWS ? 'Scripts' : 'bin'; | ||||||
|         const _binDir = path.join(installDir, pipDir); |         const _binDir = path.join(installDir, pipDir); | ||||||
| @ -66414,12 +66414,12 @@ function binDir(installDir) { | |||||||
|         return path.join(installDir, 'bin'); |         return path.join(installDir, 'bin'); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| function useCpythonVersion(version, architecture, updateEnvironment, checkLatest) { | function useCpythonVersion(version, architecture, updateEnvironment, checkLatest, allowPreReleases) { | ||||||
|     var _a; |     var _a; | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         let manifest = null; |         let manifest = null; | ||||||
|         const desugaredVersionSpec = desugarDevVersion(version); |         const desugaredVersionSpec = desugarDevVersion(version); | ||||||
|         let semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); |         let semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec, allowPreReleases); | ||||||
|         core.debug(`Semantic version spec of ${version} is ${semanticVersionSpec}`); |         core.debug(`Semantic version spec of ${version} is ${semanticVersionSpec}`); | ||||||
|         if (checkLatest) { |         if (checkLatest) { | ||||||
|             manifest = yield installer.getManifest(); |             manifest = yield installer.getManifest(); | ||||||
| @ -66510,10 +66510,17 @@ function versionFromPath(installDir) { | |||||||
|  * Python's prelease versions look like `3.7.0b2`. |  * Python's prelease versions look like `3.7.0b2`. | ||||||
|  * This is the one part of Python versioning that does not look like semantic versioning, which specifies `3.7.0-b2`. |  * This is the one part of Python versioning that does not look like semantic versioning, which specifies `3.7.0-b2`. | ||||||
|  * If the version spec contains prerelease versions, we need to convert them to the semantic version equivalent. |  * If the version spec contains prerelease versions, we need to convert them to the semantic version equivalent. | ||||||
|  |  * | ||||||
|  |  * For easier use of the action, we also map 'x.y' to allow pre-release before 'x.y.0' release if allowPreReleases is true | ||||||
|  */ |  */ | ||||||
| function pythonVersionToSemantic(versionSpec) { | function pythonVersionToSemantic(versionSpec, allowPreReleases) { | ||||||
|     const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc)\d*)/g; |     const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc)\d*)/g; | ||||||
|     return versionSpec.replace(prereleaseVersion, '$1-$2'); |     const majorMinor = /^(\d+)\.(\d+)$/; | ||||||
|  |     let result = versionSpec.replace(prereleaseVersion, '$1-$2'); | ||||||
|  |     if (allowPreReleases) { | ||||||
|  |         result = result.replace(majorMinor, '~$1.$2.0-0'); | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
| } | } | ||||||
| exports.pythonVersionToSemantic = pythonVersionToSemantic; | exports.pythonVersionToSemantic = pythonVersionToSemantic; | ||||||
| 
 | 
 | ||||||
| @ -66558,6 +66565,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | |||||||
| }; | }; | ||||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||||
| exports.findAssetForMacOrLinux = exports.findAssetForWindows = exports.isArchPresentForMacOrLinux = exports.isArchPresentForWindows = exports.pypyVersionToSemantic = exports.getPyPyBinaryPath = exports.findRelease = exports.getAvailablePyPyVersions = 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 os = __importStar(__nccwpck_require__(2037)); | ||||||
| const path = __importStar(__nccwpck_require__(1017)); | const path = __importStar(__nccwpck_require__(1017)); | ||||||
| const core = __importStar(__nccwpck_require__(2186)); | const core = __importStar(__nccwpck_require__(2186)); | ||||||
| const tc = __importStar(__nccwpck_require__(7784)); | const tc = __importStar(__nccwpck_require__(7784)); | ||||||
| @ -66566,14 +66574,22 @@ const httpm = __importStar(__nccwpck_require__(9925)); | |||||||
| const exec = __importStar(__nccwpck_require__(1514)); | const exec = __importStar(__nccwpck_require__(1514)); | ||||||
| const fs_1 = __importDefault(__nccwpck_require__(7147)); | const fs_1 = __importDefault(__nccwpck_require__(7147)); | ||||||
| const utils_1 = __nccwpck_require__(1314); | const utils_1 = __nccwpck_require__(1314); | ||||||
| function installPyPy(pypyVersion, pythonVersion, architecture, releases) { | function installPyPy(pypyVersion, pythonVersion, architecture, allowPreReleases, releases) { | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         let downloadDir; |         let downloadDir; | ||||||
|         releases = releases !== null && releases !== void 0 ? releases : (yield getAvailablePyPyVersions()); |         releases = releases !== null && releases !== void 0 ? releases : (yield getAvailablePyPyVersions()); | ||||||
|         if (!releases || releases.length === 0) { |         if (!releases || releases.length === 0) { | ||||||
|             throw new Error('No release was found in PyPy version.json'); |             throw new Error('No release was found in PyPy version.json'); | ||||||
|         } |         } | ||||||
|         const releaseData = findRelease(releases, pythonVersion, pypyVersion, architecture); |         let releaseData = findRelease(releases, pythonVersion, pypyVersion, architecture, false); | ||||||
|  |         if (allowPreReleases && (!releaseData || !releaseData.foundAsset)) { | ||||||
|  |             // check for pre-release
 | ||||||
|  |             core.info([ | ||||||
|  |                 `Stable PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`, | ||||||
|  |                 `Trying pre-release versions` | ||||||
|  |             ].join(os.EOL)); | ||||||
|  |             releaseData = findRelease(releases, pythonVersion, pypyVersion, architecture, true); | ||||||
|  |         } | ||||||
|         if (!releaseData || !releaseData.foundAsset) { |         if (!releaseData || !releaseData.foundAsset) { | ||||||
|             throw new Error(`PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`); |             throw new Error(`PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`); | ||||||
|         } |         } | ||||||
| @ -66656,12 +66672,13 @@ function installPip(pythonLocation) { | |||||||
|         yield exec.exec(`${pythonLocation}/python -m pip install --ignore-installed pip`); |         yield exec.exec(`${pythonLocation}/python -m pip install --ignore-installed pip`); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| function findRelease(releases, pythonVersion, pypyVersion, architecture) { | function findRelease(releases, pythonVersion, pypyVersion, architecture, includePrerelease) { | ||||||
|  |     const options = { includePrerelease: includePrerelease }; | ||||||
|     const filterReleases = releases.filter(item => { |     const filterReleases = releases.filter(item => { | ||||||
|         const isPythonVersionSatisfied = semver.satisfies(semver.coerce(item.python_version), pythonVersion); |         const isPythonVersionSatisfied = semver.satisfies(semver.coerce(item.python_version), pythonVersion); | ||||||
|         const isPyPyNightly = utils_1.isNightlyKeyword(pypyVersion) && utils_1.isNightlyKeyword(item.pypy_version); |         const isPyPyNightly = utils_1.isNightlyKeyword(pypyVersion) && utils_1.isNightlyKeyword(item.pypy_version); | ||||||
|         const isPyPyVersionSatisfied = isPyPyNightly || |         const isPyPyVersionSatisfied = isPyPyNightly || | ||||||
|             semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion); |             semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion, options); | ||||||
|         const isArchPresent = item.files && |         const isArchPresent = item.files && | ||||||
|             (utils_1.IS_WINDOWS |             (utils_1.IS_WINDOWS | ||||||
|                 ? isArchPresentForWindows(item, architecture) |                 ? isArchPresentForWindows(item, architecture) | ||||||
| @ -66948,6 +66965,7 @@ function run() { | |||||||
|         try { |         try { | ||||||
|             const versions = resolveVersionInput(); |             const versions = resolveVersionInput(); | ||||||
|             const checkLatest = core.getBooleanInput('check-latest'); |             const checkLatest = core.getBooleanInput('check-latest'); | ||||||
|  |             const allowPreReleases = core.getBooleanInput('allow-prereleases'); | ||||||
|             if (versions.length) { |             if (versions.length) { | ||||||
|                 let pythonVersion = ''; |                 let pythonVersion = ''; | ||||||
|                 const arch = core.getInput('architecture') || os.arch(); |                 const arch = core.getInput('architecture') || os.arch(); | ||||||
| @ -66955,12 +66973,12 @@ function run() { | |||||||
|                 core.startGroup('Installed versions'); |                 core.startGroup('Installed versions'); | ||||||
|                 for (const version of versions) { |                 for (const version of versions) { | ||||||
|                     if (isPyPyVersion(version)) { |                     if (isPyPyVersion(version)) { | ||||||
|                         const installed = yield finderPyPy.findPyPyVersion(version, arch, updateEnvironment, checkLatest); |                         const installed = yield finderPyPy.findPyPyVersion(version, arch, updateEnvironment, checkLatest, allowPreReleases); | ||||||
|                         pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; |                         pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; | ||||||
|                         core.info(`Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`); |                         core.info(`Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`); | ||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         const installed = yield finder.useCpythonVersion(version, arch, updateEnvironment, checkLatest); |                         const installed = yield finder.useCpythonVersion(version, arch, updateEnvironment, checkLatest, allowPreReleases); | ||||||
|                         pythonVersion = installed.version; |                         pythonVersion = installed.version; | ||||||
|                         core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); |                         core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||||
|                     } |                     } | ||||||
|  | |||||||
| @ -20,6 +20,7 @@ | |||||||
|     - [Linux](advanced-usage.md#linux) |     - [Linux](advanced-usage.md#linux) | ||||||
|     - [macOS](advanced-usage.md#macos) |     - [macOS](advanced-usage.md#macos) | ||||||
| - [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes) | - [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes) | ||||||
|  | - [Allow pre-releases](advanced-usage.md#allow-pre-releases) | ||||||
| 
 | 
 | ||||||
| ## Using the `python-version` input | ## Using the `python-version` input | ||||||
| 
 | 
 | ||||||
| @ -568,3 +569,31 @@ Requests should now be authenticated. To verify that you are getting the higher | |||||||
| 
 | 
 | ||||||
| ### No access to github.com | ### No access to github.com | ||||||
| If the runner is not able to access github.com, any Python versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information. | If the runner is not able to access github.com, any Python versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Allow pre-releases | ||||||
|  | 
 | ||||||
|  | The `allow-prereleases` flag defaults to `false`. | ||||||
|  | If `allow-prereleases` is set to `true`, the action will allow falling back to pre-release versions of Python when a matching GA version of Python is not available. | ||||||
|  | This allows for example to simplify reuse of `python-version` as an input of nox for pre-releases of Python by not requiring manipulation of the `3.y-dev` specifier. | ||||||
|  | For CPython, `allow-prereleases` will only have effect for `x.y` version range (e.g. `3.12`). | ||||||
|  | Let's say that python 3.12 is not generally available, the following workflow will fallback to the most recent pre-release of python 3.12: | ||||||
|  | ```yaml | ||||||
|  | jobs: | ||||||
|  |   test: | ||||||
|  |     name: ${{ matrix.os }} / ${{ matrix.python_version }} | ||||||
|  |     runs-on: ${{ matrix.os }}-latest | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         os: [Ubuntu, Windows, macOS] | ||||||
|  |         python_version: ["3.11", "3.12"] | ||||||
|  | 
 | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v3 | ||||||
|  |       - uses: actions/setup-python@v4 | ||||||
|  |         with: | ||||||
|  |           python-version: "${{ matrix.python_version }}" | ||||||
|  |       - run: pipx run nox --error-on-missing-interpreters -s tests-${{ matrix.python_version }} | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -23,7 +23,8 @@ export async function findPyPyVersion( | |||||||
|   versionSpec: string, |   versionSpec: string, | ||||||
|   architecture: string, |   architecture: string, | ||||||
|   updateEnvironment: boolean, |   updateEnvironment: boolean, | ||||||
|   checkLatest: boolean |   checkLatest: boolean, | ||||||
|  |   allowPreReleases: boolean | ||||||
| ): Promise<{resolvedPyPyVersion: string; resolvedPythonVersion: string}> { | ): Promise<{resolvedPyPyVersion: string; resolvedPythonVersion: string}> { | ||||||
|   let resolvedPyPyVersion = ''; |   let resolvedPyPyVersion = ''; | ||||||
|   let resolvedPythonVersion = ''; |   let resolvedPythonVersion = ''; | ||||||
| @ -39,7 +40,8 @@ export async function findPyPyVersion( | |||||||
|         releases, |         releases, | ||||||
|         pypyVersionSpec.pythonVersion, |         pypyVersionSpec.pythonVersion, | ||||||
|         pypyVersionSpec.pypyVersion, |         pypyVersionSpec.pypyVersion, | ||||||
|         architecture |         architecture, | ||||||
|  |         false | ||||||
|       ); |       ); | ||||||
| 
 | 
 | ||||||
|       if (releaseData) { |       if (releaseData) { | ||||||
| @ -71,6 +73,7 @@ export async function findPyPyVersion( | |||||||
|       pypyVersionSpec.pypyVersion, |       pypyVersionSpec.pypyVersion, | ||||||
|       pypyVersionSpec.pythonVersion, |       pypyVersionSpec.pythonVersion, | ||||||
|       architecture, |       architecture, | ||||||
|  |       allowPreReleases, | ||||||
|       releases |       releases | ||||||
|     )); |     )); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -34,11 +34,15 @@ export async function useCpythonVersion( | |||||||
|   version: string, |   version: string, | ||||||
|   architecture: string, |   architecture: string, | ||||||
|   updateEnvironment: boolean, |   updateEnvironment: boolean, | ||||||
|   checkLatest: boolean |   checkLatest: boolean, | ||||||
|  |   allowPreReleases: boolean | ||||||
| ): Promise<InstalledVersion> { | ): Promise<InstalledVersion> { | ||||||
|   let manifest: tc.IToolRelease[] | null = null; |   let manifest: tc.IToolRelease[] | null = null; | ||||||
|   const desugaredVersionSpec = desugarDevVersion(version); |   const desugaredVersionSpec = desugarDevVersion(version); | ||||||
|   let semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); |   let semanticVersionSpec = pythonVersionToSemantic( | ||||||
|  |     desugaredVersionSpec, | ||||||
|  |     allowPreReleases | ||||||
|  |   ); | ||||||
|   core.debug(`Semantic version spec of ${version} is ${semanticVersionSpec}`); |   core.debug(`Semantic version spec of ${version} is ${semanticVersionSpec}`); | ||||||
| 
 | 
 | ||||||
|   if (checkLatest) { |   if (checkLatest) { | ||||||
| @ -178,8 +182,18 @@ interface InstalledVersion { | |||||||
|  * Python's prelease versions look like `3.7.0b2`. |  * Python's prelease versions look like `3.7.0b2`. | ||||||
|  * This is the one part of Python versioning that does not look like semantic versioning, which specifies `3.7.0-b2`. |  * This is the one part of Python versioning that does not look like semantic versioning, which specifies `3.7.0-b2`. | ||||||
|  * If the version spec contains prerelease versions, we need to convert them to the semantic version equivalent. |  * If the version spec contains prerelease versions, we need to convert them to the semantic version equivalent. | ||||||
|  |  * | ||||||
|  |  * For easier use of the action, we also map 'x.y' to allow pre-release before 'x.y.0' release if allowPreReleases is true | ||||||
|  */ |  */ | ||||||
| export function pythonVersionToSemantic(versionSpec: string) { | export function pythonVersionToSemantic( | ||||||
|  |   versionSpec: string, | ||||||
|  |   allowPreReleases: boolean | ||||||
|  | ) { | ||||||
|   const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc)\d*)/g; |   const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc)\d*)/g; | ||||||
|   return versionSpec.replace(prereleaseVersion, '$1-$2'); |   const majorMinor = /^(\d+)\.(\d+)$/; | ||||||
|  |   let result = versionSpec.replace(prereleaseVersion, '$1-$2'); | ||||||
|  |   if (allowPreReleases) { | ||||||
|  |     result = result.replace(majorMinor, '~$1.$2.0-0'); | ||||||
|  |   } | ||||||
|  |   return result; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | import * as os from 'os'; | ||||||
| import * as path from 'path'; | import * as path from 'path'; | ||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
| import * as tc from '@actions/tool-cache'; | import * as tc from '@actions/tool-cache'; | ||||||
| @ -19,6 +20,7 @@ export async function installPyPy( | |||||||
|   pypyVersion: string, |   pypyVersion: string, | ||||||
|   pythonVersion: string, |   pythonVersion: string, | ||||||
|   architecture: string, |   architecture: string, | ||||||
|  |   allowPreReleases: boolean, | ||||||
|   releases: IPyPyManifestRelease[] | undefined |   releases: IPyPyManifestRelease[] | undefined | ||||||
| ) { | ) { | ||||||
|   let downloadDir; |   let downloadDir; | ||||||
| @ -29,13 +31,31 @@ export async function installPyPy( | |||||||
|     throw new Error('No release was found in PyPy version.json'); |     throw new Error('No release was found in PyPy version.json'); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const releaseData = findRelease( |   let releaseData = findRelease( | ||||||
|     releases, |     releases, | ||||||
|     pythonVersion, |     pythonVersion, | ||||||
|     pypyVersion, |     pypyVersion, | ||||||
|     architecture |     architecture, | ||||||
|  |     false | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|  |   if (allowPreReleases && (!releaseData || !releaseData.foundAsset)) { | ||||||
|  |     // check for pre-release
 | ||||||
|  |     core.info( | ||||||
|  |       [ | ||||||
|  |         `Stable PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`, | ||||||
|  |         `Trying pre-release versions` | ||||||
|  |       ].join(os.EOL) | ||||||
|  |     ); | ||||||
|  |     releaseData = findRelease( | ||||||
|  |       releases, | ||||||
|  |       pythonVersion, | ||||||
|  |       pypyVersion, | ||||||
|  |       architecture, | ||||||
|  |       true | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (!releaseData || !releaseData.foundAsset) { |   if (!releaseData || !releaseData.foundAsset) { | ||||||
|     throw new Error( |     throw new Error( | ||||||
|       `PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found` |       `PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found` | ||||||
| @ -162,8 +182,10 @@ export function findRelease( | |||||||
|   releases: IPyPyManifestRelease[], |   releases: IPyPyManifestRelease[], | ||||||
|   pythonVersion: string, |   pythonVersion: string, | ||||||
|   pypyVersion: string, |   pypyVersion: string, | ||||||
|   architecture: string |   architecture: string, | ||||||
|  |   includePrerelease: boolean | ||||||
| ) { | ) { | ||||||
|  |   const options = {includePrerelease: includePrerelease}; | ||||||
|   const filterReleases = releases.filter(item => { |   const filterReleases = releases.filter(item => { | ||||||
|     const isPythonVersionSatisfied = semver.satisfies( |     const isPythonVersionSatisfied = semver.satisfies( | ||||||
|       semver.coerce(item.python_version)!, |       semver.coerce(item.python_version)!, | ||||||
| @ -173,7 +195,11 @@ export function findRelease( | |||||||
|       isNightlyKeyword(pypyVersion) && isNightlyKeyword(item.pypy_version); |       isNightlyKeyword(pypyVersion) && isNightlyKeyword(item.pypy_version); | ||||||
|     const isPyPyVersionSatisfied = |     const isPyPyVersionSatisfied = | ||||||
|       isPyPyNightly || |       isPyPyNightly || | ||||||
|       semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion); |       semver.satisfies( | ||||||
|  |         pypyVersionToSemantic(item.pypy_version), | ||||||
|  |         pypyVersion, | ||||||
|  |         options | ||||||
|  |       ); | ||||||
|     const isArchPresent = |     const isArchPresent = | ||||||
|       item.files && |       item.files && | ||||||
|       (IS_WINDOWS |       (IS_WINDOWS | ||||||
|  | |||||||
| @ -77,6 +77,7 @@ async function run() { | |||||||
|   try { |   try { | ||||||
|     const versions = resolveVersionInput(); |     const versions = resolveVersionInput(); | ||||||
|     const checkLatest = core.getBooleanInput('check-latest'); |     const checkLatest = core.getBooleanInput('check-latest'); | ||||||
|  |     const allowPreReleases = core.getBooleanInput('allow-prereleases'); | ||||||
| 
 | 
 | ||||||
|     if (versions.length) { |     if (versions.length) { | ||||||
|       let pythonVersion = ''; |       let pythonVersion = ''; | ||||||
| @ -89,7 +90,8 @@ async function run() { | |||||||
|             version, |             version, | ||||||
|             arch, |             arch, | ||||||
|             updateEnvironment, |             updateEnvironment, | ||||||
|             checkLatest |             checkLatest, | ||||||
|  |             allowPreReleases | ||||||
|           ); |           ); | ||||||
|           pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; |           pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; | ||||||
|           core.info( |           core.info( | ||||||
| @ -100,7 +102,8 @@ async function run() { | |||||||
|             version, |             version, | ||||||
|             arch, |             arch, | ||||||
|             updateEnvironment, |             updateEnvironment, | ||||||
|             checkLatest |             checkLatest, | ||||||
|  |             allowPreReleases | ||||||
|           ); |           ); | ||||||
|           pythonVersion = installed.version; |           pythonVersion = installed.version; | ||||||
|           core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); |           core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user