You've already forked setup-python
							
							
				mirror of
				https://github.com/actions/setup-python.git
				synced 2025-10-31 15:16:23 +07:00 
			
		
		
		
	feature: add update-environment input (#411)
				
					
				
			This option allows to specify if the action shall update environment variables (default) or not. This allows to use the setup-python action in a composite action without side effect (except downloading/installing python if version is missing).
This commit is contained in:
		
							
								
								
									
										26
									
								
								.github/workflows/test-pypy.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								.github/workflows/test-pypy.yml
									
									
									
									
										vendored
									
									
								
							| @ -65,3 +65,29 @@ jobs: | |||||||
|           EXECUTABLE=${EXECUTABLE%%-*}  # remove any -* suffixe |           EXECUTABLE=${EXECUTABLE%%-*}  # remove any -* suffixe | ||||||
|           ${EXECUTABLE} --version |           ${EXECUTABLE} --version | ||||||
|         shell: bash |         shell: bash | ||||||
|  |  | ||||||
|  |   setup-pypy-noenv: | ||||||
|  |     name: Setup PyPy ${{ matrix.pypy }} ${{ matrix.os }} (noenv) | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest] | ||||||
|  |         pypy: ['pypy2.7', 'pypy3.7', 'pypy3.8', 'pypy3.9-nightly'] | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout | ||||||
|  |         uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |       - name: setup-python ${{ matrix.pypy }} | ||||||
|  |         id: setup-python | ||||||
|  |         uses: ./ | ||||||
|  |         with: | ||||||
|  |           python-version: ${{ matrix.pypy }} | ||||||
|  |           update-environment: false | ||||||
|  |  | ||||||
|  |       - name: PyPy and Python version | ||||||
|  |         run: ${{ steps.setup-python.outputs.python-path }} --version | ||||||
|  |  | ||||||
|  |       - name: Run simple code | ||||||
|  |         run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))' | ||||||
|  | |||||||
							
								
								
									
										25
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							| @ -147,3 +147,28 @@ 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-versions-noenv: | ||||||
|  |     name: Setup ${{ matrix.python }} ${{ matrix.os }} (noenv) | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04] | ||||||
|  |         python: ["3.7", "3.8", "3.9", "3.10"] | ||||||
|  |     steps: | ||||||
|  |     - name: Checkout | ||||||
|  |       uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |     - name: setup-python ${{ matrix.python }} | ||||||
|  |       id: setup-python | ||||||
|  |       uses: ./ | ||||||
|  |       with: | ||||||
|  |         python-version: ${{ matrix.python }} | ||||||
|  |         update-environment: false | ||||||
|  |  | ||||||
|  |     - name: Python version | ||||||
|  |       run: ${{ steps.setup-python.outputs.python-path }} --version | ||||||
|  |  | ||||||
|  |     - name: Run simple code | ||||||
|  |       run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))' | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								.licenses/npm/@actions/core.dep.yml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.licenses/npm/@actions/core.dep.yml
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| --- | --- | ||||||
| name: "@actions/core" | name: "@actions/core" | ||||||
| version: 1.2.6 | version: 1.7.0 | ||||||
| type: npm | type: npm | ||||||
| summary: Actions core lib | summary: Actions core lib | ||||||
| homepage: https://github.com/actions/toolkit/tree/main/packages/core | homepage: https://github.com/actions/toolkit/tree/main/packages/core | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								.licenses/npm/@actions/http-client-1.0.8.dep.yml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										32
									
								
								.licenses/npm/@actions/http-client-1.0.8.dep.yml
									
									
									
										generated
									
									
									
								
							| @ -1,32 +0,0 @@ | |||||||
| --- |  | ||||||
| name: "@actions/http-client" |  | ||||||
| version: 1.0.8 |  | ||||||
| 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: [] |  | ||||||
							
								
								
									
										20
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								README.md
									
									
									
									
									
								
							| @ -320,6 +320,26 @@ steps: | |||||||
| - run: pipenv install | - run: pipenv install | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | # Environment variables | ||||||
|  |  | ||||||
|  |  The `update-environment` flag defaults to `true`. | ||||||
|  |  With this setting, the action will add/update environment variables (e.g. `PATH`, `PKG_CONFIG_PATH`, `pythonLocation`) for `python` to just work out of the box. | ||||||
|  |  | ||||||
|  |  If `update-environment` is set to `false`, the action will not add/update environment variables. | ||||||
|  |  This can prove useful if you want the only side-effect to be to ensure python is installed and rely on the `python-path` output to run python. | ||||||
|  |  Such a requirement on side-effect could be because you don't want your composite action messing with your user's workflows. | ||||||
|  |  | ||||||
|  |  ```yaml | ||||||
|  |  steps: | ||||||
|  |    - uses: actions/checkout@v3 | ||||||
|  |    - uses: actions/setup-python@v4 | ||||||
|  |      id: cp310 | ||||||
|  |      with: | ||||||
|  |        python-version: '3.10' | ||||||
|  |        update-environment: false | ||||||
|  |    - run: ${{ steps.cp310.outputs.python-path }} my_script.py | ||||||
|  |  ``` | ||||||
|  |  | ||||||
| # Using `setup-python` with a self hosted runner | # Using `setup-python` with a self hosted runner | ||||||
|  |  | ||||||
| Python distributions are only available for the same [environments](https://github.com/actions/virtual-environments#available-environments) that GitHub Actions hosted environments are available for. If you are using an unsupported version of Ubuntu such as `19.04` or another Linux distribution such as Fedora, `setup-python` will not work. If you have a supported self-hosted runner and you would like to use `setup-python`, there are a few extra things you need to make sure are set up so that new versions of Python can be downloaded and configured on your runner. | Python distributions are only available for the same [environments](https://github.com/actions/virtual-environments#available-environments) that GitHub Actions hosted environments are available for. If you are using an unsupported version of Ubuntu such as `19.04` or another Linux distribution such as Fedora, `setup-python` will not work. If you have a supported self-hosted runner and you would like to use `setup-python`, there are a few extra things you need to make sure are set up so that new versions of Python can be downloaded and configured on your runner. | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ import {HttpClient} from '@actions/http-client'; | |||||||
| import * as ifm from '@actions/http-client/interfaces'; | import * as ifm from '@actions/http-client/interfaces'; | ||||||
| import * as tc from '@actions/tool-cache'; | import * as tc from '@actions/tool-cache'; | ||||||
| import * as exec from '@actions/exec'; | import * as exec from '@actions/exec'; | ||||||
|  | import * as core from '@actions/core'; | ||||||
|  |  | ||||||
| import * as path from 'path'; | import * as path from 'path'; | ||||||
| import * as semver from 'semver'; | import * as semver from 'semver'; | ||||||
| @ -148,6 +149,8 @@ describe('findPyPyVersion', () => { | |||||||
|   let spyWriteExactPyPyVersionFile: jest.SpyInstance; |   let spyWriteExactPyPyVersionFile: jest.SpyInstance; | ||||||
|   let spyCacheDir: jest.SpyInstance; |   let spyCacheDir: jest.SpyInstance; | ||||||
|   let spyChmodSync: jest.SpyInstance; |   let spyChmodSync: jest.SpyInstance; | ||||||
|  |   let spyCoreAddPath: jest.SpyInstance; | ||||||
|  |   let spyCoreExportVariable: jest.SpyInstance; | ||||||
|  |  | ||||||
|   beforeEach(() => { |   beforeEach(() => { | ||||||
|     tcFind = jest.spyOn(tc, 'find'); |     tcFind = jest.spyOn(tc, 'find'); | ||||||
| @ -201,6 +204,10 @@ describe('findPyPyVersion', () => { | |||||||
|  |  | ||||||
|     spyExistsSync = jest.spyOn(fs, 'existsSync'); |     spyExistsSync = jest.spyOn(fs, 'existsSync'); | ||||||
|     spyExistsSync.mockReturnValue(true); |     spyExistsSync.mockReturnValue(true); | ||||||
|  |  | ||||||
|  |     spyCoreAddPath = jest.spyOn(core, 'addPath'); | ||||||
|  |  | ||||||
|  |     spyCoreExportVariable = jest.spyOn(core, 'exportVariable'); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   afterEach(() => { |   afterEach(() => { | ||||||
| @ -211,22 +218,31 @@ 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) |       finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, true) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       resolvedPythonVersion: '3.6.12', |       resolvedPythonVersion: '3.6.12', | ||||||
|       resolvedPyPyVersion: '7.3.3' |       resolvedPyPyVersion: '7.3.3' | ||||||
|     }); |     }); | ||||||
|  |     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'pythonLocation', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'PKG_CONFIG_PATH', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   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) |       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true) | ||||||
|     ).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) |       finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true) | ||||||
|     ).rejects.toThrow(); |     ).rejects.toThrow(); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
| @ -238,16 +254,42 @@ 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) |       finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, true) | ||||||
|     ).resolves.toEqual({ |     ).resolves.toEqual({ | ||||||
|       resolvedPythonVersion: '3.7.9', |       resolvedPythonVersion: '3.7.9', | ||||||
|       resolvedPyPyVersion: '7.3.3' |       resolvedPyPyVersion: '7.3.3' | ||||||
|     }); |     }); | ||||||
|  |     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'pythonLocation', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'PKG_CONFIG_PATH', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('found and install successfully without environment update', 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) | ||||||
|  |     ).resolves.toEqual({ | ||||||
|  |       resolvedPythonVersion: '3.7.9', | ||||||
|  |       resolvedPyPyVersion: '7.3.3' | ||||||
|  |     }); | ||||||
|  |     expect(spyCoreAddPath).not.toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).not.toHaveBeenCalled(); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   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) |       finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture, true) | ||||||
|     ).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` | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -19,15 +19,26 @@ process.env['RUNNER_TOOL_CACHE'] = toolDir; | |||||||
| process.env['RUNNER_TEMP'] = tempDir; | process.env['RUNNER_TEMP'] = tempDir; | ||||||
|  |  | ||||||
| import * as tc from '@actions/tool-cache'; | import * as tc from '@actions/tool-cache'; | ||||||
|  | import * as core from '@actions/core'; | ||||||
| import * as finder from '../src/find-python'; | import * as finder from '../src/find-python'; | ||||||
| import * as installer from '../src/install-python'; | import * as installer from '../src/install-python'; | ||||||
|  |  | ||||||
| const manifestData = require('./data/versions-manifest.json'); | const manifestData = require('./data/versions-manifest.json'); | ||||||
|  |  | ||||||
| describe('Finder tests', () => { | describe('Finder tests', () => { | ||||||
|  |   let spyCoreAddPath: jest.SpyInstance; | ||||||
|  |   let spyCoreExportVariable: jest.SpyInstance; | ||||||
|  |  | ||||||
|  |   beforeEach(() => { | ||||||
|  |     spyCoreAddPath = jest.spyOn(core, 'addPath'); | ||||||
|  |  | ||||||
|  |     spyCoreExportVariable = jest.spyOn(core, 'exportVariable'); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   afterEach(() => { |   afterEach(() => { | ||||||
|     jest.resetAllMocks(); |     jest.resetAllMocks(); | ||||||
|     jest.clearAllMocks(); |     jest.clearAllMocks(); | ||||||
|  |     jest.restoreAllMocks(); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('Finds Python if it is installed', async () => { |   it('Finds Python if it is installed', async () => { | ||||||
| @ -35,7 +46,27 @@ 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'); |     await finder.useCpythonVersion('3.x', 'x64', true); | ||||||
|  |     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'pythonLocation', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'PKG_CONFIG_PATH', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('Finds Python if it is installed without environment update', async () => { | ||||||
|  |     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', false); | ||||||
|  |     expect(spyCoreAddPath).not.toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).not.toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).not.toHaveBeenCalled(); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('Finds stable Python version if it is not installed, but exists in the manifest', async () => { |   it('Finds stable Python version if it is not installed, but exists in the manifest', async () => { | ||||||
| @ -52,7 +83,16 @@ 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'); |     await finder.useCpythonVersion('1.2.3', 'x64', true); | ||||||
|  |     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'pythonLocation', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'PKG_CONFIG_PATH', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   it('Finds pre-release Python version in the manifest', async () => { |   it('Finds pre-release Python version in the manifest', async () => { | ||||||
| @ -74,17 +114,28 @@ describe('Finder tests', () => { | |||||||
|       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'); |     await finder.useCpythonVersion('1.2.3-beta.2', 'x64', true); | ||||||
|  |     expect(spyCoreAddPath).toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'pythonLocation', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|  |     expect(spyCoreExportVariable).toHaveBeenCalledWith( | ||||||
|  |       'PKG_CONFIG_PATH', | ||||||
|  |       expect.anything() | ||||||
|  |     ); | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   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'); |       await finder.useCpythonVersion('3.300000', 'x64', true); | ||||||
|     } catch { |     } catch { | ||||||
|       thrown = true; |       thrown = true; | ||||||
|     } |     } | ||||||
|     expect(thrown).toBeTruthy(); |     expect(thrown).toBeTruthy(); | ||||||
|  |     expect(spyCoreAddPath).not.toHaveBeenCalled(); | ||||||
|  |     expect(spyCoreExportVariable).not.toHaveBeenCalled(); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -17,6 +17,9 @@ inputs: | |||||||
|     default: ${{ github.token }} |     default: ${{ github.token }} | ||||||
|   cache-dependency-path: |   cache-dependency-path: | ||||||
|     description: 'Used to specify the path to dependency files. Supports wildcards or a list of file names for caching multiple dependencies.' |     description: 'Used to specify the path to dependency files. Supports wildcards or a list of file names for caching multiple dependencies.' | ||||||
|  |   update-environment: | ||||||
|  |     description: 'Set this option if you want the action to update environment variables.' | ||||||
|  |     default: true | ||||||
| outputs: | outputs: | ||||||
|   python-version: |   python-version: | ||||||
|     description: "The installed python version. Useful when given a version range as input." |     description: "The installed python version. Useful when given a version range as input." | ||||||
|  | |||||||
							
								
								
									
										1890
									
								
								dist/cache-save/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1890
									
								
								dist/cache-save/index.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1384
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1384
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										48
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										48
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -10,7 +10,7 @@ | |||||||
|       "license": "MIT", |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@actions/cache": "^2.0.2", |         "@actions/cache": "^2.0.2", | ||||||
|         "@actions/core": "^1.2.3", |         "@actions/core": "^1.7.0", | ||||||
|         "@actions/exec": "^1.1.0", |         "@actions/exec": "^1.1.0", | ||||||
|         "@actions/glob": "^0.2.0", |         "@actions/glob": "^0.2.0", | ||||||
|         "@actions/io": "^1.0.2", |         "@actions/io": "^1.0.2", | ||||||
| @ -55,14 +55,6 @@ | |||||||
|         "minimatch": "^3.0.4" |         "minimatch": "^3.0.4" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@actions/cache/node_modules/@actions/http-client": { |  | ||||||
|       "version": "1.0.11", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", |  | ||||||
|       "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", |  | ||||||
|       "dependencies": { |  | ||||||
|         "tunnel": "0.0.6" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@actions/cache/node_modules/semver": { |     "node_modules/@actions/cache/node_modules/semver": { | ||||||
|       "version": "6.3.0", |       "version": "6.3.0", | ||||||
|       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", |       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", | ||||||
| @ -72,9 +64,12 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@actions/core": { |     "node_modules/@actions/core": { | ||||||
|       "version": "1.2.6", |       "version": "1.7.0", | ||||||
|       "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz", |       "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.7.0.tgz", | ||||||
|       "integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==" |       "integrity": "sha512-7fPSS7yKOhTpgLMbw7lBLc1QJWvJBBAgyTX2PEhagWcKK8t0H8AKCoPMfnrHqIm5cRYH4QFPqD1/ruhuUE7YcQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@actions/http-client": "^1.0.11" | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@actions/exec": { |     "node_modules/@actions/exec": { | ||||||
|       "version": "1.1.0", |       "version": "1.1.0", | ||||||
| @ -94,9 +89,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@actions/http-client": { |     "node_modules/@actions/http-client": { | ||||||
|       "version": "1.0.8", |       "version": "1.0.11", | ||||||
|       "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", |       "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", | ||||||
|       "integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", |       "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "tunnel": "0.0.6" |         "tunnel": "0.0.6" | ||||||
|       } |       } | ||||||
| @ -11361,14 +11356,6 @@ | |||||||
|             "minimatch": "^3.0.4" |             "minimatch": "^3.0.4" | ||||||
|           } |           } | ||||||
|         }, |         }, | ||||||
|         "@actions/http-client": { |  | ||||||
|           "version": "1.0.11", |  | ||||||
|           "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", |  | ||||||
|           "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", |  | ||||||
|           "requires": { |  | ||||||
|             "tunnel": "0.0.6" |  | ||||||
|           } |  | ||||||
|         }, |  | ||||||
|         "semver": { |         "semver": { | ||||||
|           "version": "6.3.0", |           "version": "6.3.0", | ||||||
|           "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", |           "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", | ||||||
| @ -11377,9 +11364,12 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@actions/core": { |     "@actions/core": { | ||||||
|       "version": "1.2.6", |       "version": "1.7.0", | ||||||
|       "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz", |       "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.7.0.tgz", | ||||||
|       "integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==" |       "integrity": "sha512-7fPSS7yKOhTpgLMbw7lBLc1QJWvJBBAgyTX2PEhagWcKK8t0H8AKCoPMfnrHqIm5cRYH4QFPqD1/ruhuUE7YcQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "@actions/http-client": "^1.0.11" | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     "@actions/exec": { |     "@actions/exec": { | ||||||
|       "version": "1.1.0", |       "version": "1.1.0", | ||||||
| @ -11399,9 +11389,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@actions/http-client": { |     "@actions/http-client": { | ||||||
|       "version": "1.0.8", |       "version": "1.0.11", | ||||||
|       "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", |       "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", | ||||||
|       "integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", |       "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "tunnel": "0.0.6" |         "tunnel": "0.0.6" | ||||||
|       } |       } | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ | |||||||
|   "license": "MIT", |   "license": "MIT", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@actions/cache": "^2.0.2", |     "@actions/cache": "^2.0.2", | ||||||
|     "@actions/core": "^1.2.3", |     "@actions/core": "^1.7.0", | ||||||
|     "@actions/exec": "^1.1.0", |     "@actions/exec": "^1.1.0", | ||||||
|     "@actions/glob": "^0.2.0", |     "@actions/glob": "^0.2.0", | ||||||
|     "@actions/io": "^1.0.2", |     "@actions/io": "^1.0.2", | ||||||
|  | |||||||
| @ -20,7 +20,8 @@ interface IPyPyVersionSpec { | |||||||
|  |  | ||||||
| export async function findPyPyVersion( | export async function findPyPyVersion( | ||||||
|   versionSpec: string, |   versionSpec: string, | ||||||
|   architecture: string |   architecture: string, | ||||||
|  |   updateEnvironment: boolean | ||||||
| ): Promise<{resolvedPyPyVersion: string; resolvedPythonVersion: string}> { | ): Promise<{resolvedPyPyVersion: string; resolvedPythonVersion: string}> { | ||||||
|   let resolvedPyPyVersion = ''; |   let resolvedPyPyVersion = ''; | ||||||
|   let resolvedPythonVersion = ''; |   let resolvedPythonVersion = ''; | ||||||
| @ -54,10 +55,12 @@ export async function findPyPyVersion( | |||||||
|     `python${binaryExtension}` |     `python${binaryExtension}` | ||||||
|   ); |   ); | ||||||
|   const pythonLocation = pypyInstall.getPyPyBinaryPath(installDir); |   const pythonLocation = pypyInstall.getPyPyBinaryPath(installDir); | ||||||
|   core.exportVariable('pythonLocation', installDir); |   if (updateEnvironment) { | ||||||
|   core.exportVariable('PKG_CONFIG_PATH', pythonLocation + '/lib/pkgconfig'); |     core.exportVariable('pythonLocation', installDir); | ||||||
|   core.addPath(pythonLocation); |     core.exportVariable('PKG_CONFIG_PATH', pythonLocation + '/lib/pkgconfig'); | ||||||
|   core.addPath(_binDir); |     core.addPath(pythonLocation); | ||||||
|  |     core.addPath(_binDir); | ||||||
|  |   } | ||||||
|   core.setOutput('python-version', 'pypy' + resolvedPyPyVersion.trim()); |   core.setOutput('python-version', 'pypy' + resolvedPyPyVersion.trim()); | ||||||
|   core.setOutput('python-path', pythonPath); |   core.setOutput('python-path', pythonPath); | ||||||
|  |  | ||||||
|  | |||||||
| @ -32,7 +32,8 @@ function binDir(installDir: string): string { | |||||||
|  |  | ||||||
| export async function useCpythonVersion( | export async function useCpythonVersion( | ||||||
|   version: string, |   version: string, | ||||||
|   architecture: string |   architecture: string, | ||||||
|  |   updateEnvironment: boolean | ||||||
| ): Promise<InstalledVersion> { | ): Promise<InstalledVersion> { | ||||||
|   const desugaredVersionSpec = desugarDevVersion(version); |   const desugaredVersionSpec = desugarDevVersion(version); | ||||||
|   const semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); |   const semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec); | ||||||
| @ -69,46 +70,47 @@ export async function useCpythonVersion( | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   core.exportVariable('pythonLocation', installDir); |  | ||||||
|   core.exportVariable('PKG_CONFIG_PATH', installDir + '/lib/pkgconfig'); |  | ||||||
|  |  | ||||||
|   if (IS_LINUX) { |  | ||||||
|     const libPath = process.env.LD_LIBRARY_PATH |  | ||||||
|       ? `:${process.env.LD_LIBRARY_PATH}` |  | ||||||
|       : ''; |  | ||||||
|     const pyLibPath = path.join(installDir, 'lib'); |  | ||||||
|  |  | ||||||
|     if (!libPath.split(':').includes(pyLibPath)) { |  | ||||||
|       core.exportVariable('LD_LIBRARY_PATH', pyLibPath + libPath); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   const _binDir = binDir(installDir); |   const _binDir = binDir(installDir); | ||||||
|   const binaryExtension = IS_WINDOWS ? '.exe' : ''; |   const binaryExtension = IS_WINDOWS ? '.exe' : ''; | ||||||
|   const pythonPath = path.join( |   const pythonPath = path.join( | ||||||
|     IS_WINDOWS ? installDir : _binDir, |     IS_WINDOWS ? installDir : _binDir, | ||||||
|     `python${binaryExtension}` |     `python${binaryExtension}` | ||||||
|   ); |   ); | ||||||
|   core.addPath(installDir); |   if (updateEnvironment) { | ||||||
|   core.addPath(_binDir); |     core.exportVariable('pythonLocation', installDir); | ||||||
|  |     core.exportVariable('PKG_CONFIG_PATH', installDir + '/lib/pkgconfig'); | ||||||
|  |  | ||||||
|   if (IS_WINDOWS) { |     if (IS_LINUX) { | ||||||
|     // Add --user directory |       const libPath = process.env.LD_LIBRARY_PATH | ||||||
|     // `installDir` from tool cache should look like $RUNNER_TOOL_CACHE/Python/<semantic version>/x64/ |         ? `:${process.env.LD_LIBRARY_PATH}` | ||||||
|     // So if `findLocalTool` succeeded above, we must have a conformant `installDir` |         : ''; | ||||||
|     const version = path.basename(path.dirname(installDir)); |       const pyLibPath = path.join(installDir, 'lib'); | ||||||
|     const major = semver.major(version); |  | ||||||
|     const minor = semver.minor(version); |  | ||||||
|  |  | ||||||
|     const userScriptsDir = path.join( |       if (!libPath.split(':').includes(pyLibPath)) { | ||||||
|       process.env['APPDATA'] || '', |         core.exportVariable('LD_LIBRARY_PATH', pyLibPath + libPath); | ||||||
|       'Python', |       } | ||||||
|       `Python${major}${minor}`, |     } | ||||||
|       'Scripts' |     core.addPath(installDir); | ||||||
|     ); |     core.addPath(_binDir); | ||||||
|     core.addPath(userScriptsDir); |  | ||||||
|  |     if (IS_WINDOWS) { | ||||||
|  |       // Add --user directory | ||||||
|  |       // `installDir` from tool cache should look like $RUNNER_TOOL_CACHE/Python/<semantic version>/x64/ | ||||||
|  |       // So if `findLocalTool` succeeded above, we must have a conformant `installDir` | ||||||
|  |       const version = path.basename(path.dirname(installDir)); | ||||||
|  |       const major = semver.major(version); | ||||||
|  |       const minor = semver.minor(version); | ||||||
|  |  | ||||||
|  |       const userScriptsDir = path.join( | ||||||
|  |         process.env['APPDATA'] || '', | ||||||
|  |         'Python', | ||||||
|  |         `Python${major}${minor}`, | ||||||
|  |         'Scripts' | ||||||
|  |       ); | ||||||
|  |       core.addPath(userScriptsDir); | ||||||
|  |     } | ||||||
|  |     // On Linux and macOS, pip will create the --user directory and add it to PATH as needed. | ||||||
|   } |   } | ||||||
|   // On Linux and macOS, pip will create the --user directory and add it to PATH as needed. |  | ||||||
|  |  | ||||||
|   const installed = versionFromPath(installDir); |   const installed = versionFromPath(installDir); | ||||||
|   core.setOutput('python-version', installed); |   core.setOutput('python-version', installed); | ||||||
|  | |||||||
| @ -64,14 +64,23 @@ async function run() { | |||||||
|     if (version) { |     if (version) { | ||||||
|       let pythonVersion: string; |       let pythonVersion: string; | ||||||
|       const arch: string = core.getInput('architecture') || os.arch(); |       const arch: string = core.getInput('architecture') || os.arch(); | ||||||
|  |       const updateEnvironment = core.getBooleanInput('update-environment'); | ||||||
|       if (isPyPyVersion(version)) { |       if (isPyPyVersion(version)) { | ||||||
|         const installed = await finderPyPy.findPyPyVersion(version, arch); |         const installed = await finderPyPy.findPyPyVersion( | ||||||
|  |           version, | ||||||
|  |           arch, | ||||||
|  |           updateEnvironment | ||||||
|  |         ); | ||||||
|         pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; |         pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; | ||||||
|         core.info( |         core.info( | ||||||
|           `Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})` |           `Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})` | ||||||
|         ); |         ); | ||||||
|       } else { |       } else { | ||||||
|         const installed = await finder.useCpythonVersion(version, arch); |         const installed = await finder.useCpythonVersion( | ||||||
|  |           version, | ||||||
|  |           arch, | ||||||
|  |           updateEnvironment | ||||||
|  |         ); | ||||||
|         pythonVersion = installed.version; |         pythonVersion = installed.version; | ||||||
|         core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); |         core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||||
|       } |       } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Matthieu Darbois
					Matthieu Darbois