mirror of
				https://kkgithub.com/actions/setup-python.git
				synced 2025-10-31 18:51:51 +08:00 
			
		
		
		
	Compare commits
	
		
			36 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d09bd5e600 | |||
| f72db171ab | |||
| 53e15292cd | |||
| 3f82819745 | |||
| 397252c582 | |||
| de977ad132 | |||
| 22c6af91ce | |||
| 081a3cf1a5 | |||
| ff706563d7 | |||
| fff15a21cc | |||
| c57f79353b | |||
| fd8f0a9fb8 | |||
| ae11205ec6 | |||
| 8f73c1495f | |||
| e31727ce0a | |||
| a69041ca9f | |||
| 5e1e05c694 | |||
| 0b56b76337 | |||
| 22daa094b8 | |||
| ac4e858835 | |||
| 1ce308808a | |||
| c36dc43e7b | |||
| 4e6b5f40fc | |||
| bcc31375e1 | |||
| 85a7430316 | |||
| 6a4c6c1309 | |||
| 3a63f5d525 | |||
| 4a33d3c467 | |||
| abfd16b121 | |||
| 4176166af9 | |||
| 91712e11bb | |||
| f4b66dec00 | |||
| 65fe6a82c7 | |||
| 011c443f81 | |||
| 3250b5373c | |||
| 0bcf8ef2ba | 
							
								
								
									
										2
									
								
								.github/workflows/e2e-cache.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/e2e-cache.yml
									
									
									
									
										vendored
									
									
								
							| @ -61,7 +61,7 @@ jobs: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: [ubuntu-latest, windows-latest, macos-latest] | ||||
|         python-version: ['3.9', 'pypy-3.7-v7.x'] | ||||
|         python-version: ['3.9', 'pypy-3.8'] | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - name: Install poetry | ||||
|  | ||||
							
								
								
									
										23
									
								
								.github/workflows/test-pypy.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								.github/workflows/test-pypy.yml
									
									
									
									
										vendored
									
									
								
							| @ -22,6 +22,7 @@ jobs: | ||||
|         pypy: | ||||
|         - 'pypy-2.7' | ||||
|         - 'pypy-3.7' | ||||
|         - 'pypy3.9' | ||||
|         - 'pypy-2.7-v7.3.4' | ||||
|         - 'pypy-3.7-v7.3.5' | ||||
|         - 'pypy-3.7-v7.3.4' | ||||
| @ -29,18 +30,38 @@ jobs: | ||||
|         - 'pypy-3.7-v7.x' | ||||
|         - 'pypy-2.7-v7.3.4rc1' | ||||
|         - 'pypy-3.7-nightly' | ||||
|         - 'pypy3.8-v7.3.7' | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|    | ||||
|       - name: setup-python ${{ matrix.pypy }} | ||||
|         id: setup-python | ||||
|         uses: ./ | ||||
|         with: | ||||
|           python-version: ${{ matrix.pypy }} | ||||
|    | ||||
|  | ||||
|       - name: Check python-path | ||||
|         run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' | ||||
|         shell: bash | ||||
|  | ||||
|       - name: PyPy and Python version | ||||
|         run: python --version | ||||
|    | ||||
|       - name: Run simple code | ||||
|         run: python -c 'import math; print(math.factorial(5))' | ||||
|  | ||||
|       - name: Assert PyPy is running | ||||
|         run: | | ||||
|           import platform | ||||
|           assert platform.python_implementation().lower() == "pypy" | ||||
|         shell: python | ||||
|  | ||||
|       - name: Assert expected binaries (or symlinks) are present | ||||
|         run: | | ||||
|           EXECUTABLE=${{ matrix.pypy }} | ||||
|           EXECUTABLE=${EXECUTABLE/pypy-/pypy}  # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name | ||||
|           EXECUTABLE=${EXECUTABLE%%-*}  # remove any -* suffixe | ||||
|           ${EXECUTABLE} --version | ||||
|         shell: bash | ||||
|  | ||||
							
								
								
									
										102
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										102
									
								
								.github/workflows/test-python.yml
									
									
									
									
										vendored
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| name: Validate Python e2e | ||||
| on:  | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - main | ||||
| @ -10,28 +10,9 @@ on: | ||||
|       - '**.md' | ||||
|   schedule: | ||||
|     - cron: 30 3 * * * | ||||
|   workflow_dispatch: | ||||
|  | ||||
| jobs: | ||||
|   default-version: | ||||
|     name: Setup default version | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04] | ||||
|     steps: | ||||
|     - name: Checkout | ||||
|       uses: actions/checkout@v2 | ||||
|  | ||||
|     - name: setup default python  | ||||
|       uses: ./ | ||||
|  | ||||
|     - name: Validate version | ||||
|       run: python --version | ||||
|  | ||||
|     - name: Run simple python code | ||||
|       run: python -c 'import math; print(math.factorial(5))' | ||||
|  | ||||
|   setup-versions-from-manifest: | ||||
|     name: Setup ${{ matrix.python }} ${{ matrix.os }} | ||||
|     runs-on: ${{ matrix.os }} | ||||
| @ -42,13 +23,56 @@ jobs: | ||||
|         python: [3.5.4, 3.6.7, 3.7.5, 3.8.1] | ||||
|     steps: | ||||
|     - name: Checkout | ||||
|       uses: actions/checkout@v2 | ||||
|       uses: actions/checkout@v3 | ||||
|  | ||||
|     - name: setup-python ${{ matrix.python }} | ||||
|       id: setup-python | ||||
|       uses: ./ | ||||
|       with: | ||||
|         python-version: ${{ matrix.python }} | ||||
|  | ||||
|     - name: Check python-path | ||||
|       run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' | ||||
|       shell: bash | ||||
|  | ||||
|     - name: Validate version | ||||
|       run: | | ||||
|         $pythonVersion = (python --version) | ||||
|         if ("Python ${{ matrix.python }}" -ne "$pythonVersion"){ | ||||
|           Write-Host "The current version is $pythonVersion; expected version is ${{ matrix.python }}" | ||||
|           exit 1 | ||||
|         } | ||||
|         $pythonVersion | ||||
|       shell: pwsh | ||||
|  | ||||
|     - name: Run simple code | ||||
|       run: python -c 'import math; print(math.factorial(5))' | ||||
|  | ||||
|   setup-versions-from-file: | ||||
|     name: Setup ${{ matrix.python }} ${{ matrix.os }} version file | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04] | ||||
|         python: [3.5.4, 3.6.7, 3.7.5, 3.8.1] | ||||
|     steps: | ||||
|     - name: Checkout | ||||
|       uses: actions/checkout@v3 | ||||
|  | ||||
|     - name: build-version-file ${{ matrix.python }} | ||||
|       run: echo ${{ matrix.python }} > .python-version | ||||
|  | ||||
|     - name: setup-python ${{ matrix.python }} | ||||
|       id: setup-python | ||||
|       uses: ./ | ||||
|       with: | ||||
|         python-version-file: '.python-version' | ||||
|  | ||||
|     - name: Check python-path | ||||
|       run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' | ||||
|       shell: bash | ||||
|  | ||||
|     - name: Validate version | ||||
|       run: | | ||||
|         $pythonVersion = (python --version) | ||||
| @ -71,13 +95,18 @@ jobs: | ||||
|         os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04] | ||||
|     steps: | ||||
|     - name: Checkout | ||||
|       uses: actions/checkout@v2 | ||||
|       uses: actions/checkout@v3 | ||||
|  | ||||
|     - name: setup-python 3.9.0-beta.4 | ||||
|       id: setup-python | ||||
|       uses: ./ | ||||
|       with: | ||||
|         python-version: '3.9.0-beta.4' | ||||
|  | ||||
|     - name: Check python-path | ||||
|       run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' | ||||
|       shell: bash | ||||
|  | ||||
|     - name: Validate version | ||||
|       run: | | ||||
|         $pythonVersion = (python --version) | ||||
| @ -91,3 +120,30 @@ jobs: | ||||
|     - name: Run simple code | ||||
|       run: python -c 'import math; print(math.factorial(5))' | ||||
|  | ||||
|   setup-dev-version: | ||||
|     name: Setup 3.9-dev ${{ 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.9-dev | ||||
|       id: setup-python | ||||
|       uses: ./ | ||||
|       with: | ||||
|         python-version: '3.9-dev' | ||||
|  | ||||
|     - 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.9.') }} | ||||
|       shell: bash | ||||
|  | ||||
|     - name: Run simple code | ||||
|       run: python -c 'import math; print(math.factorial(5))' | ||||
|  | ||||
							
								
								
									
										12
									
								
								.github/workflows/workflow.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/workflow.yml
									
									
									
									
										vendored
									
									
								
							| @ -14,7 +14,7 @@ jobs: | ||||
|     runs-on: ${{ matrix.operating-system }} | ||||
|     strategy: | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-20.04, windows-latest] | ||||
|         operating-system: [ubuntu-latest, windows-latest] | ||||
|     steps: | ||||
|     - name: Checkout | ||||
|       uses: actions/checkout@v2 | ||||
| @ -89,3 +89,13 @@ jobs: | ||||
|         python-version: 3.8.1 | ||||
|     - name: Verify 3.8.1 | ||||
|       run: python __tests__/verify-python.py 3.8.1 | ||||
|  | ||||
|     - name: Run with setup-python 3.10 | ||||
|       id: cp310 | ||||
|       uses: ./ | ||||
|       with: | ||||
|         python-version: "3.10" | ||||
|     - name: Verify 3.10 | ||||
|       run: python __tests__/verify-python.py 3.10 | ||||
|     - name: Run python-path sample 3.10 | ||||
|       run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version | ||||
|  | ||||
							
								
								
									
										2
									
								
								.licenses/npm/@actions/core.dep.yml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.licenses/npm/@actions/core.dep.yml
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| --- | ||||
| name: "@actions/core" | ||||
| version: 1.10.0 | ||||
| version: 1.2.6 | ||||
| type: npm | ||||
| summary: Actions core lib | ||||
| homepage: https://github.com/actions/toolkit/tree/main/packages/core | ||||
|  | ||||
							
								
								
									
										32
									
								
								.licenses/npm/@actions/http-client-2.1.0.dep.yml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										32
									
								
								.licenses/npm/@actions/http-client-2.1.0.dep.yml
									
									
									
										generated
									
									
									
								
							| @ -1,32 +0,0 @@ | ||||
| --- | ||||
| name: "@actions/http-client" | ||||
| version: 2.1.0 | ||||
| type: npm | ||||
| summary: Actions Http Client | ||||
| homepage: https://github.com/actions/toolkit/tree/main/packages/http-client | ||||
| 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: [] | ||||
							
								
								
									
										76
									
								
								CODE_OF_CONDUCT.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								CODE_OF_CONDUCT.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | ||||
| # Contributor Covenant Code of Conduct | ||||
|  | ||||
| ## Our Pledge | ||||
|  | ||||
| In the interest of fostering an open and welcoming environment, we as | ||||
| contributors and maintainers pledge to make participation in our project and | ||||
| our community a harassment-free experience for everyone, regardless of age, body | ||||
| size, disability, ethnicity, sex characteristics, gender identity and expression, | ||||
| level of experience, education, socio-economic status, nationality, personal | ||||
| appearance, race, religion, or sexual identity and orientation. | ||||
|  | ||||
| ## Our Standards | ||||
|  | ||||
| Examples of behavior that contributes to creating a positive environment | ||||
| include: | ||||
|  | ||||
| * Using welcoming and inclusive language | ||||
| * Being respectful of differing viewpoints and experiences | ||||
| * Gracefully accepting constructive criticism | ||||
| * Focusing on what is best for the community | ||||
| * Showing empathy towards other community members | ||||
|  | ||||
| Examples of unacceptable behavior by participants include: | ||||
|  | ||||
| * The use of sexualized language or imagery and unwelcome sexual attention or | ||||
|   advances | ||||
| * Trolling, insulting/derogatory comments, and personal or political attacks | ||||
| * Public or private harassment | ||||
| * Publishing others' private information, such as a physical or electronic | ||||
|   address, without explicit permission | ||||
| * Other conduct which could reasonably be considered inappropriate in a | ||||
|   professional setting | ||||
|  | ||||
| ## Our Responsibilities | ||||
|  | ||||
| Project maintainers are responsible for clarifying the standards of acceptable | ||||
| behavior and are expected to take appropriate and fair corrective action in | ||||
| response to any instances of unacceptable behavior. | ||||
|  | ||||
| Project maintainers have the right and responsibility to remove, edit, or | ||||
| reject comments, commits, code, wiki edits, issues, and other contributions | ||||
| that are not aligned to this Code of Conduct, or to ban temporarily or | ||||
| permanently any contributor for other behaviors that they deem inappropriate, | ||||
| threatening, offensive, or harmful. | ||||
|  | ||||
| ## Scope | ||||
|  | ||||
| This Code of Conduct applies within all project spaces, and it also applies when | ||||
| an individual is representing the project or its community in public spaces. | ||||
| Examples of representing a project or community include using an official | ||||
| project e-mail address, posting via an official social media account, or acting | ||||
| as an appointed representative at an online or offline event. Representation of | ||||
| a project may be further defined and clarified by project maintainers. | ||||
|  | ||||
| ## Enforcement | ||||
|  | ||||
| Instances of abusive, harassing, or otherwise unacceptable behavior may be | ||||
| reported by contacting the project team at opensource+actions/setup-python@github.com. All | ||||
| complaints will be reviewed and investigated and will result in a response that | ||||
| is deemed necessary and appropriate to the circumstances. The project team is | ||||
| obligated to maintain confidentiality with regard to the reporter of an incident. | ||||
| Further details of specific enforcement policies may be posted separately. | ||||
|  | ||||
| Project maintainers who do not follow or enforce the Code of Conduct in good | ||||
| faith may face temporary or permanent repercussions as determined by other | ||||
| members of the project's leadership. | ||||
|  | ||||
| ## Attribution | ||||
|  | ||||
| This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, | ||||
| available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html | ||||
|  | ||||
| [homepage]: https://www.contributor-covenant.org | ||||
|  | ||||
| For answers to common questions about this code of conduct, see | ||||
| https://www.contributor-covenant.org/faq | ||||
							
								
								
									
										51
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								README.md
									
									
									
									
									
								
							| @ -43,7 +43,7 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       matrix: | ||||
|         python-version: [ '2.x', '3.x', 'pypy-2.7', 'pypy-3.7', 'pypy-3.8' ] | ||||
|         python-version: [ '2.x', '3.x', 'pypy2.7', 'pypy3.7', 'pypy3.8' ] | ||||
|     name: Python ${{ matrix.python-version }} sample | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
| @ -63,7 +63,7 @@ jobs: | ||||
|     strategy: | ||||
|       matrix: | ||||
|         os: [ubuntu-latest, macos-latest, windows-latest] | ||||
|         python-version: ['2.7', '3.7', '3.8', '3.9', '3.10', 'pypy-2.7', 'pypy-3.8'] | ||||
|         python-version: ['2.7', '3.7', '3.8', '3.9', '3.10', 'pypy2.7', 'pypy3.8'] | ||||
|         exclude: | ||||
|           - os: macos-latest | ||||
|             python-version: '3.8' | ||||
| @ -125,9 +125,9 @@ jobs: | ||||
|     strategy: | ||||
|       matrix: | ||||
|         python-version: | ||||
|         - 'pypy-3.7' # the latest available version of PyPy that supports Python 3.7 | ||||
|         - 'pypy-3.7-v7.3.3' # Python 3.7 and PyPy 7.3.3 | ||||
|         - 'pypy-3.8' # the latest available version of PyPy that supports Python 3.8 | ||||
|         - 'pypy3.7' # the latest available version of PyPy that supports Python 3.7 | ||||
|         - 'pypy3.7-v7.3.3' # Python 3.7 and PyPy 7.3.3 | ||||
|         - 'pypy3.8' # the latest available version of PyPy that supports Python 3.8 | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|     - uses: actions/setup-python@v3 | ||||
| @ -137,6 +137,22 @@ jobs: | ||||
| ``` | ||||
| More details on PyPy syntax and examples of using preview / nightly versions of PyPy can be found in the [Available versions of PyPy](#available-versions-of-pypy) section. | ||||
|  | ||||
| An output is available with the absolute path of the python interpreter executable if you need it: | ||||
| ```yaml | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|     - uses: actions/setup-python@v3 | ||||
|       id: cp310 | ||||
|       with: | ||||
|         python-version: "3.10" | ||||
|     - run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version | ||||
| ``` | ||||
|  | ||||
| >The environment variable `pythonLocation` also becomes available after Python or PyPy installation. It contains the absolute path to the folder where the desired version of Python or PyPy is installed. | ||||
|  | ||||
| # Getting started with Python + Actions | ||||
|  | ||||
| Check out our detailed guide on using [Python with GitHub Actions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-python-with-github-actions). | ||||
| @ -150,10 +166,13 @@ Check out our detailed guide on using [Python with GitHub Actions](https://help. | ||||
|     - For every minor version of Python, expect only the latest patch to be preinstalled. | ||||
|     - If `3.8.1` is installed for example, and `3.8.2` is released, expect `3.8.1` to be removed and replaced by `3.8.2` in the tools cache. | ||||
|     - If the exact patch version doesn't matter to you, specifying just the major and minor version will get you the latest preinstalled patch version. In the previous example, the version spec `3.8` will use the `3.8.2` Python version found in the cache. | ||||
|     - Use `-dev` instead of a patch number (e.g., `3.11-dev`) to install the latest patch version release for a given minor version, *alpha and beta releases included*. | ||||
| - Downloadable Python versions from GitHub Releases ([actions/python-versions](https://github.com/actions/python-versions/releases)). | ||||
|     - All available versions are listed in the [version-manifest.json](https://github.com/actions/python-versions/blob/main/versions-manifest.json) file. | ||||
|     - If there is a specific version of Python that is not available, you can open an issue here | ||||
|  | ||||
| **Note:** Python versions used in this action are generated in the [python-versions](https://github.com/actions/python-versions) repository. For macOS and Ubuntu images python versions are built from the source code. For Windows the python-versions repository uses installation executable. For more information please refer to the [python-versions](https://github.com/actions/python-versions) repository. | ||||
|  | ||||
|  # Available versions of PyPy | ||||
|  | ||||
|  `setup-python` is able to configure PyPy from two sources: | ||||
| @ -161,7 +180,7 @@ Check out our detailed guide on using [Python with GitHub Actions](https://help. | ||||
| - Preinstalled versions of PyPy in the tools cache on GitHub-hosted runners | ||||
|   - For detailed information regarding the available versions of PyPy that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software). | ||||
|   - For the latest PyPy release, all versions of Python are cached. | ||||
|   - Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy-3.7`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy-3.7-v7.3.3`. | ||||
|   - Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy3.7` or `pypy-3.7`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy3.7-v7.3.3` or `pypy-3.7-v7.3.3`. | ||||
|  | ||||
| - Downloadable PyPy versions from the [official PyPy site](https://downloads.python.org/pypy/). | ||||
|   - All available versions that we can download are listed in [versions.json](https://downloads.python.org/pypy/versions.json) file. | ||||
| @ -179,8 +198,8 @@ GitHub hosted runners have a tools cache that comes with a few versions of Pytho | ||||
| |**PyPy Tool Cache**|`RUNNER_TOOL_CACHE/PyPy/*`| | ||||
|  | ||||
| GitHub virtual environments are setup in [actions/virtual-environments](https://github.com/actions/virtual-environments). During the setup, the available versions of Python and PyPy are automatically downloaded, setup and documented. | ||||
| - [Tools cache setup for Ubuntu](https://github.com/actions/virtual-environments/blob/main/images/linux/scripts/installers/hosted-tool-cache.sh) | ||||
| - [Tools cache setup for Windows](https://github.com/actions/virtual-environments/blob/main/images/win/scripts/Installers/Download-ToolCache.ps1) | ||||
| - Tools cache setup for Ubuntu: [Install-Toolset.ps1](https://github.com/actions/virtual-environments/blob/main/images/linux/scripts/installers/Install-Toolset.ps1) [Configure-Toolset.ps1](https://github.com/actions/virtual-environments/blob/main/images/linux/scripts/installers/Configure-Toolset.ps1) | ||||
| - Tools cache setup for Windows: [Install-Toolset.ps1](https://github.com/actions/virtual-environments/blob/main/images/win/scripts/Installers/Install-Toolset.ps1) [Configure-Toolset.ps1](https://github.com/actions/virtual-environments/blob/main/images/win/scripts/Installers/Configure-Toolset.ps1) | ||||
|  | ||||
| # Specifying a Python version | ||||
|  | ||||
| @ -194,17 +213,17 @@ You should specify only a major and minor version if you are okay with the most | ||||
|   - Using the most recent patch version will result in a very quick setup since no downloads will be required since a locally installed version Python on the runner will be used. | ||||
|  | ||||
| # Specifying a PyPy version | ||||
| The version of PyPy should be specified in the format `pypy-<python_version>[-v<pypy_version>]`. | ||||
| The version of PyPy should be specified in the format `pypy<python_version>[-v<pypy_version>]` or `pypy-<python_version>[-v<pypy_version>]`. | ||||
| The `<pypy_version>` parameter is optional and can be skipped. The latest version will be used in this case. | ||||
|  | ||||
| ``` | ||||
| pypy-3.7 # the latest available version of PyPy that supports Python 3.7 | ||||
| pypy-3.8 # the latest available version of PyPy that supports Python 3.8 | ||||
| pypy-2.7 # the latest available version of PyPy that supports Python 2.7 | ||||
| pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3 | ||||
| pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x | ||||
| pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy | ||||
| pypy-3.7-nightly # Python 3.7 and nightly PyPy | ||||
| pypy3.7 or pypy-3.7 # the latest available version of PyPy that supports Python 3.7 | ||||
| pypy3.8 or pypy-3.8 # the latest available version of PyPy that supports Python 3.8 | ||||
| pypy2.7 or pypy-2.7 # the latest available version of PyPy that supports Python 2.7 | ||||
| pypy3.7-v7.3.3 or pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3 | ||||
| pypy3.7-v7.x or pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x | ||||
| pypy3.7-v7.3.3rc1 or pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy | ||||
| pypy3.7-nightly or pypy-3.7-nightly # Python 3.7 and nightly PyPy | ||||
| ``` | ||||
|  | ||||
| # Caching packages dependencies | ||||
|  | ||||
							
								
								
									
										14
									
								
								__tests__/check-python-path.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								__tests__/check-python-path.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,14 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| set -euo pipefail | ||||
|  | ||||
| PYTHON_PATH="$1" | ||||
| PATH_EXECUTABLE=$(python -c 'import sys; print(sys.executable)') | ||||
| PYTHON_PATH_EXECUTABLE=$("${PYTHON_PATH}" -c 'import sys; print(sys.executable)') | ||||
| if [ "${PATH_EXECUTABLE}" != "${PYTHON_PATH_EXECUTABLE}" ]; then | ||||
|     echo "Executable mismatch." | ||||
|     echo "python in PATH is: ${PATH_EXECUTABLE}" | ||||
|     echo "python-path (${PYTHON_PATH}) is: ${PYTHON_PATH_EXECUTABLE}" | ||||
|     exit 1 | ||||
| fi | ||||
| echo "python-path: ${PYTHON_PATH}" | ||||
| @ -37,16 +37,34 @@ describe('parsePyPyVersion', () => { | ||||
|     ['pypy-3.6-v7.x', {pythonVersion: '3.6', pypyVersion: 'v7.x'}], | ||||
|     ['pypy-3.6', {pythonVersion: '3.6', pypyVersion: 'x'}], | ||||
|     ['pypy-3.6-nightly', {pythonVersion: '3.6', pypyVersion: 'nightly'}], | ||||
|     ['pypy-3.6-v7.3.3rc1', {pythonVersion: '3.6', pypyVersion: 'v7.3.3-rc.1'}] | ||||
|     ['pypy-3.6-v7.3.3rc1', {pythonVersion: '3.6', pypyVersion: 'v7.3.3-rc.1'}], | ||||
|     ['pypy3.8-v7.3.7', {pythonVersion: '3.8', pypyVersion: 'v7.3.7'}], | ||||
|     ['pypy3.8-v7.3.x', {pythonVersion: '3.8', pypyVersion: 'v7.3.x'}], | ||||
|     ['pypy3.8-v7.x', {pythonVersion: '3.8', pypyVersion: 'v7.x'}], | ||||
|     ['pypy3.8', {pythonVersion: '3.8', pypyVersion: 'x'}], | ||||
|     ['pypy3.9-nightly', {pythonVersion: '3.9', pypyVersion: 'nightly'}], | ||||
|     ['pypy3.9-v7.3.8rc1', {pythonVersion: '3.9', pypyVersion: 'v7.3.8-rc.1'}] | ||||
|   ])('%s -> %s', (input, expected) => { | ||||
|     expect(finder.parsePyPyVersion(input)).toEqual(expected); | ||||
|   }); | ||||
|  | ||||
|   it('throw on invalid input', () => { | ||||
|     expect(() => finder.parsePyPyVersion('pypy-')).toThrowError( | ||||
|       "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-<python-version>'. See README for examples and documentation." | ||||
|     ); | ||||
|   }); | ||||
|   it.each(['', 'pypy-', 'pypy', 'p', 'notpypy-'])( | ||||
|     'throw on invalid input "%s"', | ||||
|     input => { | ||||
|       expect(() => finder.parsePyPyVersion(input)).toThrowError( | ||||
|         "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy<python-version>' or 'pypy-<python-version>'. See README for examples and documentation." | ||||
|       ); | ||||
|     } | ||||
|   ); | ||||
|  | ||||
|   it.each(['pypy-2', 'pypy-3', 'pypy2', 'pypy3', 'pypy3.x', 'pypy3.8.10'])( | ||||
|     'throw on invalid input "%s"', | ||||
|     input => { | ||||
|       expect(() => finder.parsePyPyVersion(input)).toThrowError( | ||||
|         "Invalid format of Python version for PyPy. Python version should be specified in format 'x.y'. See README for examples and documentation." | ||||
|       ); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| describe('getPyPyVersionFromPath', () => { | ||||
|  | ||||
| @ -4,8 +4,9 @@ description: 'Set up a specific version of Python and add the command-line tools | ||||
| author: 'GitHub' | ||||
| inputs: | ||||
|   python-version: | ||||
|     description: "Version range or exact version of a Python version to use, using SemVer's version range syntax." | ||||
|     default: '3.x' | ||||
|     description: "Version range or exact version of Python to use, using SemVer's version range syntax. Reads from .python-version if unset." | ||||
|   python-version-file: | ||||
|     description: "File containing the Python version to use. Example: .python-version" | ||||
|   cache: | ||||
|     description: 'Used to specify a package manager for caching in the default directory. Supported values: pip, pipenv, poetry.' | ||||
|     required: false | ||||
| @ -21,6 +22,8 @@ outputs: | ||||
|     description: "The installed python version. Useful when given a version range as input." | ||||
|   cache-hit: | ||||
|     description: 'A boolean value to indicate a cache entry was found' | ||||
|   python-path: | ||||
|     description: "The absolute path to the Python executable." | ||||
| runs: | ||||
|   using: 'node16' | ||||
|   main: 'dist/setup/index.js' | ||||
|  | ||||
							
								
								
									
										54454
									
								
								dist/cache-save/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54454
									
								
								dist/cache-save/index.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										66651
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										66651
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										10373
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10373
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "setup-python", | ||||
|   "version": "3.1.1", | ||||
|   "version": "4.0.0", | ||||
|   "private": true, | ||||
|   "description": "Setup python action", | ||||
|   "main": "dist/index.js", | ||||
| @ -35,7 +35,7 @@ | ||||
|     "@types/jest": "^27.0.2", | ||||
|     "@types/node": "^16.11.25", | ||||
|     "@types/semver": "^7.1.0", | ||||
|     "@zeit/ncc": "^0.22.0", | ||||
|     "@vercel/ncc": "^0.33.4", | ||||
|     "husky": "^7.0.2", | ||||
|     "jest": "^27.2.5", | ||||
|     "jest-circus": "^27.2.5", | ||||
|  | ||||
| @ -58,7 +58,7 @@ class PoetryCache extends CacheDistributor { | ||||
|     const config: any = {}; | ||||
|  | ||||
|     for (let line of lines) { | ||||
|       line = line.replace(/#.*$/, ''); | ||||
|       line = line.replace(/#.*$/gm, ''); | ||||
|  | ||||
|       const [key, value] = line.split('=').map(part => part.trim()); | ||||
|  | ||||
|  | ||||
| @ -48,11 +48,18 @@ export async function findPyPyVersion( | ||||
|  | ||||
|   const pipDir = IS_WINDOWS ? 'Scripts' : 'bin'; | ||||
|   const _binDir = path.join(installDir, pipDir); | ||||
|   const binaryExtension = IS_WINDOWS ? '.exe' : ''; | ||||
|   const pythonPath = path.join( | ||||
|     IS_WINDOWS ? installDir : _binDir, | ||||
|     `python${binaryExtension}` | ||||
|   ); | ||||
|   const pythonLocation = pypyInstall.getPyPyBinaryPath(installDir); | ||||
|   core.exportVariable('pythonLocation', pythonLocation); | ||||
|   core.exportVariable('pythonLocation', installDir); | ||||
|   core.exportVariable('PKG_CONFIG_PATH', pythonLocation + '/lib/pkgconfig'); | ||||
|   core.addPath(pythonLocation); | ||||
|   core.addPath(_binDir); | ||||
|   core.setOutput('python-version', 'pypy' + resolvedPyPyVersion.trim()); | ||||
|   core.setOutput('python-path', pythonPath); | ||||
|  | ||||
|   return {resolvedPyPyVersion, resolvedPythonVersion}; | ||||
| } | ||||
| @ -97,9 +104,14 @@ export function findPyPyToolCache( | ||||
| export function parsePyPyVersion(versionSpec: string): IPyPyVersionSpec { | ||||
|   const versions = versionSpec.split('-').filter(item => !!item); | ||||
|  | ||||
|   if (/^(pypy)(.+)/.test(versions[0])) { | ||||
|     let pythonVersion = versions[0].replace('pypy', ''); | ||||
|     versions.splice(0, 1, 'pypy', pythonVersion); | ||||
|   } | ||||
|  | ||||
|   if (versions.length < 2 || versions[0] != 'pypy') { | ||||
|     throw new Error( | ||||
|       "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-<python-version>'. See README for examples and documentation." | ||||
|       "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy<python-version>' or 'pypy-<python-version>'. See README for examples and documentation." | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -70,6 +70,7 @@ 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 | ||||
| @ -82,8 +83,14 @@ export async function useCpythonVersion( | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   const _binDir = binDir(installDir); | ||||
|   const binaryExtension = IS_WINDOWS ? '.exe' : ''; | ||||
|   const pythonPath = path.join( | ||||
|     IS_WINDOWS ? installDir : _binDir, | ||||
|     `python${binaryExtension}` | ||||
|   ); | ||||
|   core.addPath(installDir); | ||||
|   core.addPath(binDir(installDir)); | ||||
|   core.addPath(_binDir); | ||||
|  | ||||
|   if (IS_WINDOWS) { | ||||
|     // Add --user directory | ||||
| @ -105,18 +112,15 @@ export async function useCpythonVersion( | ||||
|  | ||||
|   const installed = versionFromPath(installDir); | ||||
|   core.setOutput('python-version', installed); | ||||
|   core.setOutput('python-path', pythonPath); | ||||
|  | ||||
|   return {impl: 'CPython', version: installed}; | ||||
| } | ||||
|  | ||||
| /** Convert versions like `3.8-dev` to a version like `>= 3.8.0-a0`. */ | ||||
| /** Convert versions like `3.8-dev` to a version like `~3.8.0-0`. */ | ||||
| function desugarDevVersion(versionSpec: string) { | ||||
|   if (versionSpec.endsWith('-dev')) { | ||||
|     const versionRoot = versionSpec.slice(0, -'-dev'.length); | ||||
|     return `>= ${versionRoot}.0-a0`; | ||||
|   } else { | ||||
|     return versionSpec; | ||||
|   } | ||||
|   const devVersion = /^(\d+)\.(\d+)-dev$/; | ||||
|   return versionSpec.replace(devVersion, '~$1.$2.0-0'); | ||||
| } | ||||
|  | ||||
| /** Extracts python version from install path from hosted tool cache as described in README.md */ | ||||
|  | ||||
| @ -98,7 +98,9 @@ async function createPyPySymlink( | ||||
| ) { | ||||
|   const version = semver.coerce(pythonVersion)!; | ||||
|   const pythonBinaryPostfix = semver.major(version); | ||||
|   const pythonMinor = semver.minor(version); | ||||
|   const pypyBinaryPostfix = pythonBinaryPostfix === 2 ? '' : '3'; | ||||
|   const pypyMajorMinorBinaryPostfix = `${pythonBinaryPostfix}.${pythonMinor}`; | ||||
|   let binaryExtension = IS_WINDOWS ? '.exe' : ''; | ||||
|  | ||||
|   core.info('Creating symlinks...'); | ||||
| @ -115,6 +117,13 @@ async function createPyPySymlink( | ||||
|     `python${binaryExtension}`, | ||||
|     true | ||||
|   ); | ||||
|  | ||||
|   createSymlinkInFolder( | ||||
|     pypyBinaryPath, | ||||
|     `pypy${pypyBinaryPostfix}${binaryExtension}`, | ||||
|     `pypy${pypyMajorMinorBinaryPostfix}${binaryExtension}`, | ||||
|     true | ||||
|   ); | ||||
| } | ||||
|  | ||||
| async function installPip(pythonLocation: string) { | ||||
|  | ||||
| @ -3,11 +3,12 @@ import * as finder from './find-python'; | ||||
| import * as finderPyPy from './find-pypy'; | ||||
| import * as path from 'path'; | ||||
| import * as os from 'os'; | ||||
| import fs from 'fs'; | ||||
| import {getCacheDistributor} from './cache-distributions/cache-factory'; | ||||
| import {isCacheFeatureAvailable} from './utils'; | ||||
|  | ||||
| function isPyPyVersion(versionSpec: string) { | ||||
|   return versionSpec.startsWith('pypy-'); | ||||
|   return versionSpec.startsWith('pypy'); | ||||
| } | ||||
|  | ||||
| async function cacheDependencies(cache: string, pythonVersion: string) { | ||||
| @ -21,9 +22,48 @@ async function cacheDependencies(cache: string, pythonVersion: string) { | ||||
|   await cacheDistributor.restoreCache(); | ||||
| } | ||||
|  | ||||
| function resolveVersionInput(): string { | ||||
|   let version = core.getInput('python-version'); | ||||
|   const versionFile = core.getInput('python-version-file'); | ||||
|  | ||||
|   if (version && versionFile) { | ||||
|     core.warning( | ||||
|       'Both python-version and python-version-file inputs are specified, only python-version will be used' | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   if (version) { | ||||
|     return version; | ||||
|   } | ||||
|  | ||||
|   const versionFilePath = path.join( | ||||
|     process.env.GITHUB_WORKSPACE!, | ||||
|     versionFile || '.python-version' | ||||
|   ); | ||||
|   if (!fs.existsSync(versionFilePath)) { | ||||
|     throw new Error( | ||||
|       `The specified python version file at: ${versionFilePath} does not exist` | ||||
|     ); | ||||
|   } | ||||
|   version = fs.readFileSync(versionFilePath, 'utf8'); | ||||
|   core.info(`Resolved ${versionFile} as ${version}`); | ||||
|  | ||||
|   return version; | ||||
| } | ||||
|  | ||||
| async function run() { | ||||
|   if (process.env.AGENT_TOOLSDIRECTORY?.trim()) { | ||||
|     core.debug( | ||||
|       `Python is expected to be installed into AGENT_TOOLSDIRECTORY=${process.env['AGENT_TOOLSDIRECTORY']}` | ||||
|     ); | ||||
|     process.env['RUNNER_TOOL_CACHE'] = process.env['AGENT_TOOLSDIRECTORY']; | ||||
|   } else { | ||||
|     core.debug( | ||||
|       `Python is expected to be installed into RUNNER_TOOL_CACHE==${process.env['RUNNER_TOOL_CACHE']}` | ||||
|     ); | ||||
|   } | ||||
|   try { | ||||
|     const version = core.getInput('python-version'); | ||||
|     const version = resolveVersionInput(); | ||||
|     if (version) { | ||||
|       let pythonVersion: string; | ||||
|       const arch: string = core.getInput('architecture') || os.arch(); | ||||
| @ -31,18 +71,22 @@ async function run() { | ||||
|         const installed = await finderPyPy.findPyPyVersion(version, arch); | ||||
|         pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`; | ||||
|         core.info( | ||||
|           `Successfully setup PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})` | ||||
|           `Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})` | ||||
|         ); | ||||
|       } else { | ||||
|         const installed = await finder.useCpythonVersion(version, arch); | ||||
|         pythonVersion = installed.version; | ||||
|         core.info(`Successfully setup ${installed.impl} (${pythonVersion})`); | ||||
|         core.info(`Successfully set up ${installed.impl} (${pythonVersion})`); | ||||
|       } | ||||
|  | ||||
|       const cache = core.getInput('cache'); | ||||
|       if (cache && isCacheFeatureAvailable()) { | ||||
|         await cacheDependencies(cache, pythonVersion); | ||||
|       } | ||||
|     } else { | ||||
|       core.warning( | ||||
|         'The `python-version` input is not set.  The version of Python currently in `PATH` will be used.' | ||||
|       ); | ||||
|     } | ||||
|     const matchersPath = path.join(__dirname, '../..', '.github'); | ||||
|     core.info(`##[add-matcher]${path.join(matchersPath, 'python.json')}`); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user