mirror of
https://github.com/actions/setup-python.git
synced 2025-06-23 20:27:58 +02:00
Compare commits
41 Commits
Author | SHA1 | Date | |
---|---|---|---|
65d7f2d534 | |||
f97b83114c | |||
61a6322f88 | |||
ea5b57fccc | |||
014d32a830 | |||
c16c4b8d18 | |||
0d5da6a89a | |||
3f824b7ca6 | |||
bd6b4b6205 | |||
0cbcb9a3d7 | |||
669664dac1 | |||
9cbf792a3c | |||
e732e40717 | |||
a0d867bfa9 | |||
d99bed8b21 | |||
f71253fee3 | |||
b51c97f6e3 | |||
db9987b4c1 | |||
6db7460265 | |||
57ded4d7d5 | |||
df6abcc733 | |||
7a4f344e33 | |||
d1244c8404 | |||
3091b37310 | |||
dfa76f8d0d | |||
03eb867e3d | |||
b41aaf9f0c | |||
0ffa49cfca | |||
ec365b4eba | |||
7b9ef6fc5a | |||
869e769ec8 | |||
3faddefb4c | |||
181184007f | |||
2652534ead | |||
a6eba85bba | |||
34b4b622e3 | |||
f60fe39c45 | |||
d27e3f3d7c | |||
dec86ecf4e | |||
4dcd67678f | |||
8b89ef08a0 |
6
.eslintignore
Normal file
6
.eslintignore
Normal file
@ -0,0 +1,6 @@
|
||||
# Ignore list
|
||||
/*
|
||||
|
||||
# Do not ignore these folders:
|
||||
!__tests__/
|
||||
!src/
|
51
.eslintrc.js
Normal file
51
.eslintrc.js
Normal file
@ -0,0 +1,51 @@
|
||||
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:eslint-plugin-jest/recommended',
|
||||
'eslint-config-prettier'
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint', 'eslint-plugin-node', 'eslint-plugin-jest'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-require-imports': 'error',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': [
|
||||
'error',
|
||||
{
|
||||
'ts-ignore': 'allow-with-description'
|
||||
}
|
||||
],
|
||||
'no-console': 'error',
|
||||
'yoda': 'error',
|
||||
'prefer-const': [
|
||||
'error',
|
||||
{
|
||||
destructuring: 'all'
|
||||
}
|
||||
],
|
||||
'no-control-regex': 'off',
|
||||
'no-constant-condition': ['error', {checkLoops: false}],
|
||||
'node/no-extraneous-import': 'error'
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*{test,spec}.ts'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'jest/no-standalone-expect': 'off',
|
||||
'jest/no-conditional-expect': 'off',
|
||||
'no-console': 'off',
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
env: {
|
||||
node: true,
|
||||
es6: true,
|
||||
'jest/globals': true
|
||||
}
|
||||
};
|
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@ -1 +1 @@
|
||||
* @actions/actions-service
|
||||
* @actions/setup-actions-team
|
||||
|
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1 +1 @@
|
||||
blank_issues_enabled: false
|
||||
blank_issues_enabled: false
|
||||
|
2
.github/workflows/basic-validation.yml
vendored
2
.github/workflows/basic-validation.yml
vendored
@ -12,4 +12,4 @@ on:
|
||||
jobs:
|
||||
call-basic-validation:
|
||||
name: Basic validation
|
||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
||||
|
2
.github/workflows/check-dist.yml
vendored
2
.github/workflows/check-dist.yml
vendored
@ -14,4 +14,4 @@ on:
|
||||
jobs:
|
||||
call-check-dist:
|
||||
name: Check dist/
|
||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
||||
|
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@ -2,12 +2,12 @@ name: CodeQL analysis
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 'main' ]
|
||||
branches: ['main']
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 3 * * 0'
|
||||
|
||||
jobs:
|
||||
call-codeQL-analysis:
|
||||
name: CodeQL analysis
|
||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
||||
name: CodeQL analysis
|
||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
||||
|
30
.github/workflows/e2e-cache.yml
vendored
30
.github/workflows/e2e-cache.yml
vendored
@ -43,22 +43,30 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python
|
||||
id: cache-pipenv
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pipenv'
|
||||
- name: Install pipenv
|
||||
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
|
||||
- name: Install dependencies
|
||||
- name: Prepare environment
|
||||
shell: pwsh
|
||||
run: |
|
||||
mv ./__tests__/data/Pipfile.lock .
|
||||
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") {
|
||||
pipenv install --keep-outdated --python pypy
|
||||
pipenv install --python pypy # --keep-outdated
|
||||
} 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:
|
||||
name: Test poetry (Python ${{ matrix.python-version}}, ${{ matrix.os }})
|
||||
@ -112,6 +120,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python
|
||||
id: cache-pipenv
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
@ -119,13 +128,20 @@ jobs:
|
||||
cache-dependency-path: '**/pipenv-requirements.txt'
|
||||
- name: Install pipenv
|
||||
run: curl https://raw.githubusercontent.com/pypa/pipenv/master/get-pipenv.py | python
|
||||
- name: Install dependencies
|
||||
- name: Prepare environment
|
||||
shell: pwsh
|
||||
run: |
|
||||
mv ./__tests__/data/Pipfile.lock .
|
||||
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") {
|
||||
pipenv install --keep-outdated --python pypy
|
||||
pipenv install --python pypy # --keep-outdated
|
||||
} 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
|
||||
|
134
.github/workflows/e2e-tests.yml
vendored
134
.github/workflows/e2e-tests.yml
vendored
@ -9,7 +9,7 @@ on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
|
||||
jobs:
|
||||
test-setup-python:
|
||||
name: Test setup-python
|
||||
@ -18,71 +18,85 @@ jobs:
|
||||
matrix:
|
||||
operating-system: [ubuntu-20.04, windows-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout
|
||||
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
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.5
|
||||
- name: Verify 3.5
|
||||
run: python __tests__/verify-python.py 3.5
|
||||
|
||||
- name: Run with setup-python 3.5
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.5
|
||||
- name: Verify 3.5
|
||||
run: python __tests__/verify-python.py 3.5
|
||||
- name: Run with setup-python 3.6
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.6
|
||||
- name: Verify 3.6
|
||||
run: python __tests__/verify-python.py 3.6
|
||||
|
||||
- name: Run with setup-python 3.6
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.6
|
||||
- name: Verify 3.6
|
||||
run: python __tests__/verify-python.py 3.6
|
||||
- name: Run with setup-python 3.7
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.7
|
||||
- name: Verify 3.7
|
||||
run: python __tests__/verify-python.py 3.7
|
||||
|
||||
- name: Run with setup-python 3.7
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.7
|
||||
- name: Verify 3.7
|
||||
run: python __tests__/verify-python.py 3.7
|
||||
- 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.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.7.5
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.7.5
|
||||
- name: Verify 3.7.5
|
||||
run: python __tests__/verify-python.py 3.7.5
|
||||
|
||||
- name: Run with setup-python 3.7.5
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.7.5
|
||||
- name: Verify 3.7.5
|
||||
run: python __tests__/verify-python.py 3.7.5
|
||||
- name: Run with setup-python 3.6.7
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.6.7
|
||||
- name: Verify 3.6.7
|
||||
run: python __tests__/verify-python.py 3.6.7
|
||||
|
||||
- name: Run with setup-python 3.6.7
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 3.6.7
|
||||
- name: Verify 3.6.7
|
||||
run: python __tests__/verify-python.py 3.6.7
|
||||
- name: Run with setup-python 3.8.1
|
||||
uses: ./
|
||||
with:
|
||||
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.8.1
|
||||
uses: ./
|
||||
with:
|
||||
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
|
||||
|
||||
- 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
|
||||
- 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
|
||||
|
2
.github/workflows/licensed.yml
vendored
2
.github/workflows/licensed.yml
vendored
@ -11,4 +11,4 @@ on:
|
||||
jobs:
|
||||
call-licensed:
|
||||
name: Licensed
|
||||
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
||||
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
||||
|
10
.github/workflows/release-new-action-version.yml
vendored
10
.github/workflows/release-new-action-version.yml
vendored
@ -21,8 +21,8 @@ jobs:
|
||||
name: releaseNewActionVersion
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Update the ${{ env.TAG_NAME }} tag
|
||||
uses: actions/publish-action@v0.2.1
|
||||
with:
|
||||
source-tag: ${{ env.TAG_NAME }}
|
||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||
- name: Update the ${{ env.TAG_NAME }} tag
|
||||
uses: actions/publish-action@v0.2.2
|
||||
with:
|
||||
source-tag: ${{ env.TAG_NAME }}
|
||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||
|
38
.github/workflows/test-pypy.yml
vendored
38
.github/workflows/test-pypy.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: Validate PyPy e2e
|
||||
|
||||
on:
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
@ -19,24 +19,24 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
|
||||
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-latest]
|
||||
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'
|
||||
- 'pypy-3.7-v7.3.x'
|
||||
- 'pypy-3.7-v7.x'
|
||||
- 'pypy-2.7-v7.3.4rc1'
|
||||
- 'pypy-3.7-nightly'
|
||||
- 'pypy3.8-v7.3.7'
|
||||
- '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'
|
||||
- 'pypy-3.7-v7.3.x'
|
||||
- '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@v3
|
||||
|
||||
|
||||
- name: setup-python ${{ matrix.pypy }}
|
||||
id: setup-python
|
||||
uses: ./
|
||||
@ -49,7 +49,7 @@ jobs:
|
||||
|
||||
- name: PyPy and Python version
|
||||
run: python --version
|
||||
|
||||
|
||||
- name: Run simple code
|
||||
run: python -c 'import math; print(math.factorial(5))'
|
||||
|
||||
@ -73,7 +73,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
|
||||
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-latest]
|
||||
pypy: ['pypy2.7', 'pypy3.7', 'pypy3.8', 'pypy3.9-nightly']
|
||||
|
||||
steps:
|
||||
@ -138,8 +138,8 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
python-version: |
|
||||
pypy-3.7-v7.3.x
|
||||
pypy3.8
|
||||
pypy-3.7-v7.3.x
|
||||
pypy3.8
|
||||
check-latest: true
|
||||
- name: PyPy and Python version
|
||||
run: python --version
|
||||
@ -166,4 +166,4 @@ jobs:
|
||||
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
|
||||
shell: bash
|
||||
|
402
.github/workflows/test-python.yml
vendored
402
.github/workflows/test-python.yml
vendored
@ -20,34 +20,43 @@ jobs:
|
||||
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]
|
||||
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: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: setup-python ${{ matrix.python }}
|
||||
id: setup-python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
- 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: 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: 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))'
|
||||
- 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
|
||||
@ -55,37 +64,191 @@ jobs:
|
||||
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]
|
||||
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: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: build-version-file ${{ matrix.python }}
|
||||
run: echo ${{ matrix.python }} > .python-version
|
||||
- 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: 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: 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: 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))'
|
||||
- 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, '==3.10.10']
|
||||
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 }}".replace("==", "") -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
|
||||
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-pre-release-version-from-manifest:
|
||||
name: Setup 3.9.0-beta.4 ${{ matrix.os }}
|
||||
@ -93,33 +256,33 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
|
||||
os: [macos-latest, windows-latest, ubuntu-20.04]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout
|
||||
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: 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: 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 3.9.0b4" -ne "$pythonVersion"){
|
||||
Write-Host "The current version is $pythonVersion; expected version is 3.9.0b4"
|
||||
exit 1
|
||||
}
|
||||
$pythonVersion
|
||||
shell: pwsh
|
||||
- name: Validate version
|
||||
run: |
|
||||
$pythonVersion = (python --version)
|
||||
if ("Python 3.9.0b4" -ne "$pythonVersion"){
|
||||
Write-Host "The current version is $pythonVersion; expected version is 3.9.0b4"
|
||||
exit 1
|
||||
}
|
||||
$pythonVersion
|
||||
shell: pwsh
|
||||
|
||||
- name: Run simple code
|
||||
run: python -c 'import math; print(math.factorial(5))'
|
||||
- name: Run simple code
|
||||
run: python -c 'import math; print(math.factorial(5))'
|
||||
|
||||
setup-dev-version:
|
||||
name: Setup 3.9-dev ${{ matrix.os }}
|
||||
@ -129,25 +292,54 @@ jobs:
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: setup-python 3.9-dev
|
||||
id: setup-python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: '3.9-dev'
|
||||
- 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: 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: 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))'
|
||||
- name: Run simple code
|
||||
run: python -c 'import math; print(math.factorial(5))'
|
||||
|
||||
setup-prerelease-version:
|
||||
name: Setup 3.12 ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: setup-python 3.12
|
||||
id: setup-python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: '3.12'
|
||||
allow-prereleases: true
|
||||
|
||||
- name: Check python-path
|
||||
run: ./__tests__/check-python-path.sh '${{ steps.setup-python.outputs.python-path }}'
|
||||
shell: bash
|
||||
|
||||
- name: Validate version
|
||||
run: ${{ startsWith(steps.setup-python.outputs.python-version, '3.12.') }}
|
||||
shell: bash
|
||||
|
||||
- name: Run simple code
|
||||
run: python -c 'import math; print(math.factorial(5))'
|
||||
|
||||
setup-versions-noenv:
|
||||
name: Setup ${{ matrix.python }} ${{ matrix.os }} (noenv)
|
||||
@ -155,24 +347,24 @@ jobs:
|
||||
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"]
|
||||
os: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
|
||||
python: ['3.7', '3.8', '3.9', '3.10']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: setup-python ${{ matrix.python }}
|
||||
id: setup-python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
update-environment: false
|
||||
- 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: 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))'
|
||||
- name: Run simple code
|
||||
run: ${{ steps.setup-python.outputs.python-path }} -c 'import math; print(math.factorial(5))'
|
||||
|
||||
check-latest:
|
||||
runs-on: ${{ matrix.os }}
|
||||
@ -180,7 +372,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ["3.8", "3.9", "3.10"]
|
||||
python-version: ['3.8', '3.9', '3.10']
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python and check latest
|
||||
@ -210,10 +402,10 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
python-version: |
|
||||
3.7
|
||||
3.8
|
||||
3.9
|
||||
3.10
|
||||
3.7
|
||||
3.8
|
||||
3.9
|
||||
3.10
|
||||
check-latest: true
|
||||
- name: Validate version
|
||||
run: |
|
||||
@ -223,4 +415,4 @@ jobs:
|
||||
exit 1
|
||||
}
|
||||
$pythonVersion
|
||||
shell: pwsh
|
||||
shell: pwsh
|
||||
|
11
.github/workflows/update-config-files.yml
vendored
Normal file
11
.github/workflows/update-config-files.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
name: Update configuration files
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 3 * * 0'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-update-configuration-files:
|
||||
name: Update configuration files
|
||||
uses: actions/reusable-workflows/.github/workflows/update-config-files.yml@main
|
2
.licenses/npm/@actions/cache.dep.yml
generated
2
.licenses/npm/@actions/cache.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@actions/cache"
|
||||
version: 3.0.4
|
||||
version: 3.1.4
|
||||
type: npm
|
||||
summary: Actions cache lib
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
|
||||
|
@ -1,9 +1,9 @@
|
||||
---
|
||||
name: "@actions/http-client"
|
||||
version: 2.0.1
|
||||
version: 2.1.0
|
||||
type: npm
|
||||
summary: Actions Http Client
|
||||
homepage: https://github.com/actions/http-client#readme
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
4
.licenses/npm/@azure/abort-controller.dep.yml
generated
4
.licenses/npm/@azure/abort-controller.dep.yml
generated
@ -1,9 +1,9 @@
|
||||
---
|
||||
name: "@azure/abort-controller"
|
||||
version: 1.0.4
|
||||
version: 1.1.0
|
||||
type: npm
|
||||
summary: Microsoft Azure SDK for JavaScript - Aborter
|
||||
homepage: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/core/abort-controller/README.md
|
||||
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/abort-controller/README.md
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
|
2
.licenses/npm/@azure/core-http.dep.yml
generated
2
.licenses/npm/@azure/core-http.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@azure/core-http"
|
||||
version: 2.2.2
|
||||
version: 3.0.1
|
||||
type: npm
|
||||
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
|
||||
libraries generated using AutoRest
|
||||
|
@ -1,16 +1,16 @@
|
||||
---
|
||||
name: ip-regex
|
||||
version: 2.1.0
|
||||
name: "@azure/core-util"
|
||||
version: 1.3.1
|
||||
type: npm
|
||||
summary: Regular expression for matching IP addresses (IPv4 & IPv6)
|
||||
homepage: https://github.com/sindresorhus/ip-regex#readme
|
||||
summary: Core library for shared utility methods
|
||||
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-util/
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: license
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
Copyright (c) 2020 Microsoft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -19,16 +19,14 @@ licenses:
|
||||
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 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.
|
||||
- sources: readme.md
|
||||
text: MIT © [Sindre Sorhus](https://sindresorhus.com)
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
notices: []
|
2
.licenses/npm/@azure/ms-rest-js.dep.yml
generated
2
.licenses/npm/@azure/ms-rest-js.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@azure/ms-rest-js"
|
||||
version: 2.6.0
|
||||
version: 2.7.0
|
||||
type: npm
|
||||
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
|
||||
libraries generated using AutoRest
|
||||
|
2
.licenses/npm/@azure/storage-blob.dep.yml
generated
2
.licenses/npm/@azure/storage-blob.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@azure/storage-blob"
|
||||
version: 12.8.0
|
||||
version: 12.14.0
|
||||
type: npm
|
||||
summary: Microsoft Azure Storage SDK for JavaScript - Blob
|
||||
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/
|
||||
|
26
.licenses/npm/@iarna/toml.dep.yml
generated
Normal file
26
.licenses/npm/@iarna/toml.dep.yml
generated
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
name: "@iarna/toml"
|
||||
version: 2.2.5
|
||||
type: npm
|
||||
summary: Better TOML parsing and stringifying all in that familiar JSON interface.
|
||||
homepage: https://github.com/iarna/iarna-toml#readme
|
||||
license: isc
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |+
|
||||
Copyright (c) 2016, Rebecca Turner <me@re-becca.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
notices: []
|
||||
...
|
2
.licenses/npm/@types/node-fetch.dep.yml
generated
2
.licenses/npm/@types/node-fetch.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@types/node-fetch"
|
||||
version: 2.5.12
|
||||
version: 2.6.3
|
||||
type: npm
|
||||
summary: TypeScript definitions for node-fetch
|
||||
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node-fetch
|
||||
|
26
.licenses/npm/lru-cache.dep.yml
generated
Normal file
26
.licenses/npm/lru-cache.dep.yml
generated
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
name: lru-cache
|
||||
version: 6.0.0
|
||||
type: npm
|
||||
summary: A cache object that deletes the least-recently-used items.
|
||||
homepage:
|
||||
license: isc
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
notices: []
|
43
.licenses/npm/psl.dep.yml
generated
43
.licenses/npm/psl.dep.yml
generated
@ -1,43 +0,0 @@
|
||||
---
|
||||
name: psl
|
||||
version: 1.8.0
|
||||
type: npm
|
||||
summary: Domain name parser based on the Public Suffix List
|
||||
homepage: https://github.com/lupomontero/psl#readme
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Lupo Montero lupomontero@gmail.com
|
||||
|
||||
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.
|
||||
- sources: README.md
|
||||
text: |-
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Lupo Montero <lupomontero@gmail.com>
|
||||
|
||||
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: []
|
34
.licenses/npm/punycode.dep.yml
generated
34
.licenses/npm/punycode.dep.yml
generated
@ -1,34 +0,0 @@
|
||||
---
|
||||
name: punycode
|
||||
version: 2.1.1
|
||||
type: npm
|
||||
summary: A robust Punycode converter that fully complies to RFC 3492 and RFC 5891,
|
||||
and works on nearly all JavaScript platforms.
|
||||
homepage: https://mths.be/punycode
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE-MIT.txt
|
||||
text: |
|
||||
Copyright Mathias Bynens <https://mathiasbynens.be/>
|
||||
|
||||
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.
|
||||
- sources: README.md
|
||||
text: Punycode.js is available under the [MIT](https://mths.be/mit) license.
|
||||
notices: []
|
@ -1,9 +1,9 @@
|
||||
---
|
||||
name: semver
|
||||
version: 7.1.3
|
||||
version: 7.5.2
|
||||
type: npm
|
||||
summary: The semantic version parser used by npm.
|
||||
homepage: https://github.com/npm/node-semver#readme
|
||||
homepage:
|
||||
license: isc
|
||||
licenses:
|
||||
- sources: LICENSE
|
23
.licenses/npm/tough-cookie-3.0.1.dep.yml
generated
23
.licenses/npm/tough-cookie-3.0.1.dep.yml
generated
@ -1,23 +0,0 @@
|
||||
---
|
||||
name: tough-cookie
|
||||
version: 3.0.1
|
||||
type: npm
|
||||
summary: RFC6265 Cookies and Cookie Jar for node.js
|
||||
homepage: https://github.com/salesforce/tough-cookie
|
||||
license: bsd-3-clause
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
Copyright (c) 2015, Salesforce.com, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
notices: []
|
23
.licenses/npm/tough-cookie-4.0.0.dep.yml
generated
23
.licenses/npm/tough-cookie-4.0.0.dep.yml
generated
@ -1,23 +0,0 @@
|
||||
---
|
||||
name: tough-cookie
|
||||
version: 4.0.0
|
||||
type: npm
|
||||
summary: RFC6265 Cookies and Cookie Jar for node.js
|
||||
homepage: https://github.com/salesforce/tough-cookie
|
||||
license: bsd-3-clause
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
Copyright (c) 2015, Salesforce.com, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
notices: []
|
35
.licenses/npm/tslib-2.5.0.dep.yml
generated
Normal file
35
.licenses/npm/tslib-2.5.0.dep.yml
generated
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
name: tslib
|
||||
version: 2.5.0
|
||||
type: npm
|
||||
summary: Runtime library for TypeScript helper functions
|
||||
homepage: https://www.typescriptlang.org/
|
||||
license: 0bsd
|
||||
licenses:
|
||||
- sources: LICENSE.txt
|
||||
text: |-
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
notices:
|
||||
- sources: CopyrightNotice.txt
|
||||
text: "/******************************************************************************\r\nCopyright
|
||||
(c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute
|
||||
this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE
|
||||
SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD
|
||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE,
|
||||
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS
|
||||
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS
|
||||
SOFTWARE.\r\n*****************************************************************************
|
||||
*/"
|
33
.licenses/npm/universalify.dep.yml
generated
33
.licenses/npm/universalify.dep.yml
generated
@ -1,33 +0,0 @@
|
||||
---
|
||||
name: universalify
|
||||
version: 0.1.2
|
||||
type: npm
|
||||
summary: Make a callback- or promise-based function support both promises and callbacks.
|
||||
homepage: https://github.com/RyanZim/universalify#readme
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2017, Ryan Zimmerman <opensrc@ryanzim.com>
|
||||
|
||||
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.
|
||||
- sources: README.md
|
||||
text: MIT
|
||||
notices: []
|
2
.licenses/npm/xml2js.dep.yml
generated
2
.licenses/npm/xml2js.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: xml2js
|
||||
version: 0.4.23
|
||||
version: 0.5.0
|
||||
type: npm
|
||||
summary: Simple XML to JavaScript object converter.
|
||||
homepage: https://github.com/Leonidas-from-XIV/node-xml2js
|
||||
|
26
.licenses/npm/yallist.dep.yml
generated
Normal file
26
.licenses/npm/yallist.dep.yml
generated
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
name: yallist
|
||||
version: 4.0.0
|
||||
type: npm
|
||||
summary: Yet Another Linked List
|
||||
homepage:
|
||||
license: isc
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
notices: []
|
7
.prettierignore
Normal file
7
.prettierignore
Normal file
@ -0,0 +1,7 @@
|
||||
# Ignore list
|
||||
/*
|
||||
|
||||
# Do not ignore these folders:
|
||||
!__tests__/
|
||||
!.github/
|
||||
!src/
|
11
.prettierrc.js
Normal file
11
.prettierrc.js
Normal file
@ -0,0 +1,11 @@
|
||||
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
||||
module.exports = {
|
||||
printWidth: 80,
|
||||
tabWidth: 2,
|
||||
useTabs: false,
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
trailingComma: 'none',
|
||||
bracketSpacing: false,
|
||||
arrowParens: 'avoid'
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": false,
|
||||
"arrowParens": "avoid",
|
||||
"parser": "typescript"
|
||||
}
|
12
README.md
12
README.md
@ -1,8 +1,9 @@
|
||||
# setup-python
|
||||
|
||||
<p align="left">
|
||||
<a href="https://github.com/actions/setup-python"><img alt="GitHub Actions status" src="https://github.com/actions/setup-python/workflows/Main%20workflow/badge.svg"></a>
|
||||
</p>
|
||||
[](https://github.com/actions/setup-python/actions/workflows/basic-validation.yml)
|
||||
[](https://github.com/actions/setup-python/actions/workflows/test-python.yml)
|
||||
[](https://github.com/actions/setup-python/actions/workflows/test-pypy.yml)
|
||||
[](https://github.com/actions/setup-python/actions/workflows/e2e-cache.yml)
|
||||
|
||||
This action provides the following functionality for GitHub Actions users:
|
||||
|
||||
@ -51,11 +52,11 @@ Using `architecture` input it is possible to specify the required Python or PyPy
|
||||
|
||||
The action has built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip`, `pipenv` and `poetry`. The `cache` input is optional, and caching is turned off by default.
|
||||
|
||||
The action defaults to searching for a dependency file (`requirements.txt` for pip, `Pipfile.lock` for pipenv or `poetry.lock` for poetry) in the repository, and uses its hash as a part of the cache key. Input `cache-dependency-path` is used for cases when multiple dependency files are used, they are located in different subdirectories or different files for the hash that want to be used.
|
||||
The action defaults to searching for a dependency file (`requirements.txt` or `pyproject.toml` for pip, `Pipfile.lock` for pipenv or `poetry.lock` for poetry) in the repository, and uses its hash as a part of the cache key. Input `cache-dependency-path` is used for cases when multiple dependency files are used, they are located in different subdirectories or different files for the hash that want to be used.
|
||||
|
||||
- For `pip`, the action will cache the global cache directory
|
||||
- For `pipenv`, the action will cache virtualenv directory
|
||||
- For `poetry`, the action will cache virtualenv directory
|
||||
- For `poetry`, the action will cache virtualenv directories -- one for each poetry project found
|
||||
|
||||
**Caching pip dependencies:**
|
||||
|
||||
@ -85,6 +86,7 @@ See examples of using `cache` and `cache-dependency-path` for `pipenv` and `poet
|
||||
- [Hosted tool cache](docs/advanced-usage.md#hosted-tool-cache)
|
||||
- [Using `setup-python` with a self-hosted runner](docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner)
|
||||
- [Using `setup-python` on GHES](docs/advanced-usage.md#using-setup-python-on-ghes)
|
||||
- [Allow pre-releases](docs/advanced-usage.md#allow-pre-releases)
|
||||
|
||||
## License
|
||||
|
||||
|
@ -1,19 +1,20 @@
|
||||
import * as path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as cache from '@actions/cache';
|
||||
import * as exec from '@actions/exec';
|
||||
import * as io from '@actions/io';
|
||||
import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
|
||||
import * as utils from './../src/utils';
|
||||
import {State} from '../src/cache-distributions/cache-distributor';
|
||||
|
||||
describe('restore-cache', () => {
|
||||
const pipFileLockHash =
|
||||
'a3bdcc71289e4979ca9e051810d81999cc99823109faf6912e17ff14c8e621a6';
|
||||
'f8428d7cf00ea53a5c3702f0a9cb3cc467f76cd86a34723009350c4e4b32751a';
|
||||
const requirementsHash =
|
||||
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
|
||||
const requirementsLinuxHash =
|
||||
'2d0ff7f46b0e120e3d3294db65768b474934242637b9899b873e6283dfd16d7c';
|
||||
const poetryLockHash =
|
||||
'571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836';
|
||||
'f24ea1ad73968e6c8d80c16a093ade72d9332c433aeef979a0dd943e6a99b2ab';
|
||||
const poetryConfigOutput = `
|
||||
cache-dir = "/Users/patrick/Library/Caches/pypoetry"
|
||||
experimental.new-installer = false
|
||||
@ -27,7 +28,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||
let infoSpy: jest.SpyInstance;
|
||||
let warningSpy: jest.SpyInstance;
|
||||
let debugSpy: jest.SpyInstance;
|
||||
let saveSatetSpy: jest.SpyInstance;
|
||||
let saveStateSpy: jest.SpyInstance;
|
||||
let getStateSpy: jest.SpyInstance;
|
||||
let setOutputSpy: jest.SpyInstance;
|
||||
|
||||
@ -52,8 +53,8 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||
debugSpy = jest.spyOn(core, 'debug');
|
||||
debugSpy.mockImplementation(input => undefined);
|
||||
|
||||
saveSatetSpy = jest.spyOn(core, 'saveState');
|
||||
saveSatetSpy.mockImplementation(input => undefined);
|
||||
saveStateSpy = jest.spyOn(core, 'saveState');
|
||||
saveStateSpy.mockImplementation(input => undefined);
|
||||
|
||||
getStateSpy = jest.spyOn(core, 'getState');
|
||||
getStateSpy.mockImplementation(input => undefined);
|
||||
@ -93,28 +94,81 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||
async packageManager => {
|
||||
expect(() =>
|
||||
getCacheDistributor(packageManager, '3.8.12', undefined)
|
||||
).toThrowError(`Caching for '${packageManager}' is not supported`);
|
||||
).toThrow(`Caching for '${packageManager}' is not supported`);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('Restore dependencies', () => {
|
||||
it.each([
|
||||
['pip', '3.8.12', undefined, requirementsHash],
|
||||
['pip', '3.8.12', '**/requirements-linux.txt', requirementsLinuxHash],
|
||||
[
|
||||
'pip',
|
||||
'3.8.12',
|
||||
'__tests__/data/**/requirements.txt',
|
||||
requirementsHash,
|
||||
undefined
|
||||
],
|
||||
[
|
||||
'pip',
|
||||
'3.8.12',
|
||||
'__tests__/data/**/requirements-linux.txt',
|
||||
requirementsLinuxHash,
|
||||
undefined
|
||||
],
|
||||
[
|
||||
'pip',
|
||||
'3.8.12',
|
||||
'__tests__/data/requirements-linux.txt',
|
||||
requirementsLinuxHash
|
||||
requirementsLinuxHash,
|
||||
undefined
|
||||
],
|
||||
['pip', '3.8.12', '__tests__/data/requirements.txt', requirementsHash],
|
||||
['pipenv', '3.9.1', undefined, pipFileLockHash],
|
||||
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
|
||||
['poetry', '3.9.1', undefined, poetryLockHash]
|
||||
[
|
||||
'pip',
|
||||
'3.8.12',
|
||||
'__tests__/data/requirements.txt',
|
||||
requirementsHash,
|
||||
undefined
|
||||
],
|
||||
[
|
||||
'pipenv',
|
||||
'3.9.1',
|
||||
'__tests__/data/**/Pipfile.lock',
|
||||
pipFileLockHash,
|
||||
undefined
|
||||
],
|
||||
[
|
||||
'pipenv',
|
||||
'3.9.12',
|
||||
'__tests__/data/requirements.txt',
|
||||
requirementsHash,
|
||||
undefined
|
||||
],
|
||||
[
|
||||
'poetry',
|
||||
'3.9.1',
|
||||
'__tests__/data/**/poetry.lock',
|
||||
poetryLockHash,
|
||||
[
|
||||
'/Users/patrick/Library/Caches/pypoetry/virtualenvs',
|
||||
path.join(__dirname, 'data', 'inner', '.venv'),
|
||||
path.join(__dirname, 'data', '.venv')
|
||||
]
|
||||
]
|
||||
])(
|
||||
'restored dependencies for %s by primaryKey',
|
||||
async (packageManager, pythonVersion, dependencyFile, fileHash) => {
|
||||
async (
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
dependencyFile,
|
||||
fileHash,
|
||||
cachePaths
|
||||
) => {
|
||||
restoreCacheSpy.mockImplementation(
|
||||
(cachePaths: string[], primaryKey: string, restoreKey?: string) => {
|
||||
return primaryKey.includes(fileHash) ? primaryKey : '';
|
||||
}
|
||||
);
|
||||
|
||||
const cacheDistributor = getCacheDistributor(
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
@ -123,10 +177,21 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||
|
||||
await cacheDistributor.restoreCache();
|
||||
|
||||
if (cachePaths !== undefined) {
|
||||
expect(saveStateSpy).toHaveBeenCalledWith(
|
||||
State.CACHE_PATHS,
|
||||
cachePaths
|
||||
);
|
||||
}
|
||||
|
||||
if (process.platform === 'linux' && packageManager === 'pip') {
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-20.04-Ubuntu-python-${pythonVersion}-${packageManager}-${fileHash}`
|
||||
);
|
||||
} else if (packageManager === 'poetry') {
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-v2-${fileHash}`
|
||||
);
|
||||
} else {
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-${fileHash}`
|
||||
@ -136,11 +201,7 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||
30000
|
||||
);
|
||||
|
||||
it.each([
|
||||
['pip', '3.8.12', 'requirements-linux.txt', 'requirements-linux.txt'],
|
||||
['pip', '3.8.12', 'requirements.txt', 'requirements.txt'],
|
||||
['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']
|
||||
])(
|
||||
it.each([['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt']])(
|
||||
'Should throw an error because dependency file is not found',
|
||||
async (
|
||||
packageManager,
|
||||
@ -153,19 +214,58 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||
pythonVersion,
|
||||
dependencyFile
|
||||
);
|
||||
await expect(cacheDistributor.restoreCache()).rejects.toThrowError(
|
||||
|
||||
await expect(cacheDistributor.restoreCache()).rejects.toThrow(
|
||||
`No file in ${process.cwd()} matched to [${cacheDependencyPath
|
||||
.split('\n')
|
||||
.join(',')}], make sure you have checked out the target repository`
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
it.each([
|
||||
['pip', '3.8.12', 'requirements-linux.txt'],
|
||||
['pip', '3.8.12', 'requirements.txt']
|
||||
])(
|
||||
'Shouldn`t throw an error as there is a default file `pyproject.toml` to use when requirements.txt is not specified',
|
||||
async (packageManager, pythonVersion, dependencyFile) => {
|
||||
const cacheDistributor = getCacheDistributor(
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
dependencyFile
|
||||
);
|
||||
await expect(cacheDistributor.restoreCache()).resolves.not.toThrow();
|
||||
}
|
||||
);
|
||||
|
||||
it.each([
|
||||
['pip', '3.8.12', 'requirements-linux.txt'],
|
||||
['pip', '3.8.12', 'requirements.txt']
|
||||
])(
|
||||
'Should throw an error as there is no default file `pyproject.toml` to use when requirements.txt is not specified',
|
||||
async (packageManager, pythonVersion, dependencyFile) => {
|
||||
const cacheDistributor = getCacheDistributor(
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
dependencyFile
|
||||
) as any; // Widening PipCache | PipenvCache | PoetryCache type to any allow us to change private property on the cacheDistributor to test value: "**/pyprojecttest.toml"
|
||||
|
||||
cacheDistributor.cacheDependencyBackupPath = '**/pyprojecttest.toml';
|
||||
|
||||
await expect(cacheDistributor.restoreCache()).rejects.toThrow();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('Dependencies changed', () => {
|
||||
it.each([
|
||||
['pip', '3.8.12', undefined, pipFileLockHash],
|
||||
['pip', '3.8.12', '**/requirements-linux.txt', pipFileLockHash],
|
||||
['pip', '3.8.12', '__tests__/data/**/requirements.txt', pipFileLockHash],
|
||||
[
|
||||
'pip',
|
||||
'3.8.12',
|
||||
'__tests__/data/**/requirements-linux.txt',
|
||||
pipFileLockHash
|
||||
],
|
||||
[
|
||||
'pip',
|
||||
'3.8.12',
|
||||
@ -173,9 +273,9 @@ virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/py
|
||||
pipFileLockHash
|
||||
],
|
||||
['pip', '3.8.12', '__tests__/data/requirements.txt', pipFileLockHash],
|
||||
['pipenv', '3.9.1', undefined, requirementsHash],
|
||||
['pipenv', '3.9.1', '__tests__/data/**/Pipfile.lock', requirementsHash],
|
||||
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
|
||||
['poetry', '3.9.1', undefined, requirementsHash]
|
||||
['poetry', '3.9.1', '__tests__/data/**/poetry.lock', requirementsHash]
|
||||
])(
|
||||
'restored dependencies for %s by primaryKey',
|
||||
async (packageManager, pythonVersion, dependencyFile, fileHash) => {
|
||||
|
@ -18,7 +18,7 @@ describe('run', () => {
|
||||
let infoSpy: jest.SpyInstance;
|
||||
let warningSpy: jest.SpyInstance;
|
||||
let debugSpy: jest.SpyInstance;
|
||||
let saveSatetSpy: jest.SpyInstance;
|
||||
let saveStateSpy: jest.SpyInstance;
|
||||
let getStateSpy: jest.SpyInstance;
|
||||
let getInputSpy: jest.SpyInstance;
|
||||
let setFailedSpy: jest.SpyInstance;
|
||||
@ -43,8 +43,8 @@ describe('run', () => {
|
||||
debugSpy = jest.spyOn(core, 'debug');
|
||||
debugSpy.mockImplementation(input => undefined);
|
||||
|
||||
saveSatetSpy = jest.spyOn(core, 'saveState');
|
||||
saveSatetSpy.mockImplementation(input => undefined);
|
||||
saveStateSpy = jest.spyOn(core, 'saveState');
|
||||
saveStateSpy.mockImplementation(input => undefined);
|
||||
|
||||
getStateSpy = jest.spyOn(core, 'getState');
|
||||
getStateSpy.mockImplementation(input => {
|
||||
@ -87,6 +87,7 @@ describe('run', () => {
|
||||
describe('Validate unchanged cache is not saved', () => {
|
||||
it('should not save cache for pip', async () => {
|
||||
inputs['cache'] = 'pip';
|
||||
inputs['python-version'] = '3.10.0';
|
||||
|
||||
await run();
|
||||
|
||||
@ -103,22 +104,7 @@ describe('run', () => {
|
||||
|
||||
it('should not save cache for pipenv', async () => {
|
||||
inputs['cache'] = 'pipenv';
|
||||
|
||||
await run();
|
||||
|
||||
expect(getInputSpy).toHaveBeenCalled();
|
||||
expect(debugSpy).toHaveBeenCalledWith(
|
||||
`paths for caching are ${__dirname}`
|
||||
);
|
||||
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
`Cache hit occurred on the primary key ${requirementsHash}, not saving cache.`
|
||||
);
|
||||
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not save cache for pipenv', async () => {
|
||||
inputs['cache'] = 'pipenv';
|
||||
inputs['python-version'] = '3.10.0';
|
||||
|
||||
await run();
|
||||
|
||||
@ -137,6 +123,7 @@ describe('run', () => {
|
||||
describe('action saves the cache', () => {
|
||||
it('saves cache from pip', async () => {
|
||||
inputs['cache'] = 'pip';
|
||||
inputs['python-version'] = '3.10.0';
|
||||
getStateSpy.mockImplementation((name: string) => {
|
||||
if (name === State.CACHE_MATCHED_KEY) {
|
||||
return requirementsHash;
|
||||
@ -163,6 +150,7 @@ describe('run', () => {
|
||||
|
||||
it('saves cache from pipenv', async () => {
|
||||
inputs['cache'] = 'pipenv';
|
||||
inputs['python-version'] = '3.10.0';
|
||||
getStateSpy.mockImplementation((name: string) => {
|
||||
if (name === State.CACHE_MATCHED_KEY) {
|
||||
return pipFileLockHash;
|
||||
@ -189,6 +177,7 @@ describe('run', () => {
|
||||
|
||||
it('saves cache from poetry', async () => {
|
||||
inputs['cache'] = 'poetry';
|
||||
inputs['python-version'] = '3.10.0';
|
||||
getStateSpy.mockImplementation((name: string) => {
|
||||
if (name === State.CACHE_MATCHED_KEY) {
|
||||
return poetryLockHash;
|
||||
@ -215,6 +204,7 @@ describe('run', () => {
|
||||
|
||||
it('saves with -1 cacheId , should not fail workflow', async () => {
|
||||
inputs['cache'] = 'poetry';
|
||||
inputs['python-version'] = '3.10.0';
|
||||
getStateSpy.mockImplementation((name: string) => {
|
||||
if (name === State.STATE_CACHE_PRIMARY_KEY) {
|
||||
return poetryLockHash;
|
||||
@ -241,8 +231,9 @@ describe('run', () => {
|
||||
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('saves with error from toolkit, should fail workflow', async () => {
|
||||
it('saves with error from toolkit, should not fail the workflow', async () => {
|
||||
inputs['cache'] = 'npm';
|
||||
inputs['python-version'] = '3.10.0';
|
||||
getStateSpy.mockImplementation((name: string) => {
|
||||
if (name === State.STATE_CACHE_PRIMARY_KEY) {
|
||||
return poetryLockHash;
|
||||
@ -263,7 +254,7 @@ describe('run', () => {
|
||||
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||
expect(infoSpy).not.toHaveBeenCalledWith();
|
||||
expect(saveCacheSpy).toHaveBeenCalled();
|
||||
expect(setFailedSpy).toHaveBeenCalled();
|
||||
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -4,8 +4,8 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
flake8 = "==4.0.1"
|
||||
numpy = "==1.23.0"
|
||||
flake8 = "==6.0.0"
|
||||
numpy = "==1.25.1"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
80
__tests__/data/Pipfile.lock
generated
80
__tests__/data/Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "e9c37110984955621040e2dc8548c026eb8466c23db1b8e69430289b10be8938"
|
||||
"sha256": "dcea65dabfe8442466b5e9280ecab72cfa7bf555791ee0ad55b6e7255dca1f43"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -18,62 +18,66 @@
|
||||
"default": {
|
||||
"flake8": {
|
||||
"hashes": [
|
||||
"sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d",
|
||||
"sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"
|
||||
"sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7",
|
||||
"sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.0.1"
|
||||
"version": "==6.0.0"
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
|
||||
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
|
||||
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
|
||||
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
|
||||
],
|
||||
"version": "==0.6.1"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:092f5e6025813e64ad6d1b52b519165d08c730d099c114a9247c9bb635a2a450",
|
||||
"sha256:196cd074c3f97c4121601790955f915187736f9cf458d3ee1f1b46aff2b1ade0",
|
||||
"sha256:1c29b44905af288b3919803aceb6ec7fec77406d8b08aaa2e8b9e63d0fe2f160",
|
||||
"sha256:2b2da66582f3a69c8ce25ed7921dcd8010d05e59ac8d89d126a299be60421171",
|
||||
"sha256:5043bcd71fcc458dfb8a0fc5509bbc979da0131b9d08e3d5f50fb0bbb36f169a",
|
||||
"sha256:58bfd40eb478f54ff7a5710dd61c8097e169bc36cc68333d00a9bcd8def53b38",
|
||||
"sha256:79a506cacf2be3a74ead5467aee97b81fca00c9c4c8b3ba16dbab488cd99ba10",
|
||||
"sha256:94b170b4fa0168cd6be4becf37cb5b127bd12a795123984385b8cd4aca9857e5",
|
||||
"sha256:97a76604d9b0e79f59baeca16593c711fddb44936e40310f78bfef79ee9a835f",
|
||||
"sha256:98e8e0d8d69ff4d3fa63e6c61e8cfe2d03c29b16b58dbef1f9baa175bbed7860",
|
||||
"sha256:ac86f407873b952679f5f9e6c0612687e51547af0e14ddea1eedfcb22466babd",
|
||||
"sha256:ae8adff4172692ce56233db04b7ce5792186f179c415c37d539c25de7298d25d",
|
||||
"sha256:bd3fa4fe2e38533d5336e1272fc4e765cabbbde144309ccee8675509d5cd7b05",
|
||||
"sha256:d0d2094e8f4d760500394d77b383a1b06d3663e8892cdf5df3c592f55f3bff66",
|
||||
"sha256:d54b3b828d618a19779a84c3ad952e96e2c2311b16384e973e671aa5be1f6187",
|
||||
"sha256:d6ca8dabe696c2785d0c8c9b0d8a9b6e5fdbe4f922bde70d57fa1a2848134f95",
|
||||
"sha256:d8cc87bed09de55477dba9da370c1679bd534df9baa171dd01accbb09687dac3",
|
||||
"sha256:f0f18804df7370571fb65db9b98bf1378172bd4e962482b857e612d1fec0f53e",
|
||||
"sha256:f1d88ef79e0a7fa631bb2c3dda1ea46b32b1fe614e10fedd611d3d5398447f2f",
|
||||
"sha256:f9c3fc2adf67762c9fe1849c859942d23f8d3e0bee7b5ed3d4a9c3eeb50a2f07",
|
||||
"sha256:fc431493df245f3c627c0c05c2bd134535e7929dbe2e602b80e42bf52ff760bc",
|
||||
"sha256:fe8b9683eb26d2c4d5db32cd29b38fdcf8381324ab48313b5b69088e0e355379"
|
||||
"sha256:012097b5b0d00a11070e8f2e261128c44157a8689f7dedcf35576e525893f4fe",
|
||||
"sha256:0d3fe3dd0506a28493d82dc3cf254be8cd0d26f4008a417385cbf1ae95b54004",
|
||||
"sha256:0def91f8af6ec4bb94c370e38c575855bf1d0be8a8fbfba42ef9c073faf2cf19",
|
||||
"sha256:1a180429394f81c7933634ae49b37b472d343cccb5bb0c4a575ac8bbc433722f",
|
||||
"sha256:1d5d3c68e443c90b38fdf8ef40e60e2538a27548b39b12b73132456847f4b631",
|
||||
"sha256:20e1266411120a4f16fad8efa8e0454d21d00b8c7cee5b5ccad7565d95eb42dd",
|
||||
"sha256:247d3ffdd7775bdf191f848be8d49100495114c82c2bd134e8d5d075fb386a1c",
|
||||
"sha256:35a9527c977b924042170a0887de727cd84ff179e478481404c5dc66b4170009",
|
||||
"sha256:38eb6548bb91c421261b4805dc44def9ca1a6eef6444ce35ad1669c0f1a3fc5d",
|
||||
"sha256:3d7abcdd85aea3e6cdddb59af2350c7ab1ed764397f8eec97a038ad244d2d105",
|
||||
"sha256:41a56b70e8139884eccb2f733c2f7378af06c82304959e174f8e7370af112e09",
|
||||
"sha256:4a90725800caeaa160732d6b31f3f843ebd45d6b5f3eec9e8cc287e30f2805bf",
|
||||
"sha256:6b82655dd8efeea69dbf85d00fca40013d7f503212bc5259056244961268b66e",
|
||||
"sha256:6c6c9261d21e617c6dc5eacba35cb68ec36bb72adcff0dee63f8fbc899362588",
|
||||
"sha256:77d339465dff3eb33c701430bcb9c325b60354698340229e1dff97745e6b3efa",
|
||||
"sha256:791f409064d0a69dd20579345d852c59822c6aa087f23b07b1b4e28ff5880fcb",
|
||||
"sha256:9a3a9f3a61480cc086117b426a8bd86869c213fc4072e606f01c4e4b66eb92bf",
|
||||
"sha256:c1516db588987450b85595586605742879e50dcce923e8973f79529651545b57",
|
||||
"sha256:c40571fe966393b212689aa17e32ed905924120737194b5d5c1b20b9ed0fb171",
|
||||
"sha256:d412c1697c3853c6fc3cb9751b4915859c7afe6a277c2bf00acf287d56c4e625",
|
||||
"sha256:d5154b1a25ec796b1aee12ac1b22f414f94752c5f94832f14d8d6c9ac40bcca6",
|
||||
"sha256:d736b75c3f2cb96843a5c7f8d8ccc414768d34b0a75f466c05f3a739b406f10b",
|
||||
"sha256:e8f6049c4878cb16960fbbfb22105e49d13d752d4d8371b55110941fb3b17800",
|
||||
"sha256:f76aebc3358ade9eacf9bc2bb8ae589863a4f911611694103af05346637df1b7",
|
||||
"sha256:fd67b306320dcadea700a8f79b9e671e607f8696e98ec255915c0c6d6b818503"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.23.0"
|
||||
"version": "==1.25.1"
|
||||
},
|
||||
"pycodestyle": {
|
||||
"hashes": [
|
||||
"sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20",
|
||||
"sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"
|
||||
"sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053",
|
||||
"sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==2.8.0"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.10.0"
|
||||
},
|
||||
"pyflakes": {
|
||||
"hashes": [
|
||||
"sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c",
|
||||
"sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"
|
||||
"sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf",
|
||||
"sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.4.0"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.0.1"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
1
__tests__/data/inner/poetry.lock
generated
Symbolic link
1
__tests__/data/inner/poetry.lock
generated
Symbolic link
@ -0,0 +1 @@
|
||||
../poetry.lock
|
1
__tests__/data/inner/pyproject.toml
Symbolic link
1
__tests__/data/inner/pyproject.toml
Symbolic link
@ -0,0 +1 @@
|
||||
../pyproject.toml
|
@ -1,2 +1,2 @@
|
||||
numpy==1.22.3
|
||||
pandas==1.4.2
|
||||
flake8==6.0.0
|
@ -1,4 +1,94 @@
|
||||
[
|
||||
{
|
||||
"pypy_version": "7.3.8rc2",
|
||||
"python_version": "3.8.12",
|
||||
"stable": false,
|
||||
"latest_pypy": false,
|
||||
"date": "2022-02-11",
|
||||
"files": [
|
||||
{
|
||||
"filename": "pypy3.8-v7.3.8rc2-linux32.tar.bz2",
|
||||
"arch": "i686",
|
||||
"platform": "linux",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-linux32.tar.bz2"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.8-v7.3.8rc2-linux64.tar.bz2",
|
||||
"arch": "x64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-linux64.tar.bz2"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.8-v7.3.8rc2-darwin64.tar.bz2",
|
||||
"arch": "x64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-darwin64.tar.bz2"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.8-v7.3.8rc2-s390x.tar.bz2",
|
||||
"arch": "s390x",
|
||||
"platform": "linux",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-s390x.tar.bz2"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.8-v7.3.8rc2-win64.zip",
|
||||
"arch": "x64",
|
||||
"platform": "win64",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-win64.zip"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.8-v7.3.8rc2-win32.zip",
|
||||
"arch": "x86",
|
||||
"platform": "win32",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.8-v7.3.8rc2-win32.zip"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pypy_version": "7.4.0rc1",
|
||||
"python_version": "3.6.12",
|
||||
"stable": false,
|
||||
"latest_pypy": false,
|
||||
"date": "2021-11-11",
|
||||
"files": [
|
||||
{
|
||||
"filename": "pypy3.6-v7.4.0rc1-aarch64.tar.bz2",
|
||||
"arch": "aarch64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-aarch64.tar.bz2"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.6-v7.4.0rc1-linux32.tar.bz2",
|
||||
"arch": "i686",
|
||||
"platform": "linux",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-linux32.tar.bz2"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.6-v7.4.0rc1-linux64.tar.bz2",
|
||||
"arch": "x64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-linux64.tar.bz2"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.6-v7.4.0rc1-darwin64.tar.bz2",
|
||||
"arch": "x64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-darwin64.tar.bz2"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.6-v7.4.0rc1-win32.zip",
|
||||
"arch": "x86",
|
||||
"platform": "win32",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-win32.zip"
|
||||
},
|
||||
{
|
||||
"filename": "pypy3.6-v7.4.0rc1-s390x.tar.bz2",
|
||||
"arch": "s390x",
|
||||
"platform": "linux",
|
||||
"download_url": "https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-s390x.tar.bz2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"pypy_version": "7.3.3",
|
||||
"python_version": "3.6.12",
|
||||
@ -530,4 +620,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -1,4 +1,29 @@
|
||||
[
|
||||
{
|
||||
"version": "1.2.4-beta.2",
|
||||
"stable": false,
|
||||
"release_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5",
|
||||
"files": [
|
||||
{
|
||||
"filename": "sometool-1.2.4-linux-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-linux-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "sometool-1.2.4-darwin-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-darwin-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "sometool-1.2.4-win32-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "win32",
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.4-beta.2-20200402.5/sometool-1.2.4-win32-x64.tar.gz"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.2.3",
|
||||
"stable": true,
|
||||
@ -25,28 +50,28 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.2.3-beta.2",
|
||||
"version": "1.1.0-beta.2",
|
||||
"stable": false,
|
||||
"release_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5",
|
||||
"release_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5",
|
||||
"files": [
|
||||
{
|
||||
"filename": "sometool-1.2.3-linux-x64.tar.gz",
|
||||
"filename": "sometool-1.1.0-linux-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "linux",
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-beta.2-20200402.5/sometool-1.2.3-linux-x64.tar.gz"
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-linux-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "sometool-1.2.3-darwin-x64.tar.gz",
|
||||
"filename": "sometool-1.1.0-darwin-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "darwin",
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-darwin-x64.tar.gz"
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-darwin-x64.tar.gz"
|
||||
},
|
||||
{
|
||||
"filename": "sometool-1.2.3-win32-x64.tar.gz",
|
||||
"filename": "sometool-1.1.0-win32-x64.tar.gz",
|
||||
"arch": "x64",
|
||||
"platform": "win32",
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.2.3-20200402.5/sometool-1.2.3-win32-x64.tar.gz"
|
||||
"download_url": "https://github.com/actions/sometool/releases/tag/1.1.0-beta.2-20200402.5/sometool-1.1.0-win32-x64.tar.gz"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
@ -17,7 +17,7 @@ import {
|
||||
getPyPyVersionFromPath
|
||||
} from '../src/utils';
|
||||
|
||||
const manifestData = require('./data/pypy.json');
|
||||
import manifestData from './data/pypy.json';
|
||||
|
||||
let architecture: string;
|
||||
|
||||
@ -51,7 +51,7 @@ describe('parsePyPyVersion', () => {
|
||||
it.each(['', 'pypy-', 'pypy', 'p', 'notpypy-'])(
|
||||
'throw on invalid input "%s"',
|
||||
input => {
|
||||
expect(() => finder.parsePyPyVersion(input)).toThrowError(
|
||||
expect(() => finder.parsePyPyVersion(input)).toThrow(
|
||||
"Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy<python-version>' or 'pypy-<python-version>'. See README for examples and documentation."
|
||||
);
|
||||
}
|
||||
@ -60,7 +60,7 @@ describe('parsePyPyVersion', () => {
|
||||
it.each(['pypy-2', 'pypy-3', 'pypy2', 'pypy3', 'pypy3.x', 'pypy3.8.10'])(
|
||||
'throw on invalid input "%s"',
|
||||
input => {
|
||||
expect(() => finder.parsePyPyVersion(input)).toThrowError(
|
||||
expect(() => finder.parsePyPyVersion(input)).toThrow(
|
||||
"Invalid format of Python version for PyPy. Python version should be specified in format 'x.y'. See README for examples and documentation."
|
||||
);
|
||||
}
|
||||
@ -273,7 +273,13 @@ describe('findPyPyVersion', () => {
|
||||
|
||||
it('found PyPy in toolcache', async () => {
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, true, false)
|
||||
finder.findPyPyVersion(
|
||||
'pypy-3.6-v7.3.x',
|
||||
architecture,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
)
|
||||
).resolves.toEqual({
|
||||
resolvedPythonVersion: '3.6.12',
|
||||
resolvedPyPyVersion: '7.3.3'
|
||||
@ -291,13 +297,13 @@ describe('findPyPyVersion', () => {
|
||||
|
||||
it('throw on invalid input format', async () => {
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false)
|
||||
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false)
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
it('throw on invalid input format pypy3.7-7.3.x', async () => {
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false)
|
||||
finder.findPyPyVersion('pypy3.7-v7.3.x', architecture, true, false, false)
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
@ -309,7 +315,13 @@ describe('findPyPyVersion', () => {
|
||||
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
||||
spyChmodSync.mockImplementation(() => undefined);
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, true, false)
|
||||
finder.findPyPyVersion(
|
||||
'pypy-3.7-v7.3.x',
|
||||
architecture,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
)
|
||||
).resolves.toEqual({
|
||||
resolvedPythonVersion: '3.7.9',
|
||||
resolvedPyPyVersion: '7.3.3'
|
||||
@ -333,7 +345,13 @@ describe('findPyPyVersion', () => {
|
||||
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
||||
spyChmodSync.mockImplementation(() => undefined);
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, false)
|
||||
finder.findPyPyVersion(
|
||||
'pypy-3.7-v7.3.x',
|
||||
architecture,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
).resolves.toEqual({
|
||||
resolvedPythonVersion: '3.7.9',
|
||||
resolvedPyPyVersion: '7.3.3'
|
||||
@ -344,15 +362,27 @@ describe('findPyPyVersion', () => {
|
||||
|
||||
it('throw if release is not found', async () => {
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy-3.7-v7.5.x', architecture, true, false)
|
||||
).rejects.toThrowError(
|
||||
finder.findPyPyVersion(
|
||||
'pypy-3.7-v7.5.x',
|
||||
architecture,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
)
|
||||
).rejects.toThrow(
|
||||
`PyPy version 3.7 (v7.5.x) with arch ${architecture} not found`
|
||||
);
|
||||
});
|
||||
|
||||
it('check-latest enabled version found and used from toolcache', async () => {
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy-3.6-v7.3.x', architecture, false, true)
|
||||
finder.findPyPyVersion(
|
||||
'pypy-3.6-v7.3.x',
|
||||
architecture,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
)
|
||||
).resolves.toEqual({
|
||||
resolvedPythonVersion: '3.6.12',
|
||||
resolvedPyPyVersion: '7.3.3'
|
||||
@ -371,7 +401,13 @@ describe('findPyPyVersion', () => {
|
||||
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
||||
spyChmodSync.mockImplementation(() => undefined);
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy-3.7-v7.3.x', architecture, false, true)
|
||||
finder.findPyPyVersion(
|
||||
'pypy-3.7-v7.3.x',
|
||||
architecture,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
)
|
||||
).resolves.toEqual({
|
||||
resolvedPythonVersion: '3.7.9',
|
||||
resolvedPyPyVersion: '7.3.3'
|
||||
@ -391,7 +427,13 @@ describe('findPyPyVersion', () => {
|
||||
return pypyPath;
|
||||
});
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy-3.8-v7.3.x', architecture, false, true)
|
||||
finder.findPyPyVersion(
|
||||
'pypy-3.8-v7.3.x',
|
||||
architecture,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
)
|
||||
).resolves.toEqual({
|
||||
resolvedPythonVersion: '3.8.8',
|
||||
resolvedPyPyVersion: '7.3.3'
|
||||
@ -401,4 +443,22 @@ describe('findPyPyVersion', () => {
|
||||
'Failed to resolve PyPy v7.3.x with Python (3.8) from manifest'
|
||||
);
|
||||
});
|
||||
|
||||
it('found and install successfully, pre-release fallback', async () => {
|
||||
spyCacheDir = jest.spyOn(tc, 'cacheDir');
|
||||
spyCacheDir.mockImplementation(() =>
|
||||
path.join(toolDir, 'PyPy', '3.8.12', architecture)
|
||||
);
|
||||
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
||||
spyChmodSync.mockImplementation(() => undefined);
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy3.8', architecture, false, false, false)
|
||||
).rejects.toThrow();
|
||||
await expect(
|
||||
finder.findPyPyVersion('pypy3.8', architecture, false, false, true)
|
||||
).resolves.toEqual({
|
||||
resolvedPythonVersion: '3.8.12',
|
||||
resolvedPyPyVersion: '7.3.8rc2'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ import * as core from '@actions/core';
|
||||
import * as finder from '../src/find-python';
|
||||
import * as installer from '../src/install-python';
|
||||
|
||||
const manifestData = require('./data/versions-manifest.json');
|
||||
import manifestData from './data/versions-manifest.json';
|
||||
|
||||
describe('Finder tests', () => {
|
||||
let writeSpy: jest.SpyInstance;
|
||||
@ -56,7 +56,7 @@ describe('Finder tests', () => {
|
||||
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', true, false);
|
||||
await finder.useCpythonVersion('3.x', 'x64', true, false, false);
|
||||
expect(spyCoreAddPath).toHaveBeenCalled();
|
||||
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||
'pythonLocation',
|
||||
@ -73,7 +73,7 @@ describe('Finder tests', () => {
|
||||
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, false);
|
||||
await finder.useCpythonVersion('3.x', 'x64', false, false, false);
|
||||
expect(spyCoreAddPath).not.toHaveBeenCalled();
|
||||
expect(spyCoreExportVariable).not.toHaveBeenCalled();
|
||||
});
|
||||
@ -95,7 +95,12 @@ describe('Finder tests', () => {
|
||||
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('1.2.3', 'x64', true, false);
|
||||
await expect(
|
||||
finder.useCpythonVersion('1.2.3', 'x64', true, false, false)
|
||||
).resolves.toEqual({
|
||||
impl: 'CPython',
|
||||
version: '1.2.3'
|
||||
});
|
||||
expect(spyCoreAddPath).toHaveBeenCalled();
|
||||
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||
'pythonLocation',
|
||||
@ -122,14 +127,19 @@ describe('Finder tests', () => {
|
||||
const pythonDir: string = path.join(
|
||||
toolDir,
|
||||
'Python',
|
||||
'1.2.3-beta.2',
|
||||
'1.2.4-beta.2',
|
||||
'x64'
|
||||
);
|
||||
await io.mkdirP(pythonDir);
|
||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||
});
|
||||
// This will throw if it doesn't find it in the manifest (because no such version exists)
|
||||
await finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, false);
|
||||
await expect(
|
||||
finder.useCpythonVersion('1.2.4-beta.2', 'x64', false, false, false)
|
||||
).resolves.toEqual({
|
||||
impl: 'CPython',
|
||||
version: '1.2.4-beta.2'
|
||||
});
|
||||
});
|
||||
|
||||
it('Check-latest true, finds the latest version in the manifest', async () => {
|
||||
@ -176,18 +186,18 @@ describe('Finder tests', () => {
|
||||
|
||||
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('1.2', 'x64', true, true);
|
||||
await finder.useCpythonVersion('1.2', 'x64', true, true, false);
|
||||
|
||||
expect(infoSpy).toHaveBeenCalledWith("Resolved as '1.2.3'");
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
'Version 1.2.3 was not found in the local cache'
|
||||
);
|
||||
expect(infoSpy).toBeCalledWith(
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
'Version 1.2.3 is available for downloading'
|
||||
);
|
||||
expect(installSpy).toHaveBeenCalled();
|
||||
expect(addPathSpy).toHaveBeenCalledWith(expPath);
|
||||
await finder.useCpythonVersion('1.2.3-beta.2', 'x64', false, true);
|
||||
await finder.useCpythonVersion('1.2.4-beta.2', 'x64', false, true, false);
|
||||
expect(spyCoreAddPath).toHaveBeenCalled();
|
||||
expect(spyCoreExportVariable).toHaveBeenCalledWith(
|
||||
'pythonLocation',
|
||||
@ -199,11 +209,67 @@ describe('Finder tests', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Finds stable Python version if it is not installed, but exists in the manifest, skipping newer pre-release', async () => {
|
||||
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
|
||||
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
|
||||
|
||||
const installSpy: jest.SpyInstance = jest.spyOn(
|
||||
installer,
|
||||
'installCpythonFromRelease'
|
||||
);
|
||||
installSpy.mockImplementation(async () => {
|
||||
const pythonDir: string = path.join(toolDir, 'Python', '1.2.3', 'x64');
|
||||
await io.mkdirP(pythonDir);
|
||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||
});
|
||||
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||
await expect(
|
||||
finder.useCpythonVersion('1.2', 'x64', false, false, false)
|
||||
).resolves.toEqual({
|
||||
impl: 'CPython',
|
||||
version: '1.2.3'
|
||||
});
|
||||
});
|
||||
|
||||
it('Finds Python version if it is not installed, but exists in the manifest, pre-release fallback', async () => {
|
||||
const findSpy: jest.SpyInstance = jest.spyOn(tc, 'getManifestFromRepo');
|
||||
findSpy.mockImplementation(() => <tc.IToolRelease[]>manifestData);
|
||||
|
||||
const installSpy: jest.SpyInstance = jest.spyOn(
|
||||
installer,
|
||||
'installCpythonFromRelease'
|
||||
);
|
||||
installSpy.mockImplementation(async () => {
|
||||
const pythonDir: string = path.join(
|
||||
toolDir,
|
||||
'Python',
|
||||
'1.1.0-beta.2',
|
||||
'x64'
|
||||
);
|
||||
await io.mkdirP(pythonDir);
|
||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||
});
|
||||
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||
await expect(
|
||||
finder.useCpythonVersion('1.1', 'x64', false, false, false)
|
||||
).rejects.toThrow();
|
||||
await expect(
|
||||
finder.useCpythonVersion('1.1', 'x64', false, false, true)
|
||||
).resolves.toEqual({
|
||||
impl: 'CPython',
|
||||
version: '1.1.0-beta.2'
|
||||
});
|
||||
// Check 1.1.0 version specifier does not fallback to '1.1.0-beta.2'
|
||||
await expect(
|
||||
finder.useCpythonVersion('1.1.0', 'x64', false, false, true)
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
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)
|
||||
let thrown = false;
|
||||
try {
|
||||
await finder.useCpythonVersion('3.300000', 'x64', true, false);
|
||||
await finder.useCpythonVersion('3.300000', 'x64', true, false, false);
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
IS_WINDOWS
|
||||
} from '../src/utils';
|
||||
|
||||
const manifestData = require('./data/pypy.json');
|
||||
import manifestData from './data/pypy.json';
|
||||
|
||||
let architecture: string;
|
||||
if (IS_WINDOWS) {
|
||||
@ -51,6 +51,12 @@ describe('findRelease', () => {
|
||||
platform: process.platform,
|
||||
download_url: `https://test.download.python.org/pypy/pypy3.6-v7.3.3-${extensionName}`
|
||||
};
|
||||
const filesRC1: IPyPyManifestAsset = {
|
||||
filename: `pypy3.6-v7.4.0rc1-${extensionName}`,
|
||||
arch: architecture,
|
||||
platform: process.platform,
|
||||
download_url: `https://test.download.python.org/pypy/pypy3.6-v7.4.0rc1-${extensionName}`
|
||||
};
|
||||
|
||||
let getBooleanInputSpy: jest.SpyInstance;
|
||||
let warningSpy: jest.SpyInstance;
|
||||
@ -72,7 +78,13 @@ describe('findRelease', () => {
|
||||
const pythonVersion = '3.6';
|
||||
const pypyVersion = '7.3.7';
|
||||
expect(
|
||||
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
|
||||
installer.findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
false
|
||||
)
|
||||
).toEqual(null);
|
||||
});
|
||||
|
||||
@ -80,7 +92,13 @@ describe('findRelease', () => {
|
||||
const pythonVersion = '3.6';
|
||||
const pypyVersion = '7.3.3';
|
||||
expect(
|
||||
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
|
||||
installer.findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
false
|
||||
)
|
||||
).toEqual({
|
||||
foundAsset: files,
|
||||
resolvedPythonVersion: '3.6.12',
|
||||
@ -92,7 +110,13 @@ describe('findRelease', () => {
|
||||
const pythonVersion = '3.6';
|
||||
const pypyVersion = '7.x';
|
||||
expect(
|
||||
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
|
||||
installer.findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
false
|
||||
)
|
||||
).toEqual({
|
||||
foundAsset: files,
|
||||
resolvedPythonVersion: '3.6.12',
|
||||
@ -104,7 +128,13 @@ describe('findRelease', () => {
|
||||
const pythonVersion = '3.7';
|
||||
const pypyVersion = installer.pypyVersionToSemantic('7.3.3rc2');
|
||||
expect(
|
||||
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
|
||||
installer.findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
false
|
||||
)
|
||||
).toEqual({
|
||||
foundAsset: {
|
||||
filename: `test${extension}`,
|
||||
@ -121,7 +151,13 @@ describe('findRelease', () => {
|
||||
const pythonVersion = '3.6';
|
||||
const pypyVersion = 'x';
|
||||
expect(
|
||||
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
|
||||
installer.findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
false
|
||||
)
|
||||
).toEqual({
|
||||
foundAsset: files,
|
||||
resolvedPythonVersion: '3.6.12',
|
||||
@ -129,12 +165,45 @@ describe('findRelease', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Python version and PyPy version matches semver (pre-release)', () => {
|
||||
const pythonVersion = '3.6';
|
||||
const pypyVersion = '7.4.x';
|
||||
expect(
|
||||
installer.findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
false
|
||||
)
|
||||
).toBeNull();
|
||||
expect(
|
||||
installer.findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
true
|
||||
)
|
||||
).toEqual({
|
||||
foundAsset: filesRC1,
|
||||
resolvedPythonVersion: '3.6.12',
|
||||
resolvedPyPyVersion: '7.4.0rc1'
|
||||
});
|
||||
});
|
||||
|
||||
it('Nightly release is found', () => {
|
||||
const pythonVersion = '3.6';
|
||||
const pypyVersion = 'nightly';
|
||||
const filename = IS_WINDOWS ? 'filename.zip' : 'filename.tar.bz2';
|
||||
expect(
|
||||
installer.findRelease(releases, pythonVersion, pypyVersion, architecture)
|
||||
installer.findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
false
|
||||
)
|
||||
).toEqual({
|
||||
foundAsset: {
|
||||
filename: filename,
|
||||
@ -224,8 +293,8 @@ describe('installPyPy', () => {
|
||||
|
||||
it('throw if release is not found', async () => {
|
||||
await expect(
|
||||
installer.installPyPy('7.3.3', '3.6.17', architecture, undefined)
|
||||
).rejects.toThrowError(
|
||||
installer.installPyPy('7.3.3', '3.6.17', architecture, false, undefined)
|
||||
).rejects.toThrow(
|
||||
`PyPy version 3.6.17 (7.3.3) with arch ${architecture} not found`
|
||||
);
|
||||
|
||||
@ -244,7 +313,7 @@ describe('installPyPy', () => {
|
||||
spyChmodSync.mockImplementation(() => undefined);
|
||||
|
||||
await expect(
|
||||
installer.installPyPy('7.3.x', '3.6.12', architecture, undefined)
|
||||
installer.installPyPy('7.x', '3.6.12', architecture, false, undefined)
|
||||
).resolves.toEqual({
|
||||
installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture),
|
||||
resolvedPythonVersion: '3.6.12',
|
||||
@ -257,4 +326,31 @@ describe('installPyPy', () => {
|
||||
expect(spyCacheDir).toHaveBeenCalled();
|
||||
expect(spyExec).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('found and install PyPy, pre-release fallback', async () => {
|
||||
spyCacheDir = jest.spyOn(tc, 'cacheDir');
|
||||
spyCacheDir.mockImplementation(() =>
|
||||
path.join(toolDir, 'PyPy', '3.6.12', architecture)
|
||||
);
|
||||
|
||||
spyChmodSync = jest.spyOn(fs, 'chmodSync');
|
||||
spyChmodSync.mockImplementation(() => undefined);
|
||||
|
||||
await expect(
|
||||
installer.installPyPy('7.4.x', '3.6.12', architecture, false, undefined)
|
||||
).rejects.toThrow();
|
||||
await expect(
|
||||
installer.installPyPy('7.4.x', '3.6.12', architecture, true, undefined)
|
||||
).resolves.toEqual({
|
||||
installDir: path.join(toolDir, 'PyPy', '3.6.12', architecture),
|
||||
resolvedPythonVersion: '3.6.12',
|
||||
resolvedPyPyVersion: '7.4.0rc1'
|
||||
});
|
||||
|
||||
expect(spyHttpClient).toHaveBeenCalled();
|
||||
expect(spyDownloadTool).toHaveBeenCalled();
|
||||
expect(spyExistsSync).toHaveBeenCalled();
|
||||
expect(spyCacheDir).toHaveBeenCalled();
|
||||
expect(spyExec).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
7
__tests__/test-pipenv.py
Normal file
7
__tests__/test-pipenv.py
Normal 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))
|
@ -1,9 +1,17 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import * as io from '@actions/io';
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import {
|
||||
validateVersion,
|
||||
validatePythonVersionFormatForPyPy,
|
||||
isCacheFeatureAvailable
|
||||
isCacheFeatureAvailable,
|
||||
getVersionInputFromFile,
|
||||
getVersionInputFromPlainFile,
|
||||
getVersionInputFromTomlFile
|
||||
} from '../src/utils';
|
||||
|
||||
jest.mock('@actions/cache');
|
||||
@ -73,3 +81,58 @@ describe('isCacheFeatureAvailable', () => {
|
||||
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.0';
|
||||
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.0';
|
||||
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([]);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@ -23,6 +23,9 @@ inputs:
|
||||
update-environment:
|
||||
description: "Set this option if you want the action to update environment variables."
|
||||
default: true
|
||||
allow-prereleases:
|
||||
description: "When 'true', a version range passed to 'python-version' input will match prerelease versions if no GA versions are found. Only 'x.y' version range is supported for CPython."
|
||||
default: false
|
||||
outputs:
|
||||
python-version:
|
||||
description: "The installed Python or PyPy version. Useful when given a version range as input."
|
||||
|
9107
dist/cache-save/index.js
vendored
9107
dist/cache-save/index.js
vendored
File diff suppressed because one or more lines are too long
13345
dist/setup/index.js
vendored
13345
dist/setup/index.js
vendored
File diff suppressed because one or more lines are too long
@ -20,6 +20,7 @@
|
||||
- [Linux](advanced-usage.md#linux)
|
||||
- [macOS](advanced-usage.md#macos)
|
||||
- [Using `setup-python` on GHES](advanced-usage.md#using-setup-python-on-ghes)
|
||||
- [Allow pre-releases](advanced-usage.md#allow-pre-releases)
|
||||
|
||||
## Using the `python-version` input
|
||||
|
||||
@ -60,7 +61,7 @@ steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11.0-alpha.1'
|
||||
python-version: '3.12.0-alpha.1'
|
||||
- run: python my_script.py
|
||||
```
|
||||
|
||||
@ -71,12 +72,23 @@ steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11-dev'
|
||||
python-version: '3.12-dev'
|
||||
- run: python my_script.py
|
||||
```
|
||||
|
||||
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):
|
||||
|
||||
```yaml
|
||||
@ -84,7 +96,7 @@ steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11.0-alpha - 3.11.0'
|
||||
python-version: '3.12.0-alpha - 3.12.0'
|
||||
- run: python my_script.py
|
||||
```
|
||||
|
||||
@ -250,6 +262,16 @@ steps:
|
||||
python-version-file: '.python-version' # Read python version from a file .python-version
|
||||
- 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
|
||||
|
||||
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.
|
||||
@ -259,7 +281,7 @@ If `check-latest` is set to `true`, the action first checks if the cached versio
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.7'
|
||||
check-latest: true
|
||||
@ -404,7 +426,7 @@ jobs:
|
||||
with:
|
||||
python-version: "3.8.0"
|
||||
cache: "poetry"
|
||||
- run: echo '${{ steps.cp310.outputs.cache-hit }}' # true if cache-hit occured on the primary key
|
||||
- run: echo '${{ steps.cp310.outputs.cache-hit }}' # true if cache-hit occurred on the primary key
|
||||
```
|
||||
|
||||
## Environment variables
|
||||
@ -416,7 +438,7 @@ These environment variables become available after setup-python action execution
|
||||
| pythonLocation |Contains the absolute path to the folder where the requested version of Python or PyPy is installed|
|
||||
| Python_ROOT_DIR | https://cmake.org/cmake/help/latest/module/FindPython.html#module:FindPython |
|
||||
| Python2_ROOT_DIR |https://cmake.org/cmake/help/latest/module/FindPython2.html#module:FindPython2|
|
||||
| Python3_ROOT_DIR |https://cmake.org/cmake/help/latest/module/FindPython2.html#module:FindPython3|
|
||||
| Python3_ROOT_DIR |https://cmake.org/cmake/help/latest/module/FindPython3.html#module:FindPython3|
|
||||
|
||||
## Using `update-environment` flag
|
||||
|
||||
@ -447,7 +469,7 @@ Such a requirement on side-effect could be because you don't want your composite
|
||||
- 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 tool cache.
|
||||
- If the exact patch version doesn't matter to you, specifying just the major and minor versions 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*.
|
||||
- Use `-dev` instead of a patch number (e.g., `3.12-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
|
||||
@ -558,7 +580,7 @@ Here are the steps you need to follow to avoid the rate limit:
|
||||
|
||||
```yml
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@4
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
token: ${{ secrets.GH_GITHUB_COM_TOKEN }}
|
||||
@ -567,4 +589,33 @@ Here are the steps you need to follow to avoid the rate limit:
|
||||
Requests should now be authenticated. To verify that you are getting the higher rate limit, you can call GitHub's [rate limit API](https://docs.github.com/en/rest/rate-limit) from within your workflow ([example](https://github.com/actions/setup-python/pull/443#issuecomment-1206776401)).
|
||||
|
||||
### No access to github.com
|
||||
If the runner is not able to access github.com, any Python versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information.
|
||||
If the runner is not able to access github.com, any Python versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information.
|
||||
|
||||
|
||||
## Allow pre-releases
|
||||
|
||||
The `allow-prereleases` flag defaults to `false`.
|
||||
If `allow-prereleases` is set to `true`, the action will allow falling back to pre-release versions of Python when a matching GA version of Python is not available.
|
||||
This allows for example to simplify reuse of `python-version` as an input of nox for pre-releases of Python by not requiring manipulation of the `3.y-dev` specifier.
|
||||
For CPython, `allow-prereleases` will only have effect for `x.y` version range (e.g. `3.12`).
|
||||
Let's say that python 3.12 is not generally available, the following workflow will fallback to the most recent pre-release of python 3.12:
|
||||
```yaml
|
||||
jobs:
|
||||
test:
|
||||
name: ${{ matrix.os }} / ${{ matrix.python_version }}
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [Ubuntu, Windows, macOS]
|
||||
python_version: ["3.11", "3.12"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "${{ matrix.python_version }}"
|
||||
allow-prereleases: true
|
||||
- run: pipx run nox --error-on-missing-interpreters -s tests-${{ matrix.python_version }}
|
||||
```
|
||||
|
||||
|
@ -60,6 +60,7 @@ Pull requests are the easiest way to contribute changes to git repos at GitHub.
|
||||
|
||||
- To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder
|
||||
- To comply with the code style, **you need to run the `format` script**
|
||||
- To lint the code, **you need to run the `lint:fix` script**
|
||||
- To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build
|
||||
|
||||
**Learn more about how to implement tests:**
|
||||
|
12864
package-lock.json
generated
12864
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@ -6,9 +6,10 @@
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts",
|
||||
"format": "prettier --write \"{,!(node_modules)/**/}*.ts\"",
|
||||
"format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"",
|
||||
"lint": "echo \"Fake command that does nothing. It is used in reusable workflows\"",
|
||||
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"",
|
||||
"format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check \"**/*.{ts,yml,yaml}\"",
|
||||
"lint": "eslint --config ./.eslintrc.js \"**/*.ts\"",
|
||||
"lint:fix": "eslint --config ./.eslintrc.js \"**/*.ts\" --fix",
|
||||
"release": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts && git add -f dist/",
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
@ -28,19 +29,27 @@
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/exec": "^1.1.0",
|
||||
"@actions/glob": "^0.2.0",
|
||||
"@actions/http-client": "^1.0.11",
|
||||
"@actions/io": "^1.0.2",
|
||||
"@actions/tool-cache": "^1.5.5",
|
||||
"semver": "^7.1.3"
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"semver": "^7.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/node": "^16.11.25",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
||||
"@typescript-eslint/parser": "^5.54.0",
|
||||
"@vercel/ncc": "^0.33.4",
|
||||
"eslint": "^8.35.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-plugin-jest": "^27.2.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"husky": "^7.0.2",
|
||||
"jest": "^27.2.5",
|
||||
"jest-circus": "^27.2.5",
|
||||
"prettier": "^2.0.2",
|
||||
"prettier": "^2.8.4",
|
||||
"ts-jest": "^27.0.5",
|
||||
"typescript": "^4.2.3"
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
|
||||
|
||||
export enum State {
|
||||
STATE_CACHE_PRIMARY_KEY = 'cache-primary-key',
|
||||
@ -19,27 +20,39 @@ abstract class CacheDistributor {
|
||||
primaryKey: string;
|
||||
restoreKey: string[] | undefined;
|
||||
}>;
|
||||
protected async handleLoadedCache() {}
|
||||
|
||||
public async restoreCache() {
|
||||
const {primaryKey, restoreKey} = await this.computeKeys();
|
||||
if (primaryKey.endsWith('-')) {
|
||||
const file =
|
||||
this.packageManager === 'pip'
|
||||
? `${this.cacheDependencyPath
|
||||
.split('\n')
|
||||
.join(',')} or ${CACHE_DEPENDENCY_BACKUP_PATH}`
|
||||
: this.cacheDependencyPath.split('\n').join(',');
|
||||
throw new Error(
|
||||
`No file in ${process.cwd()} matched to [${this.cacheDependencyPath
|
||||
.split('\n')
|
||||
.join(',')}], make sure you have checked out the target repository`
|
||||
`No file in ${process.cwd()} matched to [${file}], make sure you have checked out the target repository`
|
||||
);
|
||||
}
|
||||
|
||||
const cachePath = await this.getCacheGlobalDirectories();
|
||||
|
||||
core.saveState(State.CACHE_PATHS, cachePath);
|
||||
|
||||
let matchedKey: string | undefined;
|
||||
try {
|
||||
matchedKey = await cache.restoreCache(cachePath, primaryKey, restoreKey);
|
||||
} catch (err) {
|
||||
const message = (err as Error).message;
|
||||
core.info(`[warning]${message}`);
|
||||
core.setOutput('cache-hit', false);
|
||||
return;
|
||||
}
|
||||
|
||||
core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey);
|
||||
|
||||
const matchedKey = await cache.restoreCache(
|
||||
cachePath,
|
||||
primaryKey,
|
||||
restoreKey
|
||||
);
|
||||
await this.handleLoadedCache();
|
||||
|
||||
this.handleMatchResult(matchedKey, primaryKey);
|
||||
}
|
||||
|
1
src/cache-distributions/constants.ts
Normal file
1
src/cache-distributions/constants.ts
Normal file
@ -0,0 +1 @@
|
||||
export const CACHE_DEPENDENCY_BACKUP_PATH = '**/pyproject.toml';
|
@ -8,11 +8,14 @@ import os from 'os';
|
||||
|
||||
import CacheDistributor from './cache-distributor';
|
||||
import {getLinuxInfo, IS_LINUX, IS_WINDOWS} from '../utils';
|
||||
import {CACHE_DEPENDENCY_BACKUP_PATH} from './constants';
|
||||
|
||||
class PipCache extends CacheDistributor {
|
||||
private cacheDependencyBackupPath: string = CACHE_DEPENDENCY_BACKUP_PATH;
|
||||
|
||||
constructor(
|
||||
private pythonVersion: string,
|
||||
cacheDependencyPath: string = '**/requirements.txt'
|
||||
cacheDependencyPath = '**/requirements.txt'
|
||||
) {
|
||||
super('pip', cacheDependencyPath);
|
||||
}
|
||||
@ -56,7 +59,9 @@ class PipCache extends CacheDistributor {
|
||||
}
|
||||
|
||||
protected async computeKeys() {
|
||||
const hash = await glob.hashFiles(this.cacheDependencyPath);
|
||||
const hash =
|
||||
(await glob.hashFiles(this.cacheDependencyPath)) ||
|
||||
(await glob.hashFiles(this.cacheDependencyBackupPath));
|
||||
let primaryKey = '';
|
||||
let restoreKey = '';
|
||||
|
||||
|
@ -10,52 +10,44 @@ import {logWarning} from '../utils';
|
||||
class PoetryCache extends CacheDistributor {
|
||||
constructor(
|
||||
private pythonVersion: string,
|
||||
protected patterns: string = '**/poetry.lock'
|
||||
protected patterns: string = '**/poetry.lock',
|
||||
protected poetryProjects: Set<string> = new Set<string>()
|
||||
) {
|
||||
super('poetry', patterns);
|
||||
}
|
||||
|
||||
protected async getCacheGlobalDirectories() {
|
||||
const poetryConfig = await this.getPoetryConfiguration();
|
||||
// Same virtualenvs path may appear for different projects, hence we use a Set
|
||||
const paths = new Set<string>();
|
||||
const globber = await glob.create(this.patterns);
|
||||
|
||||
const cacheDir = poetryConfig['cache-dir'];
|
||||
const virtualenvsPath = poetryConfig['virtualenvs.path'].replace(
|
||||
'{cache-dir}',
|
||||
cacheDir
|
||||
);
|
||||
for await (const file of globber.globGenerator()) {
|
||||
const basedir = path.dirname(file);
|
||||
core.debug(`Processing Poetry project at ${basedir}`);
|
||||
this.poetryProjects.add(basedir);
|
||||
|
||||
const paths = [virtualenvsPath];
|
||||
const poetryConfig = await this.getPoetryConfiguration(basedir);
|
||||
|
||||
if (poetryConfig['virtualenvs.in-project'] === true) {
|
||||
paths.push(path.join(process.cwd(), '.venv'));
|
||||
}
|
||||
|
||||
const pythonLocation = await io.which('python');
|
||||
|
||||
if (pythonLocation) {
|
||||
core.debug(`pythonLocation is ${pythonLocation}`);
|
||||
const {
|
||||
exitCode,
|
||||
stderr
|
||||
} = await exec.getExecOutput(
|
||||
`poetry env use ${pythonLocation}`,
|
||||
undefined,
|
||||
{ignoreReturnCode: true}
|
||||
const cacheDir = poetryConfig['cache-dir'];
|
||||
const virtualenvsPath = poetryConfig['virtualenvs.path'].replace(
|
||||
'{cache-dir}',
|
||||
cacheDir
|
||||
);
|
||||
|
||||
if (exitCode) {
|
||||
logWarning(stderr);
|
||||
paths.add(virtualenvsPath);
|
||||
|
||||
if (poetryConfig['virtualenvs.in-project']) {
|
||||
paths.add(path.join(basedir, '.venv'));
|
||||
}
|
||||
} else {
|
||||
logWarning('python binaries were not found in PATH');
|
||||
}
|
||||
|
||||
return paths;
|
||||
return [...paths];
|
||||
}
|
||||
|
||||
protected async computeKeys() {
|
||||
const hash = await glob.hashFiles(this.patterns);
|
||||
const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-${this.packageManager}-${hash}`;
|
||||
// "v2" is here to invalidate old caches of this cache distributor, which were created broken:
|
||||
const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-${this.packageManager}-v2-${hash}`;
|
||||
const restoreKey = undefined;
|
||||
return {
|
||||
primaryKey,
|
||||
@ -63,11 +55,39 @@ class PoetryCache extends CacheDistributor {
|
||||
};
|
||||
}
|
||||
|
||||
private async getPoetryConfiguration() {
|
||||
const {stdout, stderr, exitCode} = await exec.getExecOutput('poetry', [
|
||||
'config',
|
||||
'--list'
|
||||
]);
|
||||
protected async handleLoadedCache() {
|
||||
await super.handleLoadedCache();
|
||||
|
||||
// After the cache is loaded -- make sure virtualenvs use the correct Python version (the one that we have just installed).
|
||||
// This will handle invalid caches, recreating virtualenvs if necessary.
|
||||
|
||||
const pythonLocation = await io.which('python');
|
||||
if (pythonLocation) {
|
||||
core.debug(`pythonLocation is ${pythonLocation}`);
|
||||
} else {
|
||||
logWarning('python binaries were not found in PATH');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const poetryProject of this.poetryProjects) {
|
||||
const {exitCode, stderr} = await exec.getExecOutput(
|
||||
'poetry',
|
||||
['env', 'use', pythonLocation],
|
||||
{ignoreReturnCode: true, cwd: poetryProject}
|
||||
);
|
||||
|
||||
if (exitCode) {
|
||||
logWarning(stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async getPoetryConfiguration(basedir: string) {
|
||||
const {stdout, stderr, exitCode} = await exec.getExecOutput(
|
||||
'poetry',
|
||||
['config', '--list'],
|
||||
{cwd: basedir}
|
||||
);
|
||||
|
||||
if (exitCode && stderr) {
|
||||
throw new Error(
|
||||
|
@ -17,7 +17,16 @@ export async function run() {
|
||||
}
|
||||
|
||||
async function saveCache(packageManager: string) {
|
||||
const cachePaths = JSON.parse(core.getState(State.CACHE_PATHS)) as string[];
|
||||
const cachePathState = core.getState(State.CACHE_PATHS);
|
||||
|
||||
if (!cachePathState) {
|
||||
core.warning(
|
||||
'Cache paths are empty. Please check the previous logs and make sure that the python version is specified'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const cachePaths = JSON.parse(cachePathState) as string[];
|
||||
|
||||
core.debug(`paths for caching are ${cachePaths.join(', ')}`);
|
||||
|
||||
@ -43,7 +52,16 @@ async function saveCache(packageManager: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cacheId = await cache.saveCache(cachePaths, primaryKey);
|
||||
let cacheId = 0;
|
||||
|
||||
try {
|
||||
cacheId = await cache.saveCache(cachePaths, primaryKey);
|
||||
} catch (err) {
|
||||
const message = (err as Error).message;
|
||||
core.info(`[warning]${message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cacheId == -1) {
|
||||
return;
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ export async function findPyPyVersion(
|
||||
versionSpec: string,
|
||||
architecture: string,
|
||||
updateEnvironment: boolean,
|
||||
checkLatest: boolean
|
||||
checkLatest: boolean,
|
||||
allowPreReleases: boolean
|
||||
): Promise<{resolvedPyPyVersion: string; resolvedPythonVersion: string}> {
|
||||
let resolvedPyPyVersion = '';
|
||||
let resolvedPythonVersion = '';
|
||||
@ -39,7 +40,8 @@ export async function findPyPyVersion(
|
||||
releases,
|
||||
pypyVersionSpec.pythonVersion,
|
||||
pypyVersionSpec.pypyVersion,
|
||||
architecture
|
||||
architecture,
|
||||
false
|
||||
);
|
||||
|
||||
if (releaseData) {
|
||||
@ -63,16 +65,14 @@ export async function findPyPyVersion(
|
||||
));
|
||||
|
||||
if (!installDir) {
|
||||
({
|
||||
installDir,
|
||||
resolvedPythonVersion,
|
||||
resolvedPyPyVersion
|
||||
} = await pypyInstall.installPyPy(
|
||||
pypyVersionSpec.pypyVersion,
|
||||
pypyVersionSpec.pythonVersion,
|
||||
architecture,
|
||||
releases
|
||||
));
|
||||
({installDir, resolvedPythonVersion, resolvedPyPyVersion} =
|
||||
await pypyInstall.installPyPy(
|
||||
pypyVersionSpec.pypyVersion,
|
||||
pypyVersionSpec.pythonVersion,
|
||||
architecture,
|
||||
allowPreReleases,
|
||||
releases
|
||||
));
|
||||
}
|
||||
|
||||
const pipDir = IS_WINDOWS ? 'Scripts' : 'bin';
|
||||
@ -95,7 +95,7 @@ export async function findPyPyVersion(
|
||||
core.addPath(pythonLocation);
|
||||
core.addPath(_binDir);
|
||||
}
|
||||
core.setOutput('python-version', 'pypy' + resolvedPyPyVersion.trim());
|
||||
core.setOutput('python-version', 'pypy' + resolvedPyPyVersion);
|
||||
core.setOutput('python-path', pythonPath);
|
||||
|
||||
return {resolvedPyPyVersion, resolvedPythonVersion};
|
||||
@ -142,7 +142,7 @@ export function parsePyPyVersion(versionSpec: string): IPyPyVersionSpec {
|
||||
const versions = versionSpec.split('-').filter(item => !!item);
|
||||
|
||||
if (/^(pypy)(.+)/.test(versions[0])) {
|
||||
let pythonVersion = versions[0].replace('pypy', '');
|
||||
const pythonVersion = versions[0].replace('pypy', '');
|
||||
versions.splice(0, 1, 'pypy', pythonVersion);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import * as tc from '@actions/tool-cache';
|
||||
|
||||
// Python has "scripts" or "bin" directories where command-line tools that come with packages are installed.
|
||||
// This is where pip is, along with anything that pip installs.
|
||||
// There is a seperate directory for `pip install --user`.
|
||||
// There is a separate directory for `pip install --user`.
|
||||
//
|
||||
// For reference, these directories are as follows:
|
||||
// macOS / Linux:
|
||||
@ -34,11 +34,15 @@ export async function useCpythonVersion(
|
||||
version: string,
|
||||
architecture: string,
|
||||
updateEnvironment: boolean,
|
||||
checkLatest: boolean
|
||||
checkLatest: boolean,
|
||||
allowPreReleases: boolean
|
||||
): Promise<InstalledVersion> {
|
||||
let manifest: tc.IToolRelease[] | null = null;
|
||||
const desugaredVersionSpec = desugarDevVersion(version);
|
||||
let semanticVersionSpec = pythonVersionToSemantic(desugaredVersionSpec);
|
||||
let semanticVersionSpec = pythonVersionToSemantic(
|
||||
desugaredVersionSpec,
|
||||
allowPreReleases
|
||||
);
|
||||
core.debug(`Semantic version spec of ${version} is ${semanticVersionSpec}`);
|
||||
|
||||
if (checkLatest) {
|
||||
@ -178,8 +182,18 @@ interface InstalledVersion {
|
||||
* Python's prelease versions look like `3.7.0b2`.
|
||||
* This is the one part of Python versioning that does not look like semantic versioning, which specifies `3.7.0-b2`.
|
||||
* If the version spec contains prerelease versions, we need to convert them to the semantic version equivalent.
|
||||
*
|
||||
* For easier use of the action, we also map 'x.y' to allow pre-release before 'x.y.0' release if allowPreReleases is true
|
||||
*/
|
||||
export function pythonVersionToSemantic(versionSpec: string) {
|
||||
export function pythonVersionToSemantic(
|
||||
versionSpec: string,
|
||||
allowPreReleases: boolean
|
||||
) {
|
||||
const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc)\d*)/g;
|
||||
return versionSpec.replace(prereleaseVersion, '$1-$2');
|
||||
const majorMinor = /^(\d+)\.(\d+)$/;
|
||||
let result = versionSpec.replace(prereleaseVersion, '$1-$2');
|
||||
if (allowPreReleases) {
|
||||
result = result.replace(majorMinor, '~$1.$2.0-0');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
@ -19,6 +20,7 @@ export async function installPyPy(
|
||||
pypyVersion: string,
|
||||
pythonVersion: string,
|
||||
architecture: string,
|
||||
allowPreReleases: boolean,
|
||||
releases: IPyPyManifestRelease[] | undefined
|
||||
) {
|
||||
let downloadDir;
|
||||
@ -29,13 +31,31 @@ export async function installPyPy(
|
||||
throw new Error('No release was found in PyPy version.json');
|
||||
}
|
||||
|
||||
const releaseData = findRelease(
|
||||
let releaseData = findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture
|
||||
architecture,
|
||||
false
|
||||
);
|
||||
|
||||
if (allowPreReleases && (!releaseData || !releaseData.foundAsset)) {
|
||||
// check for pre-release
|
||||
core.info(
|
||||
[
|
||||
`Stable PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`,
|
||||
`Trying pre-release versions`
|
||||
].join(os.EOL)
|
||||
);
|
||||
releaseData = findRelease(
|
||||
releases,
|
||||
pythonVersion,
|
||||
pypyVersion,
|
||||
architecture,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if (!releaseData || !releaseData.foundAsset) {
|
||||
throw new Error(
|
||||
`PyPy version ${pythonVersion} (${pypyVersion}) with arch ${architecture} not found`
|
||||
@ -43,7 +63,7 @@ export async function installPyPy(
|
||||
}
|
||||
|
||||
const {foundAsset, resolvedPythonVersion, resolvedPyPyVersion} = releaseData;
|
||||
let downloadUrl = `${foundAsset.download_url}`;
|
||||
const downloadUrl = `${foundAsset.download_url}`;
|
||||
|
||||
core.info(`Downloading PyPy from "${downloadUrl}" ...`);
|
||||
|
||||
@ -123,7 +143,7 @@ async function createPyPySymlink(
|
||||
const pythonMinor = semver.minor(version);
|
||||
const pypyBinaryPostfix = pythonBinaryPostfix === 2 ? '' : '3';
|
||||
const pypyMajorMinorBinaryPostfix = `${pythonBinaryPostfix}.${pythonMinor}`;
|
||||
let binaryExtension = IS_WINDOWS ? '.exe' : '';
|
||||
const binaryExtension = IS_WINDOWS ? '.exe' : '';
|
||||
|
||||
core.info('Creating symlinks...');
|
||||
createSymlinkInFolder(
|
||||
@ -162,8 +182,10 @@ export function findRelease(
|
||||
releases: IPyPyManifestRelease[],
|
||||
pythonVersion: string,
|
||||
pypyVersion: string,
|
||||
architecture: string
|
||||
architecture: string,
|
||||
includePrerelease: boolean
|
||||
) {
|
||||
const options = {includePrerelease: includePrerelease};
|
||||
const filterReleases = releases.filter(item => {
|
||||
const isPythonVersionSatisfied = semver.satisfies(
|
||||
semver.coerce(item.python_version)!,
|
||||
@ -173,7 +195,11 @@ export function findRelease(
|
||||
isNightlyKeyword(pypyVersion) && isNightlyKeyword(item.pypy_version);
|
||||
const isPyPyVersionSatisfied =
|
||||
isPyPyNightly ||
|
||||
semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion);
|
||||
semver.satisfies(
|
||||
pypyVersionToSemantic(item.pypy_version),
|
||||
pypyVersion,
|
||||
options
|
||||
);
|
||||
const isArchPresent =
|
||||
item.files &&
|
||||
(IS_WINDOWS
|
||||
@ -207,7 +233,7 @@ export function findRelease(
|
||||
return {
|
||||
foundAsset,
|
||||
resolvedPythonVersion: foundRelease.python_version,
|
||||
resolvedPyPyVersion: foundRelease.pypy_version
|
||||
resolvedPyPyVersion: foundRelease.pypy_version.trim()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,13 @@ import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import fs from 'fs';
|
||||
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) {
|
||||
return versionSpec.startsWith('pypy');
|
||||
@ -22,43 +28,46 @@ async function cacheDependencies(cache: string, pythonVersion: string) {
|
||||
await cacheDistributor.restoreCache();
|
||||
}
|
||||
|
||||
function resolveVersionInputFromDefaultFile(): string[] {
|
||||
const couples: [string, (versionFile: string) => string[]][] = [
|
||||
['.python-version', getVersionInputFromPlainFile]
|
||||
];
|
||||
for (const [versionFile, _fn] of couples) {
|
||||
logWarning(
|
||||
`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');
|
||||
let versionFile = core.getInput('python-version-file');
|
||||
|
||||
if (versions.length && versionFile) {
|
||||
core.warning(
|
||||
'Both python-version and python-version-file inputs are specified, only python-version will be used.'
|
||||
);
|
||||
}
|
||||
const versionFile = core.getInput('python-version-file');
|
||||
|
||||
if (versions.length) {
|
||||
return versions;
|
||||
}
|
||||
|
||||
if (versionFile) {
|
||||
if (!fs.existsSync(versionFile)) {
|
||||
throw new Error(
|
||||
`The specified python version file at: ${versionFile} doesn't exist.`
|
||||
if (versionFile) {
|
||||
core.warning(
|
||||
'Both python-version and python-version-file inputs are specified, only python-version will be used.'
|
||||
);
|
||||
}
|
||||
const version = fs.readFileSync(versionFile, 'utf8');
|
||||
core.info(`Resolved ${versionFile} as ${version}`);
|
||||
return [version];
|
||||
} else {
|
||||
if (versionFile) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -77,6 +86,7 @@ async function run() {
|
||||
try {
|
||||
const versions = resolveVersionInput();
|
||||
const checkLatest = core.getBooleanInput('check-latest');
|
||||
const allowPreReleases = core.getBooleanInput('allow-prereleases');
|
||||
|
||||
if (versions.length) {
|
||||
let pythonVersion = '';
|
||||
@ -89,18 +99,25 @@ async function run() {
|
||||
version,
|
||||
arch,
|
||||
updateEnvironment,
|
||||
checkLatest
|
||||
checkLatest,
|
||||
allowPreReleases
|
||||
);
|
||||
pythonVersion = `${installed.resolvedPyPyVersion}-${installed.resolvedPythonVersion}`;
|
||||
core.info(
|
||||
`Successfully set up PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`
|
||||
);
|
||||
} else {
|
||||
if (version.startsWith('2')) {
|
||||
core.warning(
|
||||
'The support for python 2.7 will be removed on June 19. Related issue: https://github.com/actions/setup-python/issues/672'
|
||||
);
|
||||
}
|
||||
const installed = await finder.useCpythonVersion(
|
||||
version,
|
||||
arch,
|
||||
updateEnvironment,
|
||||
checkLatest
|
||||
checkLatest,
|
||||
allowPreReleases
|
||||
);
|
||||
pythonVersion = installed.version;
|
||||
core.info(`Successfully set up ${installed.impl} (${pythonVersion})`);
|
||||
|
90
src/utils.ts
90
src/utils.ts
@ -1,8 +1,10 @@
|
||||
/* eslint no-unsafe-finally: "off" */
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
import * as toml from '@iarna/toml';
|
||||
import * as exec from '@actions/exec';
|
||||
|
||||
export const IS_WINDOWS = process.platform === 'win32';
|
||||
@ -71,9 +73,9 @@ export function getPyPyVersionFromPath(installDir: string) {
|
||||
*/
|
||||
export function readExactPyPyVersionFile(installDir: string) {
|
||||
let pypyVersion = '';
|
||||
let fileVersion = path.join(installDir, PYPY_VERSION_FILE);
|
||||
const fileVersion = path.join(installDir, PYPY_VERSION_FILE);
|
||||
if (fs.existsSync(fileVersion)) {
|
||||
pypyVersion = fs.readFileSync(fileVersion).toString();
|
||||
pypyVersion = fs.readFileSync(fileVersion).toString().trim();
|
||||
}
|
||||
|
||||
return pypyVersion;
|
||||
@ -180,3 +182,87 @@ export async function getOSInfo() {
|
||||
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}`);
|
||||
const rawVersions = Array.from(versions, version =>
|
||||
version.split(',').join(' ')
|
||||
);
|
||||
const validatedVersions = rawVersions
|
||||
.map(item => semver.validRange(item, true))
|
||||
.filter((versionRange, index) => {
|
||||
if (!versionRange) {
|
||||
core.debug(
|
||||
`The version ${rawVersions[index]} is not valid SemVer range`
|
||||
);
|
||||
}
|
||||
|
||||
return !!versionRange;
|
||||
}) as string[];
|
||||
return validatedVersions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,8 @@
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
"resolveJsonModule": true, /* Allows importing modules with a '.json' extension, which is a common practice in node projects. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
|
@ -1,7 +0,0 @@
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
# 120 chars should be enough, but don't fail if a line is longer
|
||||
line-length:
|
||||
max: 120
|
||||
level: warning
|
Reference in New Issue
Block a user