Merge branch 'main' into pr/650

This commit is contained in:
Dmitry Shibanov 2023-07-13 14:52:38 +02:00
commit 70b97ae206
16 changed files with 2720 additions and 110 deletions

View File

@ -43,22 +43,30 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
id: cache-pipenv
uses: ./ uses: ./
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
cache: 'pipenv' cache: 'pipenv'
- name: Install pipenv - name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies - name: Prepare environment
shell: pwsh shell: pwsh
run: | run: |
mv ./__tests__/data/Pipfile.lock . mv ./__tests__/data/Pipfile.lock .
mv ./__tests__/data/Pipfile . mv ./__tests__/data/Pipfile .
mv ./__tests__/test-pipenv.py .
- name: Install dependencies
shell: pwsh
if: steps.cache-pipenv.outputs.cache-hit != 'true'
run: |
if ("${{ matrix.python-version }}" -Match "pypy") { if ("${{ matrix.python-version }}" -Match "pypy") {
pipenv install --keep-outdated --python pypy pipenv install --python pypy # --keep-outdated
} else { } else {
pipenv install --keep-outdated --python ${{ matrix.python-version }} pipenv install --python ${{ matrix.python-version }} # --keep-outdated
} }
- name: Run Python Script
run: pipenv run python test-pipenv.py
python-poetry-dependencies-caching: python-poetry-dependencies-caching:
name: Test poetry (Python ${{ matrix.python-version}}, ${{ matrix.os }}) name: Test poetry (Python ${{ matrix.python-version}}, ${{ matrix.os }})
@ -112,6 +120,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Setup Python - name: Setup Python
id: cache-pipenv
uses: ./ uses: ./
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
@ -119,13 +128,20 @@ jobs:
cache-dependency-path: '**/pipenv-requirements.txt' cache-dependency-path: '**/pipenv-requirements.txt'
- name: Install pipenv - name: Install pipenv
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
- name: Install dependencies - name: Prepare environment
shell: pwsh shell: pwsh
run: | run: |
mv ./__tests__/data/Pipfile.lock . mv ./__tests__/data/Pipfile.lock .
mv ./__tests__/data/Pipfile . mv ./__tests__/data/Pipfile .
mv ./__tests__/test-pipenv.py .
- name: Install dependencies
shell: pwsh
if: steps.cache-pipenv.outputs.cache-hit != 'true'
run: |
if ("${{ matrix.python-version }}" -Match "pypy") { if ("${{ matrix.python-version }}" -Match "pypy") {
pipenv install --keep-outdated --python pypy pipenv install --python pypy # --keep-outdated
} else { } else {
pipenv install --keep-outdated --python ${{ matrix.python-version }} pipenv install --python ${{ matrix.python-version }} # --keep-outdated
} }
- name: Run Python Script
run: pipenv run python test-pipenv.py

View File

@ -21,13 +21,6 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Run with setup-python 2.7
uses: ./
with:
python-version: 2.7
- name: Verify 2.7
run: python __tests__/verify-python.py 2.7
- name: Run with setup-python 3.5 - name: Run with setup-python 3.5
uses: ./ uses: ./
with: with:
@ -86,3 +79,24 @@ jobs:
run: python __tests__/verify-python.py 3.10 run: python __tests__/verify-python.py 3.10
- name: Run python-path sample 3.10 - name: Run python-path sample 3.10
run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version run: pipx run --python '${{ steps.cp310.outputs.python-path }}' nox --version
- name: Run with setup-python ==3.8
uses: ./
with:
python-version: '==3.8'
- name: Verify ==3.8
run: python __tests__/verify-python.py 3.8
- name: Run with setup-python <3.11
uses: ./
with:
python-version: '<3.11'
- name: Verify <3.11
run: python __tests__/verify-python.py 3.10
- name: Run with setup-python >3.8
uses: ./
with:
python-version: '>3.8'
- name: Verify >3.8
run: python __tests__/verify-python.py 3.11

View File

@ -86,7 +86,152 @@ jobs:
id: setup-python id: setup-python
uses: ./ uses: ./
with: with:
python-version-file: '.python-version' 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)
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-without-parameter:
name: Setup ${{ matrix.python }} ${{ matrix.os }} version file without parameter
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.15, 3.9.13]
exclude:
- os: ubuntu-22.04
python: 3.5.4
- os: ubuntu-22.04
python: 3.6.7
- os: ubuntu-22.04
python: 3.7.5
- os: windows-latest
python: 3.8.15
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: ./
- 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-standard-pyproject-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} standard pyproject file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.15, 3.9.13]
exclude:
- os: ubuntu-22.04
python: 3.5.4
- os: ubuntu-22.04
python: 3.6.7
- os: ubuntu-22.04
python: 3.7.5
- os: windows-latest
python: 3.8.15
steps:
- name: Checkout
uses: actions/checkout@v3
- name: build-version-file ${{ matrix.python }}
run: |
echo '[project]
requires-python = "${{ matrix.python }}"
' > pyproject.toml
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: pyproject.toml
- 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-poetry-pyproject-file:
name: Setup ${{ matrix.python }} ${{ matrix.os }} poetry pyproject file
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
python: [3.5.4, 3.6.7, 3.7.5, 3.8.15, 3.9.13]
exclude:
- os: ubuntu-22.04
python: 3.5.4
- os: ubuntu-22.04
python: 3.6.7
- os: ubuntu-22.04
python: 3.7.5
- os: windows-latest
python: 3.8.15
steps:
- name: Checkout
uses: actions/checkout@v3
- name: build-version-file ${{ matrix.python }}
run: |
echo '[tool.poetry.dependencies]
python = "${{ matrix.python }}"
' > pyproject.toml
- name: setup-python ${{ matrix.python }}
id: setup-python
uses: ./
with:
python-version-file: pyproject.toml
- name: Check python-path - name: Check python-path
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}' run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'

BIN
.licenses/npm/@iarna/toml.dep.yml generated Normal file

Binary file not shown.

View File

@ -8,7 +8,7 @@ import {State} from '../src/cache-distributions/cache-distributor';
describe('restore-cache', () => { describe('restore-cache', () => {
const pipFileLockHash = const pipFileLockHash =
'a3bdcc71289e4979ca9e051810d81999cc99823109faf6912e17ff14c8e621a6'; 'f8428d7cf00ea53a5c3702f0a9cb3cc467f76cd86a34723009350c4e4b32751a';
const requirementsHash = const requirementsHash =
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121'; 'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
const requirementsLinuxHash = const requirementsLinuxHash =

View File

@ -4,8 +4,8 @@ verify_ssl = true
name = "pypi" name = "pypi"
[packages] [packages]
flake8 = "==4.0.1" flake8 = "==6.0.0"
numpy = "==1.23.0" numpy = "==1.25.1"
[dev-packages] [dev-packages]

View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "e9c37110984955621040e2dc8548c026eb8466c23db1b8e69430289b10be8938" "sha256": "dcea65dabfe8442466b5e9280ecab72cfa7bf555791ee0ad55b6e7255dca1f43"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -18,62 +18,66 @@
"default": { "default": {
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d", "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7",
"sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d" "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"
], ],
"index": "pypi", "index": "pypi",
"version": "==4.0.1" "version": "==6.0.0"
}, },
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
], ],
"version": "==0.6.1" "markers": "python_version >= '3.6'",
"version": "==0.7.0"
}, },
"numpy": { "numpy": {
"hashes": [ "hashes": [
"sha256:092f5e6025813e64ad6d1b52b519165d08c730d099c114a9247c9bb635a2a450", "sha256:012097b5b0d00a11070e8f2e261128c44157a8689f7dedcf35576e525893f4fe",
"sha256:196cd074c3f97c4121601790955f915187736f9cf458d3ee1f1b46aff2b1ade0", "sha256:0d3fe3dd0506a28493d82dc3cf254be8cd0d26f4008a417385cbf1ae95b54004",
"sha256:1c29b44905af288b3919803aceb6ec7fec77406d8b08aaa2e8b9e63d0fe2f160", "sha256:0def91f8af6ec4bb94c370e38c575855bf1d0be8a8fbfba42ef9c073faf2cf19",
"sha256:2b2da66582f3a69c8ce25ed7921dcd8010d05e59ac8d89d126a299be60421171", "sha256:1a180429394f81c7933634ae49b37b472d343cccb5bb0c4a575ac8bbc433722f",
"sha256:5043bcd71fcc458dfb8a0fc5509bbc979da0131b9d08e3d5f50fb0bbb36f169a", "sha256:1d5d3c68e443c90b38fdf8ef40e60e2538a27548b39b12b73132456847f4b631",
"sha256:58bfd40eb478f54ff7a5710dd61c8097e169bc36cc68333d00a9bcd8def53b38", "sha256:20e1266411120a4f16fad8efa8e0454d21d00b8c7cee5b5ccad7565d95eb42dd",
"sha256:79a506cacf2be3a74ead5467aee97b81fca00c9c4c8b3ba16dbab488cd99ba10", "sha256:247d3ffdd7775bdf191f848be8d49100495114c82c2bd134e8d5d075fb386a1c",
"sha256:94b170b4fa0168cd6be4becf37cb5b127bd12a795123984385b8cd4aca9857e5", "sha256:35a9527c977b924042170a0887de727cd84ff179e478481404c5dc66b4170009",
"sha256:97a76604d9b0e79f59baeca16593c711fddb44936e40310f78bfef79ee9a835f", "sha256:38eb6548bb91c421261b4805dc44def9ca1a6eef6444ce35ad1669c0f1a3fc5d",
"sha256:98e8e0d8d69ff4d3fa63e6c61e8cfe2d03c29b16b58dbef1f9baa175bbed7860", "sha256:3d7abcdd85aea3e6cdddb59af2350c7ab1ed764397f8eec97a038ad244d2d105",
"sha256:ac86f407873b952679f5f9e6c0612687e51547af0e14ddea1eedfcb22466babd", "sha256:41a56b70e8139884eccb2f733c2f7378af06c82304959e174f8e7370af112e09",
"sha256:ae8adff4172692ce56233db04b7ce5792186f179c415c37d539c25de7298d25d", "sha256:4a90725800caeaa160732d6b31f3f843ebd45d6b5f3eec9e8cc287e30f2805bf",
"sha256:bd3fa4fe2e38533d5336e1272fc4e765cabbbde144309ccee8675509d5cd7b05", "sha256:6b82655dd8efeea69dbf85d00fca40013d7f503212bc5259056244961268b66e",
"sha256:d0d2094e8f4d760500394d77b383a1b06d3663e8892cdf5df3c592f55f3bff66", "sha256:6c6c9261d21e617c6dc5eacba35cb68ec36bb72adcff0dee63f8fbc899362588",
"sha256:d54b3b828d618a19779a84c3ad952e96e2c2311b16384e973e671aa5be1f6187", "sha256:77d339465dff3eb33c701430bcb9c325b60354698340229e1dff97745e6b3efa",
"sha256:d6ca8dabe696c2785d0c8c9b0d8a9b6e5fdbe4f922bde70d57fa1a2848134f95", "sha256:791f409064d0a69dd20579345d852c59822c6aa087f23b07b1b4e28ff5880fcb",
"sha256:d8cc87bed09de55477dba9da370c1679bd534df9baa171dd01accbb09687dac3", "sha256:9a3a9f3a61480cc086117b426a8bd86869c213fc4072e606f01c4e4b66eb92bf",
"sha256:f0f18804df7370571fb65db9b98bf1378172bd4e962482b857e612d1fec0f53e", "sha256:c1516db588987450b85595586605742879e50dcce923e8973f79529651545b57",
"sha256:f1d88ef79e0a7fa631bb2c3dda1ea46b32b1fe614e10fedd611d3d5398447f2f", "sha256:c40571fe966393b212689aa17e32ed905924120737194b5d5c1b20b9ed0fb171",
"sha256:f9c3fc2adf67762c9fe1849c859942d23f8d3e0bee7b5ed3d4a9c3eeb50a2f07", "sha256:d412c1697c3853c6fc3cb9751b4915859c7afe6a277c2bf00acf287d56c4e625",
"sha256:fc431493df245f3c627c0c05c2bd134535e7929dbe2e602b80e42bf52ff760bc", "sha256:d5154b1a25ec796b1aee12ac1b22f414f94752c5f94832f14d8d6c9ac40bcca6",
"sha256:fe8b9683eb26d2c4d5db32cd29b38fdcf8381324ab48313b5b69088e0e355379" "sha256:d736b75c3f2cb96843a5c7f8d8ccc414768d34b0a75f466c05f3a739b406f10b",
"sha256:e8f6049c4878cb16960fbbfb22105e49d13d752d4d8371b55110941fb3b17800",
"sha256:f76aebc3358ade9eacf9bc2bb8ae589863a4f911611694103af05346637df1b7",
"sha256:fd67b306320dcadea700a8f79b9e671e607f8696e98ec255915c0c6d6b818503"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.23.0" "version": "==1.25.1"
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20", "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053",
"sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f" "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "markers": "python_version >= '3.6'",
"version": "==2.8.0" "version": "==2.10.0"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
"sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c", "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf",
"sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e" "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "markers": "python_version >= '3.6'",
"version": "==2.4.0" "version": "==3.0.1"
} }
}, },
"develop": {} "develop": {}

View File

@ -1,2 +1,2 @@
numpy==1.22.3 numpy==1.22.3
pandas==1.4.2 flake8==6.0.0

7
__tests__/test-pipenv.py Normal file
View File

@ -0,0 +1,7 @@
import numpy as np
a = np.array([2, 3, 4])
print(type(a))
b = np.array([1.2, 3.5, 5.1])
print(type(b))

View File

@ -1,9 +1,17 @@
import * as cache from '@actions/cache'; import * as cache from '@actions/cache';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as io from '@actions/io';
import fs from 'fs';
import path from 'path';
import { import {
validateVersion, validateVersion,
validatePythonVersionFormatForPyPy, validatePythonVersionFormatForPyPy,
isCacheFeatureAvailable isCacheFeatureAvailable,
getVersionInputFromFile,
getVersionInputFromPlainFile,
getVersionInputFromTomlFile
} from '../src/utils'; } from '../src/utils';
jest.mock('@actions/cache'); jest.mock('@actions/cache');
@ -73,3 +81,58 @@ describe('isCacheFeatureAvailable', () => {
expect(isCacheFeatureAvailable()).toBe(true); expect(isCacheFeatureAvailable()).toBe(true);
}); });
}); });
const tempDir = path.join(
__dirname,
'runner',
path.join(Math.random().toString(36).substring(7)),
'temp'
);
describe('Version from file test', () => {
it.each([getVersionInputFromPlainFile, getVersionInputFromFile])(
'Version from plain file test',
async _fn => {
await io.mkdirP(tempDir);
const pythonVersionFileName = 'python-version.file';
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
const pythonVersionFileContent = '3.7';
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersionFileContent]);
}
);
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
'Version from standard pyproject.toml test',
async _fn => {
await io.mkdirP(tempDir);
const pythonVersionFileName = 'pyproject.toml';
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
const pythonVersion = '>=3.7';
const pythonVersionFileContent = `[project]\nrequires-python = "${pythonVersion}"`;
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
}
);
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
'Version from poetry pyproject.toml test',
async _fn => {
await io.mkdirP(tempDir);
const pythonVersionFileName = 'pyproject.toml';
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
const pythonVersion = '>=3.7';
const pythonVersionFileContent = `[tool.poetry.dependencies]\npython = "${pythonVersion}"`;
fs.writeFileSync(pythonVersionFilePath, pythonVersionFileContent);
expect(_fn(pythonVersionFilePath)).toEqual([pythonVersion]);
}
);
it.each([getVersionInputFromTomlFile, getVersionInputFromFile])(
'Version undefined',
async _fn => {
await io.mkdirP(tempDir);
const pythonVersionFileName = 'pyproject.toml';
const pythonVersionFilePath = path.join(tempDir, pythonVersionFileName);
fs.writeFileSync(pythonVersionFilePath, ``);
expect(_fn(pythonVersionFilePath)).toEqual([]);
}
);
});

2294
dist/setup/index.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -78,6 +78,17 @@ steps:
You can also use several types of ranges that are specified in [semver](https://github.com/npm/node-semver#ranges), for instance: You can also use several types of ranges that are specified in [semver](https://github.com/npm/node-semver#ranges), for instance:
- **[ranges](https://github.com/npm/node-semver#ranges)** to download and set up the latest available version of Python satisfying a range:
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '>=3.9 <3.10'
- run: python my_script.py
```
- **[hyphen ranges](https://github.com/npm/node-semver#hyphen-ranges-xyz---abc)** to download and set up the latest available version of Python (includes both pre-release and stable versions): - **[hyphen ranges](https://github.com/npm/node-semver#hyphen-ranges-xyz---abc)** to download and set up the latest available version of Python (includes both pre-release and stable versions):
```yaml ```yaml
@ -251,6 +262,16 @@ steps:
python-version-file: '.python-version' # Read python version from a file .python-version python-version-file: '.python-version' # Read python version from a file .python-version
- run: python my_script.py - run: python my_script.py
``` ```
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version-file: 'pyproject.toml' # Read python version from a file pyproject.toml
- run: python my_script.py
```
## Check latest version ## Check latest version
The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific `Python or PyPy` version is always used. The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific `Python or PyPy` version is always used.

11
package-lock.json generated
View File

@ -16,6 +16,7 @@
"@actions/http-client": "^1.0.11", "@actions/http-client": "^1.0.11",
"@actions/io": "^1.0.2", "@actions/io": "^1.0.2",
"@actions/tool-cache": "^1.5.5", "@actions/tool-cache": "^1.5.5",
"@iarna/toml": "^2.2.5",
"semver": "^7.1.3" "semver": "^7.1.3"
}, },
"devDependencies": { "devDependencies": {
@ -2048,6 +2049,11 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true "dev": true
}, },
"node_modules/@iarna/toml": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
"integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="
},
"node_modules/@istanbuljs/load-nyc-config": { "node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@ -8519,6 +8525,11 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true "dev": true
}, },
"@iarna/toml": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
"integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="
},
"@istanbuljs/load-nyc-config": { "@istanbuljs/load-nyc-config": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",

View File

@ -32,6 +32,7 @@
"@actions/http-client": "^1.0.11", "@actions/http-client": "^1.0.11",
"@actions/io": "^1.0.2", "@actions/io": "^1.0.2",
"@actions/tool-cache": "^1.5.5", "@actions/tool-cache": "^1.5.5",
"@iarna/toml": "^2.2.5",
"semver": "^7.1.3" "semver": "^7.1.3"
}, },
"devDependencies": { "devDependencies": {

View File

@ -5,7 +5,13 @@ import * as path from 'path';
import * as os from 'os'; import * as os from 'os';
import fs from 'fs'; import fs from 'fs';
import {getCacheDistributor} from './cache-distributions/cache-factory'; import {getCacheDistributor} from './cache-distributions/cache-factory';
import {isCacheFeatureAvailable, logWarning, IS_MAC} from './utils'; import {
isCacheFeatureAvailable,
logWarning,
IS_MAC,
getVersionInputFromFile,
getVersionInputFromPlainFile
} from './utils';
function isPyPyVersion(versionSpec: string) { function isPyPyVersion(versionSpec: string) {
return versionSpec.startsWith('pypy'); return versionSpec.startsWith('pypy');
@ -22,43 +28,46 @@ async function cacheDependencies(cache: string, pythonVersion: string) {
await cacheDistributor.restoreCache(); await cacheDistributor.restoreCache();
} }
function resolveVersionInput() { function resolveVersionInputFromDefaultFile(): string[] {
const versions = core.getMultilineInput('python-version'); const couples: [string, (versionFile: string) => string[]][] = [
let versionFile = core.getInput('python-version-file'); ['.python-version', getVersionInputFromPlainFile]
];
if (versions.length && versionFile) { for (const [versionFile, _fn] of couples) {
core.warning( logWarning(
'Both python-version and python-version-file inputs are specified, only python-version will be used.' `Neither 'python-version' nor 'python-version-file' inputs were supplied. Attempting to find '${versionFile}' file.`
); );
if (fs.existsSync(versionFile)) {
return _fn(versionFile);
} else {
logWarning(`${versionFile} doesn't exist.`);
}
} }
return [];
}
function resolveVersionInput() {
let versions = core.getMultilineInput('python-version');
const versionFile = core.getInput('python-version-file');
if (versions.length) { if (versions.length) {
return versions; if (versionFile) {
} core.warning(
'Both python-version and python-version-file inputs are specified, only python-version will be used.'
if (versionFile) {
if (!fs.existsSync(versionFile)) {
throw new Error(
`The specified python version file at: ${versionFile} doesn't exist.`
); );
} }
const version = fs.readFileSync(versionFile, 'utf8'); } else {
core.info(`Resolved ${versionFile} as ${version}`); if (versionFile) {
return [version]; if (!fs.existsSync(versionFile)) {
throw new Error(
`The specified python version file at: ${versionFile} doesn't exist.`
);
}
versions = getVersionInputFromFile(versionFile);
} else {
versions = resolveVersionInputFromDefaultFile();
}
} }
logWarning(
"Neither 'python-version' nor 'python-version-file' inputs were supplied. Attempting to find '.python-version' file."
);
versionFile = '.python-version';
if (fs.existsSync(versionFile)) {
const version = fs.readFileSync(versionFile, 'utf8');
core.info(`Resolved ${versionFile} as ${version}`);
return [version];
}
logWarning(`${versionFile} doesn't exist.`);
return versions; return versions;
} }

View File

@ -4,6 +4,7 @@ import * as core from '@actions/core';
import fs from 'fs'; import fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import * as toml from '@iarna/toml';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
export const IS_WINDOWS = process.platform === 'win32'; export const IS_WINDOWS = process.platform === 'win32';
@ -181,3 +182,73 @@ export async function getOSInfo() {
return osInfo; return osInfo;
} }
} }
/**
* Extract a value from an object by following the keys path provided.
* If the value is present, it is returned. Otherwise undefined is returned.
*/
function extractValue(obj: any, keys: string[]): string | undefined {
if (keys.length > 0) {
const value = obj[keys[0]];
if (keys.length > 1 && value !== undefined) {
return extractValue(value, keys.slice(1));
} else {
return value;
}
} else {
return;
}
}
/**
* Python version extracted from the TOML file.
* If the `project` key is present at the root level, the version is assumed to
* be specified according to PEP 621 in `project.requires-python`.
* Otherwise, if the `tool` key is present at the root level, the version is
* assumed to be specified using poetry under `tool.poetry.dependencies.python`.
* If none is present, returns an empty list.
*/
export function getVersionInputFromTomlFile(versionFile: string): string[] {
core.debug(`Trying to resolve version form ${versionFile}`);
const pyprojectFile = fs.readFileSync(versionFile, 'utf8');
const pyprojectConfig = toml.parse(pyprojectFile);
let keys = [];
if ('project' in pyprojectConfig) {
// standard project metadata (PEP 621)
keys = ['project', 'requires-python'];
} else {
// python poetry
keys = ['tool', 'poetry', 'dependencies', 'python'];
}
const versions = [];
const version = extractValue(pyprojectConfig, keys);
if (version !== undefined) {
versions.push(version);
}
core.info(`Extracted ${versions} from ${versionFile}`);
return Array.from(versions, version => version.split(',').join(' '));
}
/**
* Python version extracted from a plain text file.
*/
export function getVersionInputFromPlainFile(versionFile: string): string[] {
core.debug(`Trying to resolve version form ${versionFile}`);
const version = fs.readFileSync(versionFile, 'utf8');
core.info(`Resolved ${versionFile} as ${version}`);
return [version];
}
/**
* Python version extracted from a plain or TOML file.
*/
export function getVersionInputFromFile(versionFile: string): string[] {
if (versionFile.endsWith('.toml')) {
return getVersionInputFromTomlFile(versionFile);
} else {
return getVersionInputFromPlainFile(versionFile);
}
}